Q1:我试图理解为什么在这段代码中,我在调用字符串指针时使用点运算符,而不是使用用于指针的箭头。
Q2:如果我尝试初始化年龄,我会使用点运算符吗?
typedef struct Person
{
char *name;
int age;
} Person;
Person* deletePerson(Person *person, int totalPeople)
{
int i;
for(i=0; i<totalPeople; i++)
{
free(person[i].name);
free(person);
}
return NULL;
}
答案 0 :(得分:4)
当您在左侧指向结构(或联合)的指针时,您需要使用箭头->
运算符;当您指向一个结构体(或联合)的指针时,需要使用点.
左侧的结构。它不取决于右边的内容。
如果person
是指向单个Person
的指针,则要访问其字段,则可以使用person->name
和person->age
。
但是这里person
显然是指向Person
数组的第一个元素的指针。 (指向第一个元素的指针是如何在C中传递数组。)要访问数组的单个元素,请使用下标运算符(方括号[…]
):person[i]
。 person[i]
是索引为i
的元素,而不是指向索引为i
的元素的指针。由于person[i]
是一个结构,因此您可以使用点运算符来访问其字段。
此外,正如其他人已经提到的那样,循环内的free(person);
毫无意义。处理完第一个元素后,就可以释放整个数组。清理完数组的所有元素后,请在循环后调用free(person)
(假设person
已分配给malloc
)。
答案 1 :(得分:1)
person->name
将与person[0].name
同义;由于您要引用任意person
的名称,因此无法使用->
。
(我想您会使用(person+i)->name
,但是您的原始代码更清晰,恕我直言。)
关于初始化age
:除了.
以外,您还会使用什么?
P.S。在循环中free
person
意味着a)您多次释放它,并且b)person[i]
将在第一次迭代后出现问题。
答案 2 :(得分:0)
对于初学者来说,该功能无效且存在错误。
我想你是说
Person* deletePerson(Person *person, int totalPeople)
{
for ( int i=0; i < totalPeople; i++ )
{
free( person[i].name );
free( person[i] );
}
free( person );
return NULL;
}
此声明
free(person[i].name);
可以等效地重写
free( ( person + i )->name );
甚至喜欢
free( ( *( person + i ) ).name );
但是第一条语句更具可读性。
根据C标准(6.5.2.1数组下标)
2后缀表达式,后跟方括号[] 是数组对象元素的下标名称。的 下标运算符[]的定义是 E1 [E2]相同 到(*((E1)+(E2)))。由于适用于 二进制+运算符,如果E1是数组对象(相当于一个指针) 到数组对象的初始元素),并且E2是整数, E1 [E2]表示E1的第E2个元素(从零开始计数)。
答案 3 :(得分:0)
在C中,->运算符是(* var).field的替代品, 并且[]代替*(ptr + n)。
在您的代码中,该行:
free(person[i].name);
等效于:
free((*(person + i)).name)
如果使用->代替点运算符,那将是错误的。 我可以看到为什么感到困惑,为了使其看起来更简单,函数参数“ Person * person”基本上是struct Person的数组,等效于“ Person person []”。 如果仅访问数组中的第一个Person,则可以使用person-> name,该名称与person [0] .name
相同