【问题标题】:Declaring and modifying strings in C在 C 中声明和修改字符串
【发布时间】:2015-06-04 21:11:32
【问题描述】:

我最近开始尝试学习 C 编程语言。在我的第一个程序(简单的 hello world 事情)中,当我意识到我不能只做 variable_name = "string data" 后,我遇到了声明字符串的不同方法:

char *variable_name = "data"
char variable_name[] = "data"
char variable_name[5] = "data"

我不明白的是它们之间的区别。我知道它们是不同的,其中一个专门分配了一定量的内存来存储数据,但仅此而已,我觉得在转向 C 中更复杂的概念之前,我需要彻底理解这一点。

另外,为什么使用*variable_name 可以让我将变量名重新分配给一个新字符串,而variable_name[number]variable_name[] 不能?当然,如果我为其分配 10 个字节 (char variable_name[10] = "data") 并尝试将其重新分配给 10 个字节或更小的内容,它应该可以工作,那为什么不呢?

空括号和星号在做什么?

【问题讨论】:

  • 我建议你阅读c-faq- 6. Arrays and Pointers
  • 阅读@hacks 建议的链接后,您可能需要查看the section on strings
  • 不要误以为char name[10] 创建了一个包含 10 个字符的小盒子,您无法将较大的字符串复制到其中。你可以,而且你只会在很久以后才会遭受可怕的后果。
  • 感谢您的链接和@lister,您介意清楚您在说什么吗?那句话并没有真正告诉我任何技术问题
  • @Linux_Noob 这与试图将超过 10 件物品放入一个显然只能容纳您放入其中的 10 件物品的盒子里没有什么不同。该盒子可能会破裂,或者内容可能会从未关闭的盒子顶部溢出。同样,当您尝试复制超过 10 个字符时,您的程序可能会崩溃,或者在复制操作以某种方式成功后,它可能会出现异常行为(崩溃、按预期运行等)。

标签: c string variables


【解决方案1】:

在此声明中

char *variable_name = "data";

声明了一个指针。该指针指向字符串文字“data”的第一个字符。编译器将字符串文字放在内存的某个区域,并通过文字的第一个字符的地址分配指针。

您可以重新分配指针。例如

char *variable_name = "data";
char c = 'A';

variable_name = &c;

但是,您不能更改字符串文字本身。尝试更改字符串文字会导致程序的未定义行为。

在这些声明中

char variable_name[] = "data";
char variable_name[5] = "data";

声明了两个数组元素,它们由用于初始化字符串文字的字符初始化。比如这个声明

char variable_name[] = "data";

等价于以下

char variable_name[] = { 'd', 'a', 't', 'a', '\0' };

数组将有 5 个元素。所以这个声明完全等同于声明

char variable_name[5] = "data";

如果您要指定其他大小的数组,则会有所不同。例如

char variable_name[7] = "data";

在这种情况下,数组将按以下方式初始化

char variable_name[7] = { 'd', 'a', 't', 'a', '\0', '\0', '\0' };

也就是说,数组中没有显式初始化器的所有元素都被初始化为零。

注意,在 C 语言中,你可以通过以下方式使用字符串字面量声明字符数组

char variable_name[4] = "data";

即字符串文字的终止零未放置在数组中。 在 C++ 中这样的声明是无效的。

当然,如果您愿意,您可以更改数组的元素(如果它没有定义为常量数组)。

考虑到您可以将用作初始化器的字符串文字括在大括号中。例如

char variable_name[5] = { "data" };

在 C99 中,您还可以使用所谓的目标初始值设定项。例如

char variable_name[] = { [4] = 'A', [5] = '\0' };

这是一个演示程序

#include <stdio.h>
#include <string.h>

int main(void) 
{
    char variable_name[] = { [4] = 'A', [5] = '\0' };

    printf( "%zu\n", sizeof( variable_name ) );
    printf( "%zu\n", strlen( variable_name ) );

    return 0;
}

程序输出是

6
0

当 ypu 应用在标头 &lt;string.h&gt; 中声明的标准 C 函数 strlen 时,您会得到它返回 0,因为在索引为 4 的元素之前的数组的第一个元素被初始化为零。

【讨论】:

  • 非常感谢。这篇文章为我清除了它。我需要将线程标记为已解决或其他什么吗?另外,如果这里有这样的功能,我如何为您的帖子投票?
  • @Linux_Noob 首先看我更新的帖子。您可以将其标记为最佳答案。:)
  • @Linux_Noob;你有足够的声望来投票。只需单击答案左上角朝上的箭头即可。您可以通过点击答案左上角的V 标记来接受答案。
  • @Vlad 我不太明白这些目标初始化程序发生了什么。你介意解释一下,例如,[4] = 'A' 在做什么?为什么 strlen 在返回数字之前不查看整个数组?因为(正如我在阅读对该线程和其他人的回复后所假设的那样)C 中的所有字符串实际上都是单个字符的数组,所以 strlen 不应该返回整个数组的长度吗?
  • @Linux_Noob 当你使用这样的声明时 char s[] = { [4] = 'A' };那么在索引为 4 的元素之前的所有元素都被初始化为零,因为它们没有显式的初始化器。函数 strlen 对字符数组中的符号进行计数,直到遇到终止零。由于数组 s 的第一个字符为零,因此初始化函数 strlen 将返回 0。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多