经典笔试题:指针详解
2017-11-19 10:03
127 查看
1.下面代码输出结果是什么?
解析:
* (a + 1):此处a代表数组首元素的地址,那(a + 1)就代表第二个元素的地址,* 解引用,* (a + 1) = 2。
答案:2 和 5
2.
假设p 的值为0x100000。 如下表表达式的值分别为多少?
①p + 0x1= 0x___ ?
②(unsigned long)p + 0x1= 0x___ ?
③(unsigned int *)p + 0x1= 0x___ ?
解析:
①此处 p 是一个结构体指针,p+1实际上是要加上p所指向的类型的大小,而p指向的这个结构体的大小是20字节,所以第①题答案是:0x100014 (结构体大小计算详解请点击:博客Tianzez——内存对齐)
②把p强转成 unsigned long 类型,那这里就是一个无符号长整型数字加1,所以结果是:0x100001。
③把p强转成 unsigned int * 类型,此时p就是一个指针,指针加一就是加上它所指向的类型的大小,无符号长整型数据的大小是4,所以这里结果是:0x100004。
答案:①0x100014 ②0x100001 ③0x100004
3.
解析:
① ptr1[-1] :
② * ptr2:这里最后结果是:0x2000000 或 0x100。详解请点击:博客Tianzez——指针 地址强转的习题解析
答案:①0x000004 ②0x2000000 或 0x100
4.
解析:
这里注意了,花括号里面是圆括号,所以这里就组成了逗号表达式。最后数组里面的值是 a[3][2] = {1, 3, 5, 0, 0, 0}; 所以a[0] = 1。
答案:1
5.
解析:
这道题只要能把内存布局图画出来就很简单了,做比较复杂的指针题时要学会画内存图,图画得越好,做题就更简单。
答案:FFFFFFFC 和 -4
6.
解析:
① * (ptr1 - 1):
② *(ptr2 - 1):
把一个二维数组看做一个一维数组,这个一维数组的每个元素都是一个一维数组
那aa就代表二维数组里第一行的地址,(aa + 1)代表第二行的地址。* (aa + 1)表示整个第二行,而此时 (aa + 1) 做左值就表示第二行的地址,所以 (ptr2 - 1) = 5。
答案:①10 ②5
7.解释下面代码:
解析:
(1)
①
②
③
④
(2)
①对这块代码进行简化:
②
8.
解析:
答案: at
9.
解析:
请参照 :博客WangYe8613
答案:①PIONT ②ER ③ST ④EW
int main() { int a[5] = { 1, 2, 3, 4, 5 }; int *ptr = (int *)(&a + 1); printf("%d,%d", *(a + 1), *(ptr - 1)); system("pause"); return 0; }
解析:
* (a + 1):此处a代表数组首元素的地址,那(a + 1)就代表第二个元素的地址,* 解引用,* (a + 1) = 2。
*(ptr - 1): int *ptr = (int *)(&a + 1);这行代码中 &a 代表 整个数组的地址,(&a + 1) 就代表数组a下一个int类型数字的地址,把这个地址强转成
int*赋给ptr。这里(ptr - 1),指针减一就是减去它所指向的类型的大小,即往前移动四个字节,所以 *(ptr - 1) = 5。
答案:2 和 5
2.
struct Test { int Num; char *pcName; shortsDate; charcha[2]; shortsBa[4]; }*p;
假设p 的值为0x100000。 如下表表达式的值分别为多少?
①p + 0x1= 0x___ ?
②(unsigned long)p + 0x1= 0x___ ?
③(unsigned int *)p + 0x1= 0x___ ?
解析:
①此处 p 是一个结构体指针,p+1实际上是要加上p所指向的类型的大小,而p指向的这个结构体的大小是20字节,所以第①题答案是:0x100014 (结构体大小计算详解请点击:博客Tianzez——内存对齐)
②把p强转成 unsigned long 类型,那这里就是一个无符号长整型数字加1,所以结果是:0x100001。
③把p强转成 unsigned int * 类型,此时p就是一个指针,指针加一就是加上它所指向的类型的大小,无符号长整型数据的大小是4,所以这里结果是:0x100004。
答案:①0x100014 ②0x100001 ③0x100004
3.
int main() { int a[4] = { 1, 2, 3, 4 }; int *ptr1 = (int *)(&a + 1); int *ptr2 = (int *)((int)a + 1); printf("%x, %x", ptr1[-1], *ptr2); system("pause"); return 0; }
解析:
① ptr1[-1] :
int *ptr1 = (int *)(&a + 1);这行代码中 &a 代表整个数组的地址,(&a + 1) 就代表数组a下一个int类型数字的地址,把这个地址强转成 int * 赋给ptr,ptr 就指向尾元素a[3]下个元素的地址。ptr1[-1] 就相当于 *(ptr - 1)。所以最后结果是:0x000004。
② * ptr2:这里最后结果是:0x2000000 或 0x100。详解请点击:博客Tianzez——指针 地址强转的习题解析
答案:①0x000004 ②0x2000000 或 0x100
4.
int main(int argc, char * argv[]) { int a[3][2] = { (0, 1), (2, 3), (4, 5) }; int *p; p = a[0]; printf("%d\n", p[0]); system("pause"); return 0; }
解析:
这里注意了,花括号里面是圆括号,所以这里就组成了逗号表达式。最后数组里面的值是 a[3][2] = {1, 3, 5, 0, 0, 0}; 所以a[0] = 1。
答案:1
5.
int main() { int a[5][5]; int(*p)[4]; p = a; printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]); system("pause"); return 0; }
解析:
这道题只要能把内存布局图画出来就很简单了,做比较复杂的指针题时要学会画内存图,图画得越好,做题就更简单。
答案:FFFFFFFC 和 -4
6.
int main() { int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *ptr1 = (int *)(&aa + 1); int *ptr2 = (int *)(*(aa + 1)); printf("%d, %d", *(ptr1 - 1), *(ptr2 - 1)); system("pause"); return 0; }
解析:
① * (ptr1 - 1):
int *ptr1 = (int *)(&aa + 1);这行代码中 &aa 代表整个数组的地址,(&aa + 1) 就代表数组a下一个int类型数字的地址,把这个地址强转成 int * 赋给ptr,这个时候ptr就指向数组 aa 尾元素 aa[2][5] 的下一个元素。然后(ptr1 - 1),此时 ptr 就指向aa[2][5]。*(ptr1 - 1) = 10。
② *(ptr2 - 1):
int *ptr2 = (int *)(*(aa + 1));这行代码里 aa 代表数组首元素地址,而我们通常解决这类问题时:
把一个二维数组看做一个一维数组,这个一维数组的每个元素都是一个一维数组
那aa就代表二维数组里第一行的地址,(aa + 1)代表第二行的地址。* (aa + 1)表示整个第二行,而此时 (aa + 1) 做左值就表示第二行的地址,所以 (ptr2 - 1) = 5。
答案:①10 ②5
7.解释下面代码:
(1)(*( void(*) ()) 0)() (2)void(*signal(int, void(*)(int)))(int);
解析:
(1)
①
void(*)()是一个函数指针类型,这个函数无参数,无返回值。
②
(void(*)())0把0强转成函数指针类型,0是一个函数的首地址。
③
(*(void(*)())0)解引用,把地址为0的函数取出来。
④
(*(void(*)())0)()调用这个地址为0的函数。
(2)
①对这块代码进行简化:
typedef void(* pfun_t)(int);
②
pfun_t signal(int, pfun_t):定义了一个函数指针 signal,指向的函数有两个参数,类型分别是 int 和 pfun_t 。
8.
int main() { char *a[] = { "work", "at", "alibaba" }; char **pa = a; pa++; printf("%s\n", *pa); system("pause"); return 0; }
解析:
char **pa = a;此时pa是一个二级指针,
pa++;实际上是pa加上它所指向的元素类型的大小,而pa指向的是一个 char * 类型指针,即pa = &a[0],
pa++之后,pa = &a[1]。所以*pa = a[1],最后输出结果就是 “at” 。
答案: at
9.
int main() { char *c[] = { "ENTER", "NEW", "POINT", "FIRST" }; char **cp[] = { c + 3, c + 2, c + 1, c }; char ***cpp = cp; printf("%s\n", **++cpp); printf("%s\n", *--*++cpp + 3); printf("%s\n", *cpp[-2] + 3); printf("%s\n", cpp[-1][-1] + 1); system("pause"); return 0; }
解析:
请参照 :博客WangYe8613
答案:①PIONT ②ER ③ST ④EW
相关文章推荐
- 经典笔试题:一级指针数组、二级指针数组和三级指针的联合使用详解
- 指针、数组相关笔试题详解
- 一道笔试指针题目详解
- C指针详解(经典,非常详细)
- 一个关于的指针的经典笔试题目,加上自己的一点体会
- 让你不再害怕指针——C指针详解(经典,非常详细)
- 让你不再害怕指针——C指针详解(经典,非常详细)
- iOS 数组与指针经典笔试题
- 19C指针详解(经典,非常详细)
- C/C++指针的经典笔试面试题
- 【C语言】让你不再害怕指针——C指针详解(经典,非常详细)
- 金山笔试题解析(经典指针)
- 指针的笔试面试经典题目
- C指针详解(经典,非常详细)
- C++经典笔试题详解
- 让你不再害怕指针——C指针详解(经典,非常详细)
- 最新java经典笔试题带详解 30道
- C++智能指针详解(真的很经典 )
- 一道笔试指针题目详解
- 【c基础知识】C指针详解(经典,非常详细)