经典笔试题:指针详解
来源:互联网 发布:linux系统哪个版本好 编辑:程序博客网 时间:2024/06/05 10:58
1.下面代码输出结果是什么?
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++经典笔试题详解
- iOS 数组与指针经典笔试题
- 经典笔试题:动态内存分配,详解
- 指针、数组相关笔试题详解
- 初识指针-----经典指针详解
- 指针的笔试面试经典题目
- 金山笔试题解析(经典指针)
- 最新java经典笔试题带详解 30道
- java经典笔试题
- .net经典笔试题
- c++经典笔试题
- 经典笔试题
- 经典C++笔试题
- 经典笔试题
- C++经典笔试题
- 经典笔试题笔记
- html 标签
- poj3764 The xor-longest Path(01字典树+dfs)
- git 相关知识
- Angular4订阅(Subscribe)与取消
- 使用循环神经网络训练情感分析
- 经典笔试题:指针详解
- 在Android的webview中定制js的alert,confirm和prompt对话框的方法
- 欢迎使用CSDN-markdown编辑器
- simplest_ffmpeg_streamer加注释版
- [POJ] 2251 Dungeon Master
- 2-2 hanxin
- WebSocket总结
- Java和C++ Protect安全性
- [2017.11.18]作业12