c - 为什么不能将指向整数数组的指针分配给指向整数的指针?

标签 c arrays pointers

在 c primer plus 中,它告诉我遵循了一些赋值规则:

不能将指向整数数组的指针分配给指向整数的指针。

 int *pt; int a[3][2];
 pt=a; /* invalid */

不能将指向双整数数组的指针分配给指向三整数数组的指针。

 int (*pt)[3]; int a[3][2];
 pt=a; /* invalid */

坦率地说,我对这个解释感到困惑。因为上面的指针虽然是指向不同对象的指针,但是在内存中,指针都是以无符号的十六进制地址存储的,也就是说它们的存储形式是一样的。它们统一为 8 位(64 位操作系统)或 4 位(32 位操作系统)。那么为什么他们不能在根本原因上相互分配呢?因为编译器禁止这类赋值?

最佳答案

语言具有类型的一个主要原因是帮助程序员避免犯错误。指向不同类型事物的指针本身被视为不同类型。像这样的规则会捕捉到许多错误,程序员可能会将指针分配给错误的东西。

一个int,一个包含两个int的数组,一个包含三个int的数组是不同类型的东西,所以指向它们的指针是不同类型的指针,C 的规则要求编译器诊断任何将一个指针分配给另一个指针的尝试。 (这可以通过使用强制转换来显式转换指针来覆盖,但是在您了解有关使用不同类型的别名对象的 C 规则之前,应该避免这种情况。)

最简单的,要设置int *pt指向int a[3][2]的第一个元素,你可以使用pt = &a [0][0];pt = a[0];。在后者中,由于a是两个int的三个数组的数组,a[0]是两个int的数组。当在表达式中使用而不是作为 sizeof 或一元 &1 的操作数时,它会自动转换为指向其第一个元素的指针,所以它的行为与 &a[0][0] 相同。

顺便说一句,“……指针都是以无符号的十六进制地址存储的,这意味着它们具有相同的存储形式。它们统一在 8 位(64 位操作系统)或 4 位(32 位操作系统)中”通常不正确。 C 标准允许不同类型的指针有不同的表示。这在现代 C 实现中并不常见,但确实存在。

脚注

1 用于初始化字符数组的字符串文字也不会转换为指针。

关于c - 为什么不能将指向整数数组的指针分配给指向整数的指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60707126/

相关文章:

sql - 将 NULL 数组填充到自定义聚合函数的最大长度

java - 在特定位置初始化另一个数组时使用数组

c++ - 将 char* 分配给字符串变量后删除

使用链表的 C++ 堆栈

PHP - 仅洗牌数组的一部分

c++ - 查找由链表链接的数据的各个地址。 C++

c++ - 确保内存映射页在内存中

c - 如果 '&' 没有放在 'scanf' 语句中会发生什么?

c++ - 我怎样才能 Eloquent 地写 "if not greater than or equal to some value"?

c - seccomp 系统调用陷阱函数中的指针返回值