数组/指针:左操作数必须是l值

时间:2014-11-30 17:10:28

标签: c

我刚刚开始使用C,而且在混合指针和数组时我很难掌握。

我收到以下错误:

错误C2106:' =' :左操作数必须是l值

#include <stdio.h>

struct PersonDetails {
    char *name;
    int *phoneNumber;
};

int* getPhoneNumber(struct PersonDetails *phoneBook[], char* name);

int main() {

    struct PersonDetails a;
    struct PersonDetails b;
    struct PersonDetails people[2];
    struct PersonDetails *ptr[2];
    char aName = 'T';
    int aNum = 123;
    char bName = 'O';
    int bNum = 456;
    a.name = &aName;
    a.phoneNumber = &aNum;
    b.name = &bName;
    b.phoneNumber = &bNum;

    people[0] = a;
    people[1] = b;
    ptr = &people;

    printf("%d", *getPhoneNumber(ptr, aName));

    return 0;
}

int* getPhoneNumber(struct PersonDetails *phoneBook[], char* name) {
    int i;
    for (i = 0; i < 2; i++) {
        if (*phoneBook[i]->name == *name) return phoneBook[i]->phoneNumber;
    }
    return 0;
}

它正在线上发生:

ptr = &people;

已编辑的代码:

#include <stdio.h>

struct PersonDetails {
    char *name;
    int *phoneNumber;
};

int* getPhoneNumber(struct PersonDetails *phoneBook[], char* name);

int main() {
    struct PersonDetails a;
    struct PersonDetails b;
    struct PersonDetails people[2];
    struct PersonDetails *ptr;
    char aName = 'T';
    int aNum = 123;
    char bName = 'O';
    int bNum = 456;
    a.name = &aName;
    a.phoneNumber = &aNum;
    b.name = &bName;
    b.phoneNumber = &bNum;

    people[0] = a;
    people[1] = b;

    ptr = people;

    printf("%d", *getPhoneNumber(ptr, aName));

    return 0;
}

int* getPhoneNumber(struct PersonDetails *phoneBook, char* name) {
    int i;
    for (i = 0; i < 2; i++) {
        if (*phoneBook[i].name == *name) return phoneBook[i].phoneNumber;
    }
    return 0;
}

4 个答案:

答案 0 :(得分:2)

将与OP的对话中的各种评论转移到答案中

  

因为方法getPhoneNumber()需要参数struct PersonDetails *phoneBook[]

为什么getPhoneNumber()需要那种古怪的类型?必须有一个理由为什么你选择使用它(比如&#34;老师在我正在研究的问题中设定了这个&#34;)。否则,参数似乎更有可能是struct PersonDetail *whostruct PersonDetail who[] - 在函数的参数列表的上下文中(并且仅在函数的上下文中) s参数列表)相同的东西。

  

最初是PersonDetails *phoneBook,但我认为这不起作用?我想错了,我怎么会用它来使用名字找到一个数字呢?

假设您的意思是struct PersonDetails *phoneBook(代码中没有PersonDetails类型,但类型为struct PersonDetails),那么这样可以正常工作。它是一个指针参数,既可以指向单个人的详细信息,也可以指向一组人员详细信息的开头。在函数内部,只要您知道数组足够大,就可以谨慎使用phoneBook[i].namephoneBook[i].number。 (或者,确实是phoneBook->namephoneBook->number,它们引用phoneBook指向的单个元素,或者您可以将其视为使用有效的下标0。)

  哇,哇,谢谢你,这非常有帮助。所以我会将ptr更改为struct PersonDetails *ptr;而不是指针数组?

是的 - 只需使用struct PersonDetails *ptr;即可。你(不小心)钻研更复杂的结构,这些结构在更复杂的情况下占有一席之地,这就是为什么没人能说'#34;这是错误的'#34;但它们目前超出了你的需要或者你目前的理解。没关系;您刚刚学到的内容可能涵盖了95%或更多的实际使用案例。

  

好的,它现在全部编译,但在执行时崩溃。我觉得这与我如何分配ptrpeople有关。我只是删除people数组吗?如果你能帮我看一下,我在问题中添加了一个经过编辑的部分?

您现在传递charaName,其中函数需要char *&aName*。顶部的函数原型也与函数定义不匹配;定义是正确的。您需要从原型中删除[]char *,但不能同时删除两者。有了这个,它就可以了。

请注意,您没有字符串(strcmp()值不指向空终止的字符数组),因此您无法进行字符串比较(#include <stdio.h> struct PersonDetails { char *name; int *phoneNumber; }; int *getPhoneNumber(struct PersonDetails *phoneBook, char *name); int main(void) { struct PersonDetails a; struct PersonDetails b; struct PersonDetails people[2]; struct PersonDetails *ptr; char aName = 'T'; int aNum = 123; char bName = 'O'; int bNum = 456; a.name = &aName; a.phoneNumber = &aNum; b.name = &bName; b.phoneNumber = &bNum; people[0] = a; people[1] = b; ptr = people; printf("%d\n", *getPhoneNumber(ptr, &aName)); return 0; } int *getPhoneNumber(struct PersonDetails *phoneBook, char *name) { int i; for (i = 0; i < 2; i++) { if (*phoneBook[i].name == *name) return phoneBook[i].phoneNumber; } return 0; } ),但确定这可能是下一个发展阶段。

您的编译器应该已经生成警告;注意。记住,它对C的了解远远超过你现在所做的事情!

工作代码

int *p_number = getPhoneNumber(ptr, &name);
if (p_number == NULL)
    printf("No entry for name %c\n", name);
else
    printf("Number for %c is %d\n", name, *p_number);

请注意,如果&#39;名称&#39;那么直接打印显示的结果将会非常糟糕(通常)。找不到。你将取消引用一个空指针,它会调用未定义的行为 - 一件坏事™!你真的需要使用:

int *number;

您还应该检查int number;而不仅仅是char *number;+44 1395 276679的原因。如果你只是存储一个未格式化的整数,前者会更好;如果您可能需要存储char number[MAX_PHONE_NUMBER_STRING_LEN];或类似的东西,后者会更好,但您应该考虑int *getPhoneNumber(int n_entries, struct PersonDetails *phoneBook, char *name) { int i; for (i = 0; i < n_entries; i++) { if (*phoneBook[i].name == *name) return phoneBook[i].phoneNumber; } return 0; } 而不是指针的相对优点。

此外,对于更接近通用的代码,您的功能应该被告知电话簿中有多少条目,而不是使用硬连线大小2(这是一个非常小的电话簿,任何标准):

int *getPhoneNumber(int n_entries, struct PersonDetails phoneBook[n_entries], char *name)
{
    for (int i = 0; i < n_entries; i++)
    {
        if (*phoneBook[i].name == *name)
            return phoneBook[i].phoneNumber;
    }
    return 0;
}

数组中的条目数是参数。假设您有C99或C11,您也可以将其理解为:

const

在这两个最后的样本中,我没有改变结构中的数据类型(即使我认为它们应该被更改)。我还没有将const限定符添加到指针/数组或名称,即使两者都合法地{{1}} - 合格。

答案 1 :(得分:1)

struct PersonDetails *ptr[2];

ptr是一个指针数组,数组本身永远不是可修改的值。左值应该是存储值的位置(如变量)。所以这是一个错误。

答案 2 :(得分:0)

您定义如下 -

struct PersonDetails people[2];
struct PersonDetails *ptr[2];

这意味着people是类型为PersonDetails的结构的2元素数组,而ptr是指向此类结构的2元素指针数组。

你不能覆盖数组的地址,它不仅仅是一些指针(虽然有一些相互的语义),它是在堆栈上分配的。

如果您认为ptr中的每个元素都指向相应的people元素,请使用循环:

for (i = 0; i < 2; ++i)
    ptr[i] = &people[i];

另请注意,将所有这些指针传递给main中定义的简单变量的效果之一是,您可以从getPhoneNumber返回空指针,并将其传递给printf - 这将是段错误

答案 3 :(得分:0)

  • ptr是一个指向struct PersonDetails的指针数组,所以ptr [0]和ptr [1] 是指向struct PersonDetails的指针,然后你可以将struct PersonDetails类型的变量的地址设置为ptr的每个元素。

  • 在C中,数组就像一个指针(但它并不完全相同)指向一部分 内存(具有变量类型的大小乘以数组元素的数量),您可以在其中存储一个或多个类型的变量,所以在 你的例子,你可以看到人们喜欢指向struct PersonDetails的指针,ptr喜欢指向struct PersonDetails的指针。

所以,尽管如此,你可以做的是ptr [0] = people或ptr [1] = people。