c程序员面试必看
### C程序员面试必看知识点详解 #### 知识点一:C语言中处理绝对地址与函数调用 在C语言中,对特定的绝对地址进行赋值或调用,涉及到了指针类型转换和函数指针的概念。例如,对绝对地址`0x100000`赋值为`1234`可以使用`*(unsigned int*)0x100000 = 1234;`。而若想让程序跳转至该地址执行,则需将该地址转换为函数指针并调用,具体实现如下: ```c *((void(*)())0x100000)(); ``` 这里的`void(*)()`, 是一个函数指针的类型声明,表示无参数、无返回值的函数。通过类型强制转换,`0x100000`被转换为此类型,随后通过`*`操作符调用该函数指针。 为了提高代码的可读性,可以通过`typedef`定义函数指针类型,使代码更加清晰: ```c typedef void (*VoidFuncPtr)(); *((VoidFuncPtr)0x100000)(); ``` #### 知识点二:C语言动态内存管理与潜在问题 考虑以下C语言代码片段,其中`GetMemory`函数用于动态分配内存,`main`函数负责使用和释放内存: ```c void GetMemory(char** p, int num) { *p = (char*)malloc(num); } int main() { char* str = NULL; GetMemory(&str, 100); strcpy(str, "hello"); free(str); if(str != NULL) { strcpy(str, "world"); } printf("str is %s", str); } ``` 程序运行时,`printf`语句输出`str is world`。此现象背后的机制在于C语言中的动态内存管理。当使用`free`释放内存时,并不会立即清除指针`str`的内容,仅释放其指向的内存区域。如果之后没有重新分配该区域,`str`仍可能访问先前的数据,导致所谓的“悬挂指针”问题。 为了避免这类问题,良好的编程习惯是在`free`后将指针置为`NULL`: ```c free(str); str = NULL; ``` 这样可以防止后续意外使用已释放的内存,减少程序崩溃的风险。 #### 知识点三:`strlen`与`sizeof`的区别 对于未初始化的字符数组`char a[10];`,调用`strlen(a)`为何会返回`15`? 实际上,`strlen`函数计算的是字符串中从第一个非空字符到第一个`\0`终止符的长度。由于`a`未初始化,其内容可能是任意值,包括可能存在的零多个`\0`。在这种情况下,`strlen`遇到的`'\0'`可能出现在数组的任何位置,甚至超出数组范围,导致不可预知的结果。因此,对于未初始化的数组,直接调用`strlen`是不安全的,其结果具有不确定性。 #### 知识点四:数组指针与指针数组的区别 在C语言中,`char(*str)[20];`与`char*str[20];`虽看起来相似,但意义截然不同: 1. `char(*str)[20];`:`str`是一个数组指针,指向一个包含20个字符的数组。这意味着`str`可以存储多个字符数组的地址,每个数组最多有20个字符。 2. `char*str[20];`:`str`是一个指针数组,它由20个指针组成,每个指针都可以指向一个字符。这里,`str`的每个元素都是一个指向字符的指针,可用于存储不同字符串的地址。 #### 知识点五:结构体与位域的使用及注意事项 在C语言中,结构体可以包含位域成员,如: ```c typedef struct AA { int b1:5; int b2:2; } AA; ``` 这里,`b1`占用5位,`b2`占用2位。当使用`memcpy`从一个字符数组复制到此类结构体时,需要注意位域成员的大小和对齐方式。在本例中,`AA`的大小为4字节,`memcpy`后,`aa`的4个字节中分别存储了`0,1,2,3`的ASCII码。显示`b1`和`b2`时,实际上是取这四个字节的前5位和接下来的2位,得到的值分别是`-16`和`1`。此结果展示了位域成员在内存布局上的特性及其与整数类型表示之间的转换关系。
剩余62页未读,继续阅读
- kaluote5235232013-11-20讲的东西不多,可以参考一下
- 粉丝: 0
- 资源: 2
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助