【问题标题】:is access to array member in structure in c a access to value or address?访问 c 结构中的数组成员是访问值还是地址?
【发布时间】:2018-01-14 12:27:13
【问题描述】:

在以下代码中:

struct a  {
    char name[18];
}customer;
scanf("%s",customer.name);
printf("%s",customer.name); 
struct a *pt=&customer;    `

因为指向数组名的第一个元素,是customer.name指向这个成员的第一个元素吗?

在一本书中写道*(customer.name+2) 等同于customer.name[2]pt->name[2]。但我无法理解这些注释以及为什么scanf() 函数中的customer.name 是地址而printf() 函数中的不是地址?

【问题讨论】:

  • 在某些用途下,数组表示为指针。

标签: c arrays string


【解决方案1】:

在此处print()scanf() 的示例中,customer.name 解析为指向数组name 的第一个元素的指针,它是customer 类型的变量struct a 的成员。

为了消除混淆,在 %s 格式说明符与 printf() 的情况下,预期的参数类型是指向数组第一个元素的指针。所以,在这个 printf() 调用的情况下,参数 customer.name 是正确的,它是一个指针。

【讨论】:

    【解决方案2】:

    当数组用作函数参数时,它会衰减为指向其第一个元素的指针。在scanfprintf 这两个函数中,参数customer.name 被转换为指针并具有char * 类型。

    【讨论】:

      【解决方案3】:

      customer.name 是指向name 字符数组中第一个字符的指针。

      customer.name 等价于&(customer.name[0])

      customer.name 约定是访问结构中字符数组的典型方式。

      printf() %s 格式中需要指向数组第一个元素的指针。

      结构体a、成员name数组和name[0]字符在内存中的地址完全相同。您可以在以下程序中看到:

      #include <stdio.h>
      #include <stdlib.h>
      
      typedef struct a  {
          char name[18];
      }customer;
      
      int main()
      {
          customer bob;
          customer *ptr; 
      
          scanf("%s",bob.name);
          printf("Customer name is: %s\n",bob.name); 
      
          ptr = & bob;  
      
          printf("Memory Address of the bob structure is:  %p\n", (void *) ptr);    
          printf("Memory Address of the 'bob.name'    is:  %p\n", (void *) &bob.name);
          printf("Memory Address of the 'bob.name[0]' is:  %p\n", (void *) &(bob.name[0]) );
      
          return 0;
      }
      

      输出:

      Bob
      Customer name is: Bob
      Memory Address of the bob structure is:  0x7ffe0d7687e0
      Memory Address of the 'bob.name'    is:  0x7ffe0d7687e0
      Memory Address of the 'bob.name[0]' is:  0x7ffe0d7687e0
      

      【讨论】:

        【解决方案4】:

        在这两种情况下,它都是一个地址。但是,其中一个使用该地址填充字符串,另一个使用该地址读取值。

        printf 中使用%s 时,函数需要该字符串的起始地址。您不应该被int i = 10; printf("%d", i"); 的情况误解,变量的哪个值被传递给printf。如你所见,字符串在 print 函数中的故事是不同的。

        【讨论】:

          【解决方案5】:

          这种情况scanf你最终传递了地址,因为数组衰减到指向第一个元素的指针。(这种衰减不会发生的一些情况是sizeofAlignOf 或运营商地址&amp; 等)。该指针包含数组第一个元素的地址。

          scanf("%s",customer.name);
                     ^^^^
          

          指向数组第一个元素的指针char* 保存scanf 将值写入所需内存地址所需的地址。为了澄清一点,你甚至可以等效地传递这个:(前面的讨论解释了为什么它是可能的)。

          scanf("%s",&customer.name[0]);
          

          printf 中也是它是一个正在传递的地址,其逻辑与之前相同,然后由print 到@987654332 使用@它所包含的字符,直到它到达\0

          来自standard 7.21.6.6frpintf功能说明:

          如果不存在l 长度修饰符,参数应为指向 字符类型数组的初始元素.280) 来自的字符 数组被写入(但不包括)终止的 null 特点。如果指定了精度,则不超过那么多字节 被写。如果未指定精度或大于 数组的大小,数组应包含一个空字符

          作为一个经验法则 - 在scanf 的情况下,您将始终传递将存储输入数据的变量的地址。如果 printf 它取决于使用的格式说明符 - 就像上面显示的 %s 格式说明符需要一个地址,但 %d%c 说明符没有。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2017-06-11
            • 1970-01-01
            • 1970-01-01
            • 2021-09-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多