C语言中int (*p)[10]=s和int (*o)[5]=&s有什么区别?
两种写法的核心差异与推荐
&s写法的原因 你测试代码输出一致只是地址数值巧合相等的假象,两种写法本质上有合法性、安全性的巨大差异,推荐&s写法的核心原因如下:
1. 类型完全匹配,符合C语言标准
C语言中:
- 数组
s的原生类型是int[5],&s是取整个数组的地址,类型恰好是int (*)[5],和int (*o)[5]的指针类型100%匹配,属于合法的标准写法,编译时不会报类型不匹配警告/错误。 - 你写的
int (*p)[10] = s属于非法的类型强转:大多数场景下数组名s会隐式退化为指向首元素的int*类型,和int (*)[10](指向10个int元素数组的指针)完全不兼容,C标准将这种行为定义为未定义行为,只是你当前测试环境下地址数值刚好重合才输出了相同结果。
2. 避免后续操作的隐藏风险
类型不匹配的写法会带来大量隐性问题,只是你当前的测试用例没触发而已:
- 指针运算结果完全错误:
p + 1会跳过10个int的长度(通常是40字节),而你原数组只有5个int的长度,运算后直接越界;o + 1则刚好跳过整个s数组的长度,符合预期。 - 失去编译器的类型检查能力:类型匹配时如果你访问
(*o)[5],编译器能提前识别越界风险给出警告;而用p时你访问(*p)[5]属于合法的指针范围,编译器不会报错,实际已经访问了数组外的非法内存,极容易出现野指针、内存污染问题。
额外说明:测试代码的不规范问题
你用printf("%d", 指针)的写法本身不符合C标准,打印指针应该用%p格式符,同时将指针强转为void*类型:
printf("%p\n", (void*)*p);
你当前输出的只是地址的低32位整数值,重合完全是巧合,不能作为两种写法等价的依据。
内容的提问来源于stack exchange,提问作者Ankit Bhardwaj
相关产品推荐
相关产品推荐

