【问题标题】:What happens when I declare an array in a struct in C language?当我在 C 语言的结构中声明一个数组时会发生什么?
【发布时间】:2021-12-29 19:30:22
【问题描述】:

我很难理解在结构中声明数组时会发生什么。谈论普通数组(int,float,char ...类型)我知道数组的名称本身就是指向数组第一个元素的指针。但是,假设我有一个这样的结构:

struct student
{
   char name[12];
   int age;
}

main 函数中,假设我声明:struct student s1; 好吧,我不明白这个变量是如何在内存中分配的。 年龄是否有 4 个字节,字符串有 10 个字节,但是名为 s1.name 的指针(它是指向字符串的第一个元素的指针,对吗?)呢?结构与否?

【问题讨论】:

    标签: c struct declaration sizeof


    【解决方案1】:

    数组不是指针,它们的“名称”也不是,不管这意味着什么。

    在大多数情况下它们被隐式转换为指针,但生成的指针是动态计算的,并且在转换之前通常不存在于内存中。

    一个数组(任何元素类型)作为 N 个连续元素存储在内存中,仅此而已。

    所以,char name[12] 占用 12 个字节(存储 12 个字符)。 int age 在大多数现代平台上占用 4 个字节。

    因此struct Student 占用16 个字节。大小为Nstruct Student 数组占用sizeof(struct Student) * N 字节。

    【讨论】:

    • 好的,我明白了,但是为什么我声明 struct student s1; s1.name 是数组的内存位置,我的意思是 s1.name 不是分配在内存某处的变量吗?
    • @LorenzoZabot 是的,s1.name 分配在内存中,但不是作为指针。它只是彼此相邻的 12 个字符。 “为什么我声明 struct student s1; s1.name 是数组的内存位置” 数组的大多数使用导致它们被隐式转换为指向它们的第一个元素的指针。
    【解决方案2】:

    我知道数组名本身就是一个指针

    这是一个错误的陈述。数组是数组而不是指针。但在表达式中使用时,除了极少数例外,数组指示符会隐式转换为指向其第一个元素的指针。

    您声明了类型说明符 struct student。

    struct student
    {
       char name[12];
       int age;
    };
    

    要确定这种类型的对象的大小,您可以编写

    printf( "sizeof( struct student ) = %zu\n", sizeof( struct student ) );
    

    这是一个演示程序。

    #include <stdio.h>
    
    int main( void )
    {
        struct student
        {
            char name[12];
            int age;
        };
    
        printf( "sizeof( struct student ) = %zu\n", sizeof( struct student ) );
    
        struct student s;
    
        printf( "sizeof( s ) = %zu\n", sizeof( s ) );
        printf( "sizeof( s.name ) = %zu\n", sizeof( s.name ) );
        printf( "sizeof( s.age ) = %zu\n", sizeof( s.age ) );
    }
    

    程序输出可能看起来像

    sizeof( struct student ) = 16
    sizeof( s ) = 16
    sizeof( s.name ) = 12
    sizeof( s.age ) = 4
    

    即结构类型的对象占用16个字节。前12个字节被其数据成员(数组)name占用,后4个字节被数据成员age占用。

    【讨论】:

      【解决方案3】:

      回答您的具体问题。没有“名为 s.name 的指针”,有一个名为 s.name 的变量。此变量引用分配在 struct s 偏移量 0 处的 12 字符数组。在某些情况下,编译器会将数组视为指向第一个元素的指针,而在其他情况下则不然。所以

      sizeof(s.name) = 12
      

      将 s.name 视为真正的字符数组。而真正的指针,比如 char *p,会产生

      sizeof(p) = 4 or 8 depending on 32 or 64 bit
      

      您可以看到 s.name 在其他地方被视为指针,因为它们都有效:

      strlen(s.name);
      strlen(p);
      

      strlen 被声明为采用 char*

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-10-21
        • 1970-01-01
        • 1970-01-01
        • 2014-08-05
        • 2019-03-31
        相关资源
        最近更新 更多