嵌入式面试知识点总结

您所在的位置:网站首页 嵌入式c语言基础知识 嵌入式面试知识点总结

嵌入式面试知识点总结

2024-07-15 21:14| 来源: 网络整理| 查看: 265

如需转载请注明出处:https://juyou.blog.csdn.net/article/details/115716559

之前有写过 日常生活 – 嵌入式面试 ,讲了面试大部分都会问哪些问题。 也有自己总结了一些面试题:

C语言再学习 – 详解C++/C 面试题 1C语言再学习 – 详解C++/C 面试题 2

下载:嵌入式C语言面试题汇总(超经典) 提取码:w779

但是每次我都要翻好几篇文章挨个看知识点,这就很烦了。现在将所用到的知识点在这篇文章内加以总结。

一、关键字 1、const 问题: 问题一:const有什么用途?(请至少说明两种) (1)可以定义const常量 (2)const可以修饰函数的参数和返回值,甚至函数的定义体。被const修饰的东西都受到强制保护,可以预防意外的变动,能提高程序的健壮性。问题二:以下的p和*p哪个可变,哪个不可变? 先忽略类型名(编译器解析的时候也是忽略类型名),我们看 const 离哪个近。“近水楼先得月”,离谁近就修饰谁。 int arr[5]; const int * p = arr; //const 修饰 * p,p 是指针,可变; * p 是指针指向的对象,不可变。 int const * p = arr; //const 修饰 * p,p 是指针, 可变; * p 是指针指向的对象,不可变。 int * const p = arr; //const 修饰 p, p 是指针,不可变; p 指向的对象可变。 const int * const p= arr; //前一个 const 修饰 * p,后一个 const 修饰 p,指针 p 和 p 指向的对象都不可变。问题三:关键字const有什么含义? const修饰的数据类型是指常类型,常类型的变量或对象的值是不能被更新的。或者说const意味着只读。 解答:

参看:C语言再学习 – 关键字const const 修饰类型: (1)const 修饰一般常量 (2)const修饰指针、数组 (3)const 修饰函数的形参和返回值 (4)const 修饰常对象 (5)const 修饰常引用 (6)const 修饰类的成员变量 (7)const 修饰类的成员函数

const 作用: (1)可以定义 const 常量,具有不可变性。 (2)便于进行类型检查,使编译器对处理内容有更多了解,消除一些隐患。 (3)可以避免意义模糊的数字出现,同样可以很方便进行参数的调整和修改。同宏定义一样,可以做到不变则已,一变都变。 (4)可以保护被修改的东西,防止意外的修改,增强程序的健壮性。 (5)可以节省空间,避免不必要的内存分配。 (6)为函数重载提供了一个参考 (7)提高效率

const介绍: (1)在定义该const 变量时,通常需要对它进行初始化,因为以后就没有机会再去改变它了; (2)对指针来说,可以指定指针本身为const,也可以指定指针所指的数据为 const,或二者同时指定为const; (3)在一个函数声明中,const可以修饰形参,表明它是一个输入参数,在函数内部不能改变其值; (4)对于类的成员函数,若指定其为const 类型,则表明其是一个常函数,不能修改类的成员变量; (5)对于类的成员函数,有时候必须指定其返回值为const 类型,以使得其返回值不为“左值”。 作用的话,可以保护被修改的东西,防止意外的修改,增强程序的健壮性。

2、static 问题: 问题一:关键static的作用是什么? static 修饰全局变量 static 修饰局部变量 static 修饰函数 解答:

参看:C语言再学习 – 存储类型关键字 (1)static 修饰的全局变量也叫静态全局变量,该类具有静态存储时期、文件作用域和内部链接,仅在编译时初始化一次。如未明确初始化,它的字节都被设定为0。static全局变量只初使化一次,是为了防止在其他文件单元中被引用;利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。 (2)static 修饰的局部变量也叫静态局部变量,该类具有静态存储时期、代码作用域和空链接,仅在编译时初始化一次。如未明确初始化,它的字节都被设定为0。函数调用结束后存储区空间并不释放,保留其当前值。 (3)static 修饰的函数也叫静态函数,只可以在定义它的文件中使用。

3、volatile 问题: 问题一:关键字volatile有什么含意?并给出三个不同的例子。 volatile关键字是一种类型修饰符。volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。直接读值是指从内存重新装载内容,而不是直接从寄存器拷贝内容。 volatile使用: (1)并行设备的硬件寄存器(如:状态寄存器)。 (2)一个中断服务子程序中会访问到的非自动变量。 (3)多线程应用中被几个任务共享的变量。 解答:

参看:C语言再学习 – 关键字volatile

4、sizeof 问题: 问题一:以下为Windows NT下的32位C++程序,请计算sizeof的值。 void Func ( char str[100]) { 请计算: sizeof( str ) = 4 } char str[] = “Hello” ; char *p = str ; int n = 10; 请计算: sizeof (str ) = 6 sizeof ( p ) = 4 sizeof ( n ) = 4 void *p = malloc( 100 ); 请计算: sizeof ( p ) = 4问题二:在 32 位系统下:short * p =NULL;sizeof( p )的值是多少?sizeof( * p)呢? sizeof ( p ) = 4; 因为 p为指针,32位系统 指针所占字节为 4个字节 sizeof ( *p ) = 2; 因为 *p 为 指针所指向的变量为int类型,short为 2个字节问题三:请计算sizeof的值 int a[100]; sizeof (a) = 400; // 因为 a是类型为整型、有100个元素的数组,所占内存为400个字节 sizeof (a[100]) = 4; //因为 a[100] 为数组的第100元素的值该值为 int 类型,所占内存为4个字节。 sizeof (&a) = 4; //因为 &a 为数组的地址即指针,32位系统 指针所占字节为 4个字节 sizeof (&a[0]) = 4; //因为&a[0] 为数组的首元素的地址即指针,32位系统 指针所占字节为 4个字节 解答:

参看:C语言再学习 – 关键字sizeof与strlen (1)sizeof 操作符以字节形式给出了其操作数的存储大小。操作数可以是一个表达式或括在括号内的类型名。操作数的存储大小由操作数的类型决定。 在windows,32位系统中 char 1个字节 short 2个字节 int 4个字节 long 4个字节 double 8个字节 float 4个字节 (2)数据类型必须用圆括号括住。如:sizeof (int)

记住这两句话: 在 32 位系统下,不管什么样的指针类型,其大小都为 4 byte。 参数传递数组永远都是传递指向数组首元素的指针。

5、extern 问题: 问题一:在C++程序中调用被C编译器编译后的函数,为什么要加extern “C”声明? C++语言支持函数重载, C 语言不支持函数重载。函数被 C++编译后在库中的名字与 C 语言的不同。假设某个函数的原型为: void foo(int x, int y);该 函 数 被 C 编 译 器 编 译 后 在 库 中 的 名 字 为 _foo, 而 C++编 译 器 则 会 产 生 像_foo_int_int 之类的名字。C++提供了 C 连接交换指定符号 extern“ C”来解决名字匹配问题。 解答:

参看:C语言再学习 – 存储类型关键字 C 程序中,不允许出现类型不同的同名变量。而C++程序中 却允许出现重载。重载的定义:同一个作用域,函数名相同,参数表不同的函数构成重载关系。因此会造成链接时找不到对应函数的情况,此时C函数就需要用extern “C”进行链接指定,来解决名字匹配问题。简单来说就是,extern “C”这个声明的真实目的是为了实现C++与C及其它语言的混合编程。

二、字符串 1、strcpy 函数功能实现 问题: 问题一:编写 strcpy 函数 已知 strcpy 函数的原型是 char *strcpy(char *strDest, const char *strSrc); 其中 strDest 是目的字符串, strSrc 是源字符串。 (1)不调用 C++/C 的字符串库函数,请编写函数 strcpy char *strcpy(char *strDest, const char *strSrc); { assert((strDest!=NULL) && (strSrc !=NULL)); // 2分 char *address = strDest; // 2分 while( (*strDest++ = * strSrc++) != ‘\0’ ) // 2分 NULL ; return address ; // 2分 } (2) strcpy 能把 strSrc 的内容复制到 strDest,为什么还要 char * 类型的返回值? 答:为了实现链式表达式。 // 2 分 例如 int length = strlen( strcpy( strDest, “hello world”) ); 2、字符串的翻转 问题: 问题一:字符串的翻转实现 实现逻辑,就是将字符串从中间一分为二,互相换位置即完成了翻转的效果void rechange_str(char *str) { int i, len; char tmp; if (NULL == str) { return ; } len = strlen(str); for (i = 0; i < len/2; i ++) { tmp = str[i]; str[i] = str[len-i-1]; str[len-i-1] = tmp; } } 3、strcpy和memcpy区别 问题: 问题一:strcpy和memcpy区别? (1)复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。 (2)复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。 (3)用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy。 解答:

参看:C语言再学习 – 字符串和字符串函数 剩下的像strcat、strlen、atoi、itoa函数功能实现,自行查看。

三、大小端 问题: 问题一:C语言实现大小端 #include #icnlude int main (void) { union { short i; char a[2]; }u; u.a[0] = 0x11; u.a[1] = 0x22; printf ("0x%x\n", u.i); //0x2211 为小端 0x1122 为大端 printf ("0x%.x\n", htons (u.i)); //大小端转换 return 0; } 输出结果: 0x2211 0x1122 问题二:大小端应用场景? 一般操作系统都是小端,而通讯协议是大端的。 大小端是由CPU和操作系统来决定的,在操作系统中,x86和一般的OS(如windows,FreeBSD,Linux)使用的是小端模式,但比如Mac OS是大端模式。 在网络上传输数据时,由于数据传输的两端对应不同的硬件平台,采用的存储字节顺序可能不一致。所以在TCP/IP协议规定了在网络上必须采用网络字节顺序,也就是大端模式。 解答:

参看:C语言再学习-- 大端小端详解(转) 一般都是采用 union 来判断机器的字节序。 union 型数据所占的空间等于其最大的成员所占的空间。 对 union 型的成员的存取都是相对于该联合体基地址的偏移量为 0 处开始,也就是联合体的访问不论对哪个变量的存取都是从 union 的首地址位置开始。 联合是一个在同一个存储空间里存储不同类型数据的数据类型。 这些存储区的地址都是一样的,联合里不同存储区的内存是重叠的,修改了任何一个其他的会受影响。

现在明白了,我们为什么用 union 联合来测试大小端,在联合变量 u 中, 短整型变量 i 和字符数组 a 共用同一内存位置。给 a[0]、a[1] 赋值后,i 也是从同一内存地址读值的。

四、预处理 问题:

问题一:用预处理指令#define 声明一个常数,用以表明1年中有多少秒(忽略闰年问题) #define SENCONDS_PER_YEAR (60 * 60 * 24 * 365)UL #define 声明一个常量,使用计算常量表达式的值来表明一年中有多少秒,显得就更加直观了。再有这个表达式的值为无符号长整形,因此应使用符号 UL。

问题二:写一个“标准”宏MIN ,这个宏输入两个参数并返回较小的一个。 #define MIN(A,B) ((A)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3