[英]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 = '\0';
}
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 中,所以如果我没有错,它应该是一个指针?
我是否错误地尝试访问结构的每个名称中的每个字符? : (idCard[b].personName)[c]
谢谢
但是,我很困惑为什么编译器要我使用点表示法而不是指针表示法……
idCard[i]
是一个结构体,而不是一个结构体的指针,所以它的成员作为idCard[i].
被访问idCard[i].
, not idCard[i]->
. ,而不是
idCard[i]->
。
idCard[i]
是一个结构体,因为每当x
是一个指针时, x[i]
就是x
指向的对象之一。 它不是对象的地址。 您可以使用x+i
计算对象的地址,然后您可以使用*(x+i)
引用该对象。 而x[i]
其实是这样定义的; x[i]
被定义为*(x+i)
。 [ ] is defined to be (*(( )+( )))
.) (在一般表达式的情况下, [ ]
被定义为(*(( )+( )))
。)
我是否错误地尝试访问结构的每个名称中的每个字符? : (idCard[b].personName)[c]
这会起作用,但括号是不必要的。 您可以使用idCard[b].personName[c]
。 由于 C 语法,它已经被分组为(idCard[b].personName)[c]
。
但是,我很困惑为什么编译器要求我使用点表示法而不是指针表示法,因为我认为我将结构的地址传递到 *idCard 中,所以如果我没有错,它应该是一个指针?
数组大多只是指向数组中第一个元素的指针(编译器可能知道数组大小除外)。
因为数组大多只是指针; 对于整数数组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);
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;
更容易阅读myInt = (idCard + i)->nameCardID;
.
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.