c - 指针数组如何存储在内存中以及如何正确取消引用它们?
问题描述
int main(void) {
int* b[3] = {1, 2, 3}; // b is an array of pointers to integer
printf("%d", b); // b = address of array of pointers
printf("\n%d", *b); // *b should be address of the place where 1 is stored ....right?
printf("\n%d", *(b+1)); // similarly *(b+1) should be address of place where 2 is stored
printf("\n%d", *(b+2)); // and so on... But they print 1,2 and 3
printf("\n%d", b[0]); // prints 1 . No problem!
printf("%d", *(*(b+1)+2)); // Also why does this give segmentation fault?
//PLUS I GET THIS WARNING : array_of_pointers2.c:5:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
//PLEASE EXPLAIN !! I think I have misunderstood something.
return 0;
}
解决方案
您的代码有很多问题,主要是因为int *b[3]
没有适当的初始化程序。{ 1, 2, 3 }
可以用于 的数组int
,而不是 的数组int *
,因为编译器正确诊断:
array_of_pointers2.c:5:13: warning: initialization makes pointer from integer without a cast [-Wint-conversion]
为了与古代代码兼容,编译器仅发出警告,但此类警告表示必须纠正的错误。我强烈建议你编译你的代码,-Wall -Werror
让编译器产生错误,而不是仅仅对这些问题发出警告。
访问地址1
,2
或者3
很可能有未定义的行为,这表现为系统上的分段错误。
要初始化指针数组,您可以指定int
变量的地址。
这是一个更正的版本:
#include <stdio.h>
int main(void) {
int x = 1, y = 2, z = 3;
int *b[3] = { &x, &y, &z }; // b is an array of pointers to integer
printf(" b: %p\n", (void*)(b)); // b = address of array of pointers
printf(" *b: %p\n", (void*)(*b)); // *b is the address of variable x that has a value of 1
printf(" *(b+1): %p\n", (void*)(*(b+1))); // similarly *(b+1) is the address of y where 2 is stored
printf(" *(b+2): %p\n", (void*)(*(b+2))); // and so on...
printf(" *b[0]: %d\n", *b[0]); // prints 1. No problem!
printf("*(*(b+1)): %d\n", *(*(b+1))); // prints 2
// accessing *(*(b+1)+2) would have undefined behavior because b[1] is
// not the address of an array of at least 3 ints.
printf(" b[2][0]: %d\n", b[2][0]); // prints 3
return 0;
}
请注意,指针无法打印,%d
因为它具有未定义的行为,因为指针可能以不同的方式从整数传递到printf
. 格式是%p
并且指针应该被转换(void*)
为完全可移植性。
推荐阅读
- python - 如何使用数据框中的散点图数据制作热图?
- javascript - 如果 SQL 中有数据则显示按钮,否则隐藏
- javascript - 将项目推送到“for of”内的数组未按预期工作
- html - 网站上的链接标签在点击时四处移动?
- javascript - 如何使用 Jest/Puppeteer 等到元素从 DOM 中移除
- java - Java 8:同时编写排序、过滤和计数的函数式方法
- c# - 将 TResult 转换为 Func
在 Xamarin.forms 中 - laravel - 如何让单元测试忽略 Laravel 中的中间件
- typescript - 如何从接口的属性中提取“枚举类型”?
- python - 如何使用 Python 将二元组列表转换为标记列表