繁体   English   中英

结构中指针符号和点符号的混淆

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM