gpt4 book ai didi

将指向数组的指针转换为指针

转载 作者:行者123 更新时间:2023-12-04 23:20:14 26 4
gpt4 key购买 nike

考虑以下 C 代码:

int arr[2] = {0, 0};
int *ptr = (int*)&arr;
ptr[0] = 5;
printf("%d\n", arr[0]);

现在,很明显代码打印了 5在常见的编译器上。但是,有人可以在 C 标准中找到指定代码实际上有效的相关部分吗?还是代码未定义的行为?

我主要问的是为什么 &arr当铸成 void *arr 相同当铸成 void * ?因为我相信代码等价于:
int arr[2] = {0, 0};
int *ptr = (int*)(void*)&arr;
ptr[0] = 5;
printf("%d\n", arr[0]);

我在思考这里的问题时发明了这个例子: Pointer-to-array overlapping end of array ...但这显然是一个不同的问题。

最佳答案

对于 union 和结构,参见。 ISO 9899:2011§6.7.2.1/16f:

16 The size of a union is sufficient to contain the largest of its members. The value of at most one of the members can be stored in a union object at any time. A pointer to a union object, suitably converted, points to each of its members (or if a member is a bit-field, then to the unit in which it resides), and vice versa.

17 Within a structure object, the non-bit-field members and the units in which bit-fields reside have addresses that increase in the order in which they are declared. A pointer to a structure object, suitably converted, points to its initial member (or if that member is a bit-field, then to the unit in which it resides), and vice versa. There may be unnamed padding within a structure object, but not at its beginning.



对于数组类型,情况稍微复杂一些。首先,观察什么是数组,来自 ISO 9899:2011§6.2.5/20:

An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. The element type shall be complete whenever the array type is specified. Array types are characterized by their element type and by the number of elements in the array. An array type is said to be derived from its element type, and if its element type is T, the array type is sometimes called “array of T”. The construction of an array type from an element type is called “array type derivation”.



“连续分配”一词意味着数组成员之间没有填充。脚注 109 肯定了这一概念:

Two objects may be adjacent in memory because they are adjacent elements of a larger array or adjacent members of a structure with no padding between them, or because the implementation chose to place them so, even though they are unrelated. If prior invalid pointer operations (such as accesses outside array bounds) produced undefined behavior, subsequent comparisons also produce undefined behavior.


sizeof的使用§6.5.3.5 中的运算符,示例 2 表达了在数组之前或之后也没有填充的意图:

EXAMPLE 2

Another use of the sizeof operator is to compute the number of elements in an array:

sizeof array / sizeof array[0]


因此,我得出结论,指向数组的指针,转换为指向该数组元素错字的指针,指向数组中的第一个元素。此外,观察相等的定义对指针的说明(第 6.5.9/6f. 节):

6 Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning) or function, both are pointers to one past the last element of the same array object, or one is a pointer to one past the end of one array object and the other is a pointer to the start of a different array object that happens to immediately follow the first array object in the address space.109)

7 For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.



由于数组的第一个元素是“其开头的子对象”,因此指向数组第一个元素的指针和指向数组的指针比较相等。

关于将指向数组的指针转换为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29244504/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com