C 对结构在内存中的位置感到困惑

C 对结构在内存中的位置感到困惑,c,pointers,memory,struct,memory-address,C,Pointers,Memory,Struct,Memory Address,我正在探索指针,目前正在特别处理结构指针。目前,我有以下代码: #include <stdlib.h> #include <stdio.h> struct point{ double x; double y; }; int main(){ char *pc; int *pi; struct point *pp; //char pointer printf("%p\n\n", (void*)pc); pc++;

我正在探索指针,目前正在特别处理结构指针。目前,我有以下代码:

#include <stdlib.h>
#include <stdio.h>

struct point{
double x;
double y;
};

int main(){
    char *pc;
    int *pi;
    struct point *pp;

    //char pointer
    printf("%p\n\n", (void*)pc);
    pc++;
    printf("%p\n\n", (void*)pc);

    //int pointer
    printf("%p\n\n", (void*)pi);
    pi += 2;
    printf("%p\n\n", (void*)pi);

    //struct pointer
    printf("%p\n\n", (void*)pp);
    pp -= 3;
    printf("%p\n\n", (void*)pp);
}
我理解前4个输出,使用char和int指针算法,但是我不明白为什么它返回0x0作为结构指针的内存地址?另外,如果我想要内存中的地址,比如双y,我该如何打印它?

您的代码调用未定义的行为,因为您的所有指针都是未初始化的

在启用警告的情况下编译,例如-Wall for GCC,并将获得:

prog.c: In function 'main':
prog.c:15:5: warning: 'pc' is used uninitialized in this function [-Wuninitialized]
     printf("%p\n\n", (void*)pc);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.c:20:5: warning: 'pi' is used uninitialized in this function [-Wuninitialized]
     printf("%p\n\n", (void*)pi);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.c:25:5: warning: 'pp' is used uninitialized in this function [-Wuninitialized]
     printf("%p\n\n", (void*)pp);
     ^~~~~~~~~~~~~~~~~~~~~~~~~~~
像这样初始化指针,例如:

char c = 'a';
char *pc = &c;
int i = 5;
int *pi = &i;
struct point p;
struct point *pp = &p;
可以得到:

0x7ffe629c90d7 // address of the charatcer

0x7ffe629c90d8 // sizeof(char) is 1

0x7ffe629c90d0 // address of the integer

0x7ffe629c90d8 // sizeof(int) is 8 in this system

0x7ffe629c90c0 // address of the struct

0x7ffe629c9090 // sizeof(struct point) is 16 in this system
// 0x7ffe629c90c0 - 0x7ffe629c9090 = 0x30 -> Decimal: 48 = 3 * 16

当您声明一个指针时,您必须为它分配内存,如果您不使用它,则必须将其设置为null

pc = malloc(sizeof(*pc));
pi = malloc(sizeof(*pi));
pp = malloc(sizeof(*pp));
别忘了验证malloc的返回值!!!!不是故意的

您应该使用-W-Wall-Wextra-g进行编译,然后使用valgrind运行二进制文件

此外,您不需要强制转换为void*,因为它已经是一个指针

结果如下:

0xf88010

0xf88011

0xf88030

0xf88038

0xf88050

0xf88020

我理解。。。。不,你没有。这里没有什么需要理解的。代码的行为完全没有意义,因为没有任何变量被初始化。我的意思是我理解从36跳到37,从bbc8跳到bbd0,由于字符和整数的大小,我仍然在学习C,没有意识到这是未定义的行为,Sorry对空指针或任何超出边界的指针进行指针数学运算,即使没有取消引用也是很困难的。当结构设置为零时,初始化的基元类型有垃圾值是有原因的吗?@Carl我没有看到结构设置为零。
0xf88010

0xf88011

0xf88030

0xf88038

0xf88050

0xf88020