我刚刚开始使用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;
}
答案 0 :(得分:2)
将与OP的对话中的各种评论转移到答案中
因为方法
getPhoneNumber()
需要参数struct PersonDetails *phoneBook[]
。
为什么getPhoneNumber()
需要那种古怪的类型?必须有一个理由为什么你选择使用它(比如&#34;老师在我正在研究的问题中设定了这个&#34;)。否则,参数似乎更有可能是struct PersonDetail *who
或struct PersonDetail who[]
- 在函数的参数列表的上下文中(并且仅在函数的上下文中) s参数列表)相同的东西。
最初是
PersonDetails *phoneBook
,但我认为这不起作用?我想错了,我怎么会用它来使用名字找到一个数字呢?
假设您的意思是struct PersonDetails *phoneBook
(代码中没有PersonDetails
类型,但类型为struct PersonDetails
),那么这样可以正常工作。它是一个指针参数,既可以指向单个人的详细信息,也可以指向一组人员详细信息的开头。在函数内部,只要您知道数组足够大,就可以谨慎使用phoneBook[i].name
或phoneBook[i].number
。 (或者,确实是phoneBook->name
和phoneBook->number
,它们引用phoneBook
指向的单个元素,或者您可以将其视为使用有效的下标0。)
哇,哇,谢谢你,这非常有帮助。所以我会将ptr更改为struct PersonDetails *ptr;
而不是指针数组?
是的 - 只需使用struct PersonDetails *ptr;
即可。你(不小心)钻研更复杂的结构,这些结构在更复杂的情况下占有一席之地,这就是为什么没人能说'#34;这是错误的'#34;但它们目前超出了你的需要或者你目前的理解。没关系;您刚刚学到的内容可能涵盖了95%或更多的实际使用案例。
好的,它现在全部编译,但在执行时崩溃。我觉得这与我如何分配
ptr
和people
有关。我只是删除people
数组吗?如果你能帮我看一下,我在问题中添加了一个经过编辑的部分?
您现在传递char
值aName
,其中函数需要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。