指针访问类
题目 1
题目:下面程序的运行结果是:
int main(){ int a[5] = {1, 2, 3, 4, 5}; int *ptr = (int *)(&a+1); printf("%d %d\n", *(a+1), *(ptr-1)); }
答案:
对于数组名取地址和正常的常量取地址不同,&a 在这里的意思是 5 个 5 个的取数值,所以 &a+1 实际上是从第一个值开始取了 5 ,所以指向的是数值 5 的下一个位置即第六个位置。但是 ptr 本身被定义为 1 个 1 个的取地址。
故 *(a+1) 的结果是 2 ,*(ptr-1) 的结果是 5 。
题目 2
题目:请问下列代码有什么问题?
int main(){ char a; char *str = &a; strcpy(str, "hello"); printf(str); return 0; }
答案: 这是一个典型的越界问题, str 指针只定义了 1 个字节,所以在拷贝 hello 时会出现越界问题。但是不同情况下报错的位置可能不同,有可能在进行 strcpy 的时候系统就已经报错了,因为访问到了不该访问的位置。
但是有可能 str 越界的位置后续用不到,所以 strcpy 就顺利执行了,然后打印出来,可最后返回时可能会报错,因为越界的位置可能修改了我要返回的地址处导致 main 函数无法正确返回。
题目 3
题目:下面程序的运行结果是:
char *s = "AAA"; printf("%s", s); s[0] = 'B'; printf("%s", s);
答案:s
指向的是一个常量,所以当 s[0]
想要改变其中的值时就直接会报段错误,最后一句是无法执行到的。
题目 4
题目:下面的程序运行结果是:
int arr[] = {6, 7, 8, 9, 10}; int *ptr = arr; *(ptr++) += 123; printf("%d %d\n", *ptr, *(++ptr));
答案: 这里输出的结果不会是 7
和 8
,因为 c
语言会用栈来存储这些信息,从右往左将各个参数压入栈中。所以,*(++ptr)
会先被执行,导致结果变成了 8
和 8
。