为什么我和C中的arr 一样有更大的数据类型?

众所周知,如果你在C中以arr[i]访问数组元素,你也可以像i[arr]一样访问元素,因为这些只是归结为*(arr + i)并且加法是可交换的。 我的问题是为什么这适用于大于char数据类型,因为sizeof(char)是1,对我来说这应该只需要一个char来推进指针。

也许这个例子让它更清晰:

 #include  #include  struct large { char data[1024]; }; int main( int argc, char * argv[] ) { struct large arr[4]; memset( arr, 0, sizeof( arr ) ); printf( "%lu\n", sizeof( arr ) ); // prints 4096 strcpy( arr[0].data, "should not be accessed (and is not)" ); strcpy( arr[1].data, "Hello world!" ); printf( "%s, %s, %s\n", arr[1].data, 1[arr].data, (*(arr+1)).data ); // prints Hello world!, Hello world!, Hello world! // I expected `hold not be accessed (and is not)' for #3 at least return 0; } 

那么为什么在数组指针中添加一个以sizeof( struct large )推进呢?

在C中,定义指针算法以便写入

 ptr + k 

不是将指针推进k 个字节 ,而是推进k 对象 。 因此,如果你有一个指向整数数组的指针并写入

 *(myIntArrayPointer + 3) 

您正在取消引用指向数组中索引3处的元素的指针,而不是从对象开始处开始三个字节的整数。

类似地,如果您减去两个指针,则会获得它们之间的逻辑元素数,而不是总字节数。 这样写作

 (myIntArrayPointer + 3) - myIntArrayPointer 

产生值3,即使它们之间有3 * sizeof(int)字节。

希望这可以帮助!

这是指针算术 。 当你写作

 some_pointer + i 

它编译为

 some_pointer + (i * sizeof(*my_pointer)) 

i是这个问题的int :))

通过阅读C规范, 能回答这类问题。 试试吧!

§6.5.6加法运算符,第8段:

当一个具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。 如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素偏移的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式。

键入数组/指针。 编译器知道“事物”有多大,在这种情况下你的结构。

而C就是这样定义的; 通过“一”推进指针将转到数组中的下一个事物。 编译器知道要走多远。 这适用于任何相关和等效的语法:

 *(arr + i) arr[i] i[arr] 

对于编译器知道的任何类型。

这称为“指针算术”,它至少有一个有趣的属性:如果你有两个指向数组中项目的指针,你可以减去它们以获得它们之间的项目数,即对象(即非字节)。

arr被声明为4个结构的数组,每个结构包含1024个字符的char数组。

arr被解析为指向此结构数组的第一个元素的指针。 当你将arr增加1时,这个新指针将跳过一个整体结构(它指向的类型),然后指向数组中的下一个元素。

这一切都归结为编译器知道指针所指向的类型,然后如果递增数组,它将指向连续内存位置中相似类型的下一个元素。

在这种情况下,如果数组的基址是XYZ,则arr + i = XYZ + i * sizeof(arr)/ sizeof(struct large)