结构中指针表示法和点表示法之间的混淆

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].