C 分配一个指向结构数组的整数指针,并且代码仍在执行?

C 分配一个指向结构数组的整数指针,并且代码仍在执行?,c,pointers,C,Pointers,我在一本教科书中看到了下面的C代码片段,它工作正常。。。但我不理解输出以及为什么它工作正常,因为它看起来是错误的: #include <stdio.h> int main() { struct { int x,y; } s[4] = {{10,20},{15,25},{8,75},{6,2}}; int *i; i=s; clrscr(); printf("\n%d",s[i[7]].x); printf(

我在一本教科书中看到了下面的C代码片段,它工作正常。。。但我不理解输出以及为什么它工作正常,因为它看起来是错误的:

#include <stdio.h>

int main()
{

    struct {
        int x,y;
    } s[4] = {{10,20},{15,25},{8,75},{6,2}};
    int *i;
    i=s;

    clrscr();
    printf("\n%d",s[i[7]].x);
    printf("\n%d",i[i[1]-i[2]]);
    printf("\n%d",i[s[3].y]);
    printf("\n%d",(s+1)->x+5);
    printf("\n%d",s[i[0]-i[4]].y + 10);
    printf("\n%d",++i[i[6]]);
    getch();

    return 0;

}

就指针分配而言:

以下是您的评论:

“由int数组和struct数组组成的内存布局 仅凭ints是相同的”

必须定义指针类型的原因是编译器必须知道指针指向的数据的大小。整数的大小为4个字节,而此结构的大小为8个字节。当程序试图访问位于
s[1]
位置的内存时,编译器知道程序需要
s[0]
之后的8个字节的数据,其中
i[1]
只需要
i[0]
之后的4个字节的数据

s
是一个结构数组(有两个int类型的成员),
i
是指向int的指针。由于
s
的第一个元素是一个2 int的结构,
i=s
s
的第一个元素的第一个成员的地址分配给
i

i=&s[0]
是相同的赋值

如果
s[0]
从0x00开始,则其第一个成员的地址为0x00,而其第二个成员的地址为0x04
s[1]
将从0x08开始,该位置的结构具有地址为0x0C的第二个成员

对于
i=s
i[0]
具有地址0x00,
i[1]
具有地址0x04,
s
的第一个元素的第二个成员
i[2]
的地址为0x08,是数组中第二个结构的第一个成员,
i[3]
的地址为0x0C,是数组中第二个结构的第二个成员。等等

  { 10, 20 } { 15, 25 } { 8, 75 } { 6, 2 }
s:|    0    |     1    |    2    |   3   |
i:| 0 |  1  |  2 |  3  |  4 | 5  | 6 | 7 |
i
现在指向第一个整数(全部8个整数中的第一个)

i[0]=10

i[7]=2

第一个printf语句解释如下:由于
i[7]=2
,因此我们有
s[2]
引用具有x值
8
的对
{8,75}

指针确实不兼容,使用gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5.1)编译会产生以下警告:

test.c:在函数“main”中:test.c:10:警告:从 不兼容的指针类型

但是,程序会编译并生成输出:

875152085


就指针分配而言:

以下是您的评论:

“由int数组和struct数组组成的内存布局 仅凭ints是相同的”

必须定义指针类型的原因是编译器必须知道指针指向的数据的大小。整数的大小为4个字节,而此结构的大小为8个字节。当程序试图访问位于
s[1]
位置的内存时,编译器知道程序需要
s[0]
之后的8个字节的数据,其中
i[1]
只需要
i[0]
之后的4个字节的数据

s
是一个结构数组(有两个int类型的成员),
i
是指向int的指针。由于
s
的第一个元素是一个2 int的结构,
i=s
s
的第一个元素的第一个成员的地址分配给
i

i=&s[0]
是相同的赋值

如果
s[0]
从0x00开始,则其第一个成员的地址为0x00,而其第二个成员的地址为0x04
s[1]
将从0x08开始,该位置的结构具有地址为0x0C的第二个成员

对于
i=s
i[0]
具有地址0x00,
i[1]
具有地址0x04,
s
的第一个元素的第二个成员
i[2]
的地址为0x08,是数组中第二个结构的第一个成员,
i[3]
的地址为0x0C,是数组中第二个结构的第二个成员。等等

  { 10, 20 } { 15, 25 } { 8, 75 } { 6, 2 }
s:|    0    |     1    |    2    |   3   |
i:| 0 |  1  |  2 |  3  |  4 | 5  | 6 | 7 |
i
现在指向第一个整数(全部8个整数中的第一个)

i[0]=10

i[7]=2

第一个printf语句解释如下:由于
i[7]=2
,因此我们有
s[2]
引用具有x值
8
的对
{8,75}

指针确实不兼容,使用gcc版本4.4.3(Ubuntu 4.4.3-4ubuntu5.1)编译会产生以下警告:

test.c:在函数“main”中:test.c:10:警告:从 不兼容的指针类型

但是,程序会编译并生成输出:

875152085

此外,我不明白如何在语句中为s指定整数指针:
i=s

这很简单,在C语言中没有强制转换是不可能的。您的编译器很乐意接受这样的程序,但其他编译器有权拒绝编译该程序

此外,我不明白如何在语句中为s指定整数指针:
i=s


这很简单,在C语言中没有强制转换是不可能的。您的编译器很乐意接受这样的程序,但其他编译器有权拒绝编译该程序。

编译器将s[4]的数据存储在线性内存中,例如10,20,15,25,8,75,6,2。i[7]等于2。这只是一个类似下面示例的技巧

有这样一种结构:

struct block{
int a;
int b;
};

struct block item;
如果我知道
item->b
的地址,我怎么知道
item
的地址呢


答案是使用
item->b
减去
((struct block*)0)->b

编译器将s[4]的数据存储在线性内存中,例如10,20,15,25,8,75,6,2。i[7]等于2。它是jus