结构';常量字符*x';vs';char x[30]';
嗨,对不起,我已经在这段代码上停留了一段时间,两种代码似乎都起作用了,我只是不太理解它们的区别结构';常量字符*x';vs';char x[30]';,c,struct,C,Struct,嗨,对不起,我已经在这段代码上停留了一段时间,两种代码似乎都起作用了,我只是不太理解它们的区别 struct faveThings{ const char *favFood; const char *faveFriend; }; struct dog{ const char name[20]; const char breed[20]; int height; int weight; struct faveThings dogFaves; }; 我可以完全理解
struct faveThings{
const char *favFood;
const char *faveFriend;
};
struct dog{
const char name[20];
const char breed[20];
int height;
int weight;
struct faveThings dogFaves;
};
我可以完全理解dog结构,“char name[20]”的使用对我来说完全有意义。但是对于faveThings,我很难理解“char*favFood”,我知道这是一个指针,但是如果它只是一个char,它怎么能容纳字符串呢?它不应该是一个字符数组吗
const char *favFood[20];
谢谢你的帮助,我几个小时来一直在努力寻找不同之处。
favFood
根本站不住脚。它指向某处。可以让它指向字符串中的第一个字符。按照惯例,由于c字符串可以有不同的长度,因此它们以'\0'
字符结尾。这样,即使只有指向第一个字符的指针,也可以找到字符串的结尾
因此,像strlen
这样的库函数将使用指针从第一个字符转到后面的每个字符,直到找到NUL字符
const char*favFood[20]代码>是一个完全不同的野兽。这是一个由20个指针组成的数组。每个指针都可以指向不同的东西。你说得对,const char*favFood
确实指向单个字符
,但可以理解,将有一个包含连续字符
的内存块,该指针指向第一个。因此,代码可以使用该指针访问块中的所有char
s
使用favFood
的代码还包括执行内存分配,用字符(和空终止符)填充该内存,并查看favFood
以指向该分配
const char*favFood[20]
是一个由20个指针组成的数组。const char*favFood[20]
是一个指向字符数据的指针数组
就像
*favFood[1] -------->MemLocation(0x001) = a
*favFood[2] -------->MemLocation(0x002) = b
等等,请看这里:
我希望下面的问题的答案是一组常量字符。它实际上包含五个元素,因为C语言在由“
符号分隔的字符串末尾添加了一个“\0”。在C语言中,数组对象(如MEAT
)实际上是指向数组第一个元素的指针,因此MEAT实际上是一个内存地址,而不是整个字符数组
const char[] MEAT = "Meat";
下面是指向常量字符的指针。*
符号告诉您它是一个指针。(不管你是根据所指向的类型还是变量的名称来放置星号。这可能会让人困惑,所以我通常会将类型信息放在一起,并单独命名,但我相信这不是最常见的惯例。)favFood
变量用MEAT
数组中第一个字符的地址初始化。(请记住MEAT
是一个内存地址,因此这是将一个内存地址设置为另一个相等。)
在将来的某个时候,你的动物可能会突然决定不再喜欢肉,而现在它实际上更喜欢饼干(我知道,猫比狗更有可能改变主意,但这只是一个例子)
现在,肉
和饼干
都是常量,这意味着您无法更改它们,但是favFood
本身不是常量,而是指向常量字符串(字符串中的第一个字符),因此您可以更改它
您还可以具有非常量字符串:
char nameAndFaveFood[50];
sprintf(nameAndFaveFood, "%.26s likes %.9s best.", name, favFood);
…但请确保复制的字符(包括终止的'\0'空字符)不超过分配的空间,在本例中为49个字符和一个终止符。这就是为什么sprint
函数具有精度说明符来限制子字符串的长度
您可以有指向可变内存的常量指针
char* const LIKES_FOOD = &nameAndFaveFood[27];
请注意,LIKES_FOOD
对象初始化为指向name和favefood
数组的一部分。它将始终指向该地址。您可以使用不同的name
和favFood
参数调用上一代码块中的例程,但LIKES_FOOD
将始终指向第28位nameAndFaveFood
数组中的字符。我知道它指向某个地方,但我不明白如何使用它来检索字符串,例如,我可以使用它来保存“Meat”"然后用“theDog.dogFaves.favFood”返回它,这不应该只返回一个字符“M”而不是字符串吗?@MGordon0405-theDog.dogFaves.favFood
不返回任何内容。它的计算结果是字符串中第一个字符的地址,而不是字符本身。@MGordon0405-暂时忘记字符串。你明白是什么吗要将整数数组传递给函数,只需要一个指向第一个元素的指针和数组长度?@MGordon0405-是的,您掌握了它。但是,对于字符串,终止NUL约定是适当的,以避免必须将长度传递到所有位置。这样,一个简单的指针就足以表示string@StoryTellernice解释,特别是在评论中。啊,好的,谢谢你的解释。感谢你的帮助!
char nameAndFaveFood[50];
sprintf(nameAndFaveFood, "%.26s likes %.9s best.", name, favFood);
char* const LIKES_FOOD = &nameAndFaveFood[27];