在 C 的结构中访问数组成员是对值或地址的访问吗?



在下面的代码中:

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].但是我无法理解这些注释,以及为什么customer.namescanf()函数是地址而printf()函数中不是地址?

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

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

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

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: %sn",bob.name); 
ptr = & bob;  
printf("Memory Address of the bob structure is:  %pn", (void *) ptr);    
printf("Memory Address of the 'bob.name'    is:  %pn", (void *) &bob.name);
printf("Memory Address of the 'bob.name[0]' is:  %pn", (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

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

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

在本中,在scanf中,您最终传递了地址,因为数组衰减为指向第一个元素的指针。不会发生这种衰减的一些情况是sizeofAlignOf或运算符&的地址等)。该指针包含数组第一个元素的地址。

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

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

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

printf中,它也是一个地址,该地址以与以前相同的逻辑传递,而print又使用它来print其中包含的字符,直到到达

标准 7.21.6.6frpintf功能说明:

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

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

最新更新