我正在学习C,我对char数组和字符串之间的差异以及它们如何工作感到困惑。
问题1:
为什么源代码1和源代码2的结果有所不同?
源代码1:
#include <stdio.h>
#include <string.h>
int main(void)
{
char c[2]="Hi";
printf("%d\n", strlen(c)); //returns 3 (not 2!?)
return 0;
}
源代码2:
#include <stdio.h>
#include <string.h>
int main(void)
{
char c[3]="Hi";
printf("%d\n", strlen(c)); //returns 2 (not 3!?)
return 0;
}
问题2:
字符串变量与char数组有何不同?如何使用允许\ 0存储的最小所需索引号来声明它们(请阅读下面的代码)?
char name[index] = "Mick"; //should index be 4 or 5?
char name[index] = {'M', 'i', 'c', 'k'}; //should index be 4 or 5?
#define name "Mick" //what is the size? Is there a \0?
问题3:
终止NUL是仅遵循字符串而不是字符数组吗?所以字符串“Hi”的实际值是[H] [i] [\ 0],字符数组“Hi”的实际值是[H] [i]?
问题4:
假设c [2]将存储“Hi”后跟一个\ 0(不确定如何完成,使用gets(c)
可能?)。那么\ 0存储在哪里?它是在c [2]之后“某处”存储为[H] [i] \ 0或将c [2]附加一个\ 0变为c [3],即[H] [i] [\ 0 ]?
令人困惑的是,有时在字符串/ char数组后面有一个\ 0,当我比较两个变量时会导致麻烦,if (c1==c2)
因为它很可能返回FALSE(0)。
详细的答案表示赞赏。但保持你的答案简短有助于我理解:)提前谢谢!
发布于 2019-06-03 09:48:13
问题1: 为什么源代码1和源代码2的结果有所不同?
源代码1:
#include <stdio.h>
#include <string.h>
int main()
{
char c[2]="Hi";
printf("%d", strlen(c)); //returns 3 (not 2!?)
getchar();
}
源代码2:
#include <stdio.h>
#include <string.h>
int main()
{
char c[3]="Hi";
printf("%d", strlen(c)); //returns 2 (not 3!?)
getchar();
}
回答:因为在第一种情况下,c[]
只持有“嗨”。strlen最后会找到一个零,并且,根据后面的确切内容,c[]
迟早会发现一个或者崩溃。我们不能不知道c[]
阵列后面的内存究竟是什么。
问题2: 字符串变量与char数组有何不同?如何使用允许\ 0存储的最小所需索引号来声明它们(请阅读下面的代码)?
char name[index] = "Mick"; //should index be 4 or 5?
char name[index] = {'M', 'i', 'c', 'k'}; //should index be 4 or 5?
回答 真的取决于你想做什么。如果你想将内容实际用作字符串,可能就是5。但是没有什么可以说你不能将“Mick”存储在4个字符的数组中 - 你只是不能使用strlen来找出它有多长,因为strlen将继续5并且很可能(很多)进一步找到长度如果在接下来的几个内存位置中没有零,则可能导致崩溃,因为最终,将无法读取有效的内存地址。
#define name "Mick" //what is the size? Is there a \0?
这完全没有大小,直到你使用名称somwhere。#defines并非编译器看到的部分-预处理器将取代name
使用"Mick"
,如果你使用name
的任何地方-希望,这是在一个地方,编译器就感。然后应用与之前的答案相同的规则 - 这取决于您希望如何使用字符数组。要使用strlen
,strpy
以及几乎所有其他str...
功能正确操作,最后需要零。
问题3: 终止null是仅遵循字符串而不是字符数组?所以字符串“Hi”的实际值是[H] [i] [\ 0],字符数组“Hi”的实际值是[H] [i]?
是的,不,也许吧。这一切都取决于你如何使用"Hi"
字符串文字(这是“双引号内的东西”的技术名称)。如果编译器是“允许的”,它将在结尾处放置零。但是如果你将一个数组初始化到一个给定的大小,它会把字节填入那里,如果没有空间,那就是你的问题,而不是编译器的问题。
问题4: 假设c [2]将存储“Hi”后跟一个\ 0(不确定如何完成,使用gets(c)可能?)。那么\ 0存储在哪里?它是在c [2]之后“某处”存储为[H] [i] \ 0或将c [2]附加一个\ 0变为c [3],即[H] [i] [\ 0 ]?
在c [2]中,除了'H','i'之外,没有人知道存储了什么[技术上,它很可能是“地球的尽头” - 在计算机术语中,这是“不能存储的内存”读 - 在哪种情况下strlen
会使你的程序崩溃,因为strlen读取超出地球的末端]。但是如果也可以是零,一个,字母'a',数字42或任何其他8位[1]价值。
令人安静的是,有时在字符串/ char数组后面有一个\ 0,当我用if(c1 == c2)比较两个变量时会产生麻烦,因为它很可能返回FALSE(0)。
如果c1和c2是char数组,那么总是假的,因为c1和c2永远不会有相同的地址,并且当以这种方式在C中使用数组时,它变成“内存中第一个元素的地址”阵”。所以无论c1和c2的内容是什么,它们的地址都不能相同[因为它们是两个不同的变量,而且两个变量在内存中不能有相同的位置 - 就像试图将两辆车停在停车位一样只有一辆车足够大 - 不,在我们的思想实验中不允许破碎任何一辆车]。
[1] Char不保证是8位。但是现在就让我们知道。
https://stackoverflow.com/questions/-100006886
复制相似问题