结构中指针表示法和点表示法之间的混淆
Confusion between Pointer Notation and Dot Notation in Structs
我正在尝试将 Struct 中的所有名称设为小写,以便我可以比较它们并删除它们。
int removeNameCard(NameCard *idCard, int *size){
char name[80];
char *ptr;
char rubbish;
int a = 0, c = 0;
printf("removeNameCard():\n");
printf("Enter personName:\n");
scanf("%c", &rubbish); // Why is there a '\n' char here??
fgets(name, 80, stdin);
if((ptr = strchr(name, '\n'))){
*ptr = '[=10=]';
}
if((*size) == 0){
printf("The name card holder is empty\n");
return 0;
}
// Convert everything to Lower Case first
while(name[a]){
name[a] = tolower(name[a]);
a += 1;
}
printf("tolower(): %s", name);
for(int b = 0; b < *size; b += 1){
// Why is this Dot Notation when I passed in a pointer to the Struct?
while (idCard[b].personName)[c]){
(idCard[b].personName)[c] = tolower((idCard[b].personName)[c]);
c += 1;
}
}
for(int i = 0; i < *size; i += 1){
if((idCard[i].personName) == name){
printf("%d. This is from Holder: %s, This is from User: %s", i,(idCard[i].personName),name);
printf("The name card is removed\n");
printf("nameCardID: %d\n", idCard[i].nameCardID);
printf("personName: %s\n", idCard[i].personName);
printf("companyName: %s\n", idCard[i].companyName);
int k = 0;
do{
idCard[i+k].nameCardID = idCard[i+k+1].nameCardID;
strcpy((idCard[i+k].personName),(idCard[i+k+1].personName));
strcpy((idCard[i+k].companyName),(idCard[i+k+1].companyName));
}while((i+k+1) != (*size + 1));
}
}
return 0;
}
但是,我很困惑为什么编译器要求我使用点表示法而不是指针表示法,因为我认为我将结构的地址传递给了 *idCard 所以它应该是一个指针,如果我没记错的话?
我这样尝试访问 Struct 的每个名称中的每个字符是不是错了?:
(idCard[b].personName)[c]
谢谢
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation as I thought I passed in the address of the Struct into *idCard so it should be a pointer if I am not wrong?
数组大多只是指向数组中第一个元素的指针(除了编译器可能知道数组大小)。
因为数组大多只是指针;对于整数数组 myInt = myIntArray[x];
就像 myInt = *(myIntArray + x);
- 指针取消引用由数组索引 隐含。请注意,要访问数组中 int
中间的 char
,您可以(不可移植)使用类似 myChar = *((char *)(myIntArray + x)) + offset_of_char_in_int);
的东西;这有点像访问结构数组中的字段(因为它们都在访问更大的数组中的更小的内容)。
对于结构数组;索引数组会导致取消引用(就像它对整数数组所做的那样);所以 myIDcardStruct = idCard[i];
就像 myIDcardStruct = *(idcard + i);
。因为数组索引隐含取消引用,所以 myIDcardStruct
不是指针。
->
运算符就像将请求的结构字段的偏移量添加到地址,将地址强制转换为请求的字段的类型,然后取消引用。换句话说 myInt = myStructPointer->myIntField;
就像 myInt = (*myStructPointer).myIntField;
就像 tempAddress = (void *)myStructPointer + offset_of_myIntField; myInt = *((int *)tempAddress);
.
这意味着如果你有一个结构数组(主要是指向数组中第一个结构的指针),索引数组会导致指针被隐式取消引用,并使用 ->
也会导致隐式取消引用;如果您同时执行这两项操作,那么您已经(隐式地)取消引用了一个指针两次,这是太多的取消引用(因为它不是指向结构指针的指针,也不是指向结构的指针数组)。因为您只希望在必须在一个隐式遵循(数组索引)或另一个隐式取消引用(->
)之间进行选择时取消引用;例如您可以选择 myInt = idCard[i].nameCardID;
或 myInt = (idCard + i)->nameCardID;
。
当然重要的是让代码易于阅读,myInt = idCard[i].nameCardID;
比myInt = (idCard + i)->nameCardID;
更容易阅读。
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation…
idCard[i]
是一个结构体,不是指向结构体的指针,所以它的成员被访问为idCard[i].<i>member</i>
,不是idCard[i]-><i>member</i>
.
idCard[i]
是一个结构,因为只要 x
是指针,x[i]
就是 x
指向的对象之一。它不是对象的地址。您可以使用 x+i
计算对象的地址,然后可以使用 *(x+i)
引用该对象。而x[i]
其实就是这样定义的; x[i]
定义为 *(x+i)
。 (对于一般表达式,<i>E1</i>[<i>E2</i>]
定义为 (*((<i>E1</i>)+(<i>E2</i>)))
.)
And am I wrong for trying to access each individual character in every name of the Struct like this?: (idCard[b].personName)[c]
这可行,但括号是不必要的。您可以使用 idCard[b].personName[c]
。由于 C 语法,它已被分组为 (idCard[b].personName)[c]
.
我正在尝试将 Struct 中的所有名称设为小写,以便我可以比较它们并删除它们。
int removeNameCard(NameCard *idCard, int *size){
char name[80];
char *ptr;
char rubbish;
int a = 0, c = 0;
printf("removeNameCard():\n");
printf("Enter personName:\n");
scanf("%c", &rubbish); // Why is there a '\n' char here??
fgets(name, 80, stdin);
if((ptr = strchr(name, '\n'))){
*ptr = '[=10=]';
}
if((*size) == 0){
printf("The name card holder is empty\n");
return 0;
}
// Convert everything to Lower Case first
while(name[a]){
name[a] = tolower(name[a]);
a += 1;
}
printf("tolower(): %s", name);
for(int b = 0; b < *size; b += 1){
// Why is this Dot Notation when I passed in a pointer to the Struct?
while (idCard[b].personName)[c]){
(idCard[b].personName)[c] = tolower((idCard[b].personName)[c]);
c += 1;
}
}
for(int i = 0; i < *size; i += 1){
if((idCard[i].personName) == name){
printf("%d. This is from Holder: %s, This is from User: %s", i,(idCard[i].personName),name);
printf("The name card is removed\n");
printf("nameCardID: %d\n", idCard[i].nameCardID);
printf("personName: %s\n", idCard[i].personName);
printf("companyName: %s\n", idCard[i].companyName);
int k = 0;
do{
idCard[i+k].nameCardID = idCard[i+k+1].nameCardID;
strcpy((idCard[i+k].personName),(idCard[i+k+1].personName));
strcpy((idCard[i+k].companyName),(idCard[i+k+1].companyName));
}while((i+k+1) != (*size + 1));
}
}
return 0;
}
但是,我很困惑为什么编译器要求我使用点表示法而不是指针表示法,因为我认为我将结构的地址传递给了 *idCard 所以它应该是一个指针,如果我没记错的话?
我这样尝试访问 Struct 的每个名称中的每个字符是不是错了?: (idCard[b].personName)[c]
谢谢
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation as I thought I passed in the address of the Struct into *idCard so it should be a pointer if I am not wrong?
数组大多只是指向数组中第一个元素的指针(除了编译器可能知道数组大小)。
因为数组大多只是指针;对于整数数组 myInt = myIntArray[x];
就像 myInt = *(myIntArray + x);
- 指针取消引用由数组索引 隐含。请注意,要访问数组中 int
中间的 char
,您可以(不可移植)使用类似 myChar = *((char *)(myIntArray + x)) + offset_of_char_in_int);
的东西;这有点像访问结构数组中的字段(因为它们都在访问更大的数组中的更小的内容)。
对于结构数组;索引数组会导致取消引用(就像它对整数数组所做的那样);所以 myIDcardStruct = idCard[i];
就像 myIDcardStruct = *(idcard + i);
。因为数组索引隐含取消引用,所以 myIDcardStruct
不是指针。
->
运算符就像将请求的结构字段的偏移量添加到地址,将地址强制转换为请求的字段的类型,然后取消引用。换句话说 myInt = myStructPointer->myIntField;
就像 myInt = (*myStructPointer).myIntField;
就像 tempAddress = (void *)myStructPointer + offset_of_myIntField; myInt = *((int *)tempAddress);
.
这意味着如果你有一个结构数组(主要是指向数组中第一个结构的指针),索引数组会导致指针被隐式取消引用,并使用 ->
也会导致隐式取消引用;如果您同时执行这两项操作,那么您已经(隐式地)取消引用了一个指针两次,这是太多的取消引用(因为它不是指向结构指针的指针,也不是指向结构的指针数组)。因为您只希望在必须在一个隐式遵循(数组索引)或另一个隐式取消引用(->
)之间进行选择时取消引用;例如您可以选择 myInt = idCard[i].nameCardID;
或 myInt = (idCard + i)->nameCardID;
。
当然重要的是让代码易于阅读,myInt = idCard[i].nameCardID;
比myInt = (idCard + i)->nameCardID;
更容易阅读。
However, I am rather confused why the Compiler asked me to use Dot Notation instead of Pointer Notation…
idCard[i]
是一个结构体,不是指向结构体的指针,所以它的成员被访问为idCard[i].<i>member</i>
,不是idCard[i]-><i>member</i>
.
idCard[i]
是一个结构,因为只要 x
是指针,x[i]
就是 x
指向的对象之一。它不是对象的地址。您可以使用 x+i
计算对象的地址,然后可以使用 *(x+i)
引用该对象。而x[i]
其实就是这样定义的; x[i]
定义为 *(x+i)
。 (对于一般表达式,<i>E1</i>[<i>E2</i>]
定义为 (*((<i>E1</i>)+(<i>E2</i>)))
.)
And am I wrong for trying to access each individual character in every name of the Struct like this?: (idCard[b].personName)[c]
这可行,但括号是不必要的。您可以使用 idCard[b].personName[c]
。由于 C 语法,它已被分组为 (idCard[b].personName)[c]
.