指针访问类
题目 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
。