结构'const char * x'对'char x [30]'

时间:2017-01-12 12:32:06

标签: 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;

};

我完全可以理解狗结构使用'char name [20]'对我来说完全有道理。但是使用faveThings我会遇到'char * favFood',我知道这是一个指针,但如果它只是一个字符,它怎么能保持一个字符串呢?它不应该是一系列字符吗?

const char *favFood[20];

感谢任何帮助,我一直在撞墙,试图找到差异。

4 个答案:

答案 0 :(得分:6)

favFood没有字符串。它指向某个地方。并且可以指向一个字符,该字符是 in 字符串中的第一个字符。按照惯例,由于c字符串可以具有不同的长度,因此它们以'\0'字符终止。这样,即使你拥有的是指向第一个字符的指针,你也可以找到字符串的结尾。

所以像strlen这样的库函数会使用指针从第一个字符到每个后续字符,直到它找到NUL字符。

const char *favFood[20];是一个完全不同的野兽。它是一个20个指针的数组。每个指针都可以指向不同的东西。

答案 1 :(得分:1)

你是对的,const char *favFood;确实指向单个char,但据了解,将会有一个包含连续char s的内存块,以及该指针指向第一个。因此代码可以使用该指针访问块中的所有char

使用favFood的代码还将涉及执行内存分配,使用字符填充内存(以及空终止符),并看到favFood指向该分配。

const char *favFood[20];将是一个包含20个指针的数组。

答案 2 :(得分:0)

const char *favFood[20]是一个指向字符数据的指针数组。

就像

*favFood[1] -------->MemLocation(0x001) = a
*favFood[2] -------->MemLocation(0x002) = b

依此类推:Can I create an Array of Char pointers in C?

我希望能回答你的问题

答案 3 :(得分:0)

下面是一个常量字符数组。它实际上包含五个元素,因为C语言在由"符号分隔的字符串末尾添加了一个'\ 0'。在C中,数组对象(例如MEAT)实际上是指向数组第一个元素的指针,因此MEAT实际上是一个内存地址而不是整个字符数组!

const char[] MEAT = "Meat";

下面是指向const char的指针。 *符号告诉您它是一个指针。 (如果按照指向的类型或变量的名称放置星形并不重要。这可能会让人感到困惑,所以我通常会将类型信息保存在一起并自己拥有名称,但我相信这一点这不是最常见的约定。)favFood变量初始化为MEAT数组中第一个字符的地址。 (请记住MEAT是一个内存地址,所以这是将一个内存地址设置为另一个。)

const char* favFood = MEAT;

在未来的某个时刻,你的动物可能突然决定它不再喜欢吃肉了,现在它实际上更喜欢吃饼干(我知道,它更可能是猫改变主意而不是狗,但这仅仅是一个例子)。

const char BISCUITS[] = "Biscuits";

/* Some code is done here, until you find... */

favFood = BISCUITS;

现在,MEATBISCUITS都是常量,这意味着您无法更改它们,但favFood本身不是常量,而是指向一个常量字符串(字符串中的第一个字符)无论如何),所以你可以改变它!

您还可以拥有非常量字符串:

char nameAndFaveFood[50];
sprintf(nameAndFaveFood, "%.26s likes %.9s best.", name, favFood);

...但请确保不要复制更多字符 - 包括终止'\ 0'null字符 - 而不是分配空格,在本例中为49个字符和终结符。这就是sprint函数具有精度说明符来限制子字符串长度的原因。

你可以有不断变化的记忆指针。

char* const LIKES_FOOD = &nameAndFaveFood[27];

请注意,LIKES_FOOD对象已初始化为指向nameAndFaveFood数组的一部分。它总是指向该地址。您可以使用不同的namefavFood参数调用上一代码块中的例程,但LIKES_FOOD将始终指向nameAndFaveFood数组中的第28个字符。