C 没有指针的奇怪输出

C 没有指针的奇怪输出,c,pointers,char,C,Pointers,Char,我是C语言的初学者,我想写一个程序,将用户输入转换成莫尔斯电码。 这就是我所做的: char-morseCode[26][4]={ “-”,/*A*/ “-…”、/*B*/ “-.-.”,/*C**/ “-…”,/*D*/ “,/*E*/ “.-.”,/*F**/ “-。”,/*G*/ “…”,/*H**/ “.”,/*I*/ “----”,/*J*/ “-.-”,/*K*/ “-…”、/*L**/ “-”,/*M*/ “-。”,/*N*/ “----”,/*O*/ “--.”,/*P**/ “

我是C语言的初学者,我想写一个程序,将用户输入转换成莫尔斯电码。 这就是我所做的:

char-morseCode[26][4]={
“-”,/*A*/
“-…”、/*B*/
“-.-.”,/*C**/
“-…”,/*D*/
“,/*E*/
“.-.”,/*F**/
“-。”,/*G*/
“…”,/*H**/
“.”,/*I*/
“----”,/*J*/
“-.-”,/*K*/
“-…”、/*L**/
“-”,/*M*/
“-。”,/*N*/
“----”,/*O*/
“--.”,/*P**/
“-.-”,/*Q**/
“-”,/*R*/
“…”、/*S*/
“-”,/*T*/
“.-”,/*U*/
“…-”,/*V**/
“-”,/*W*/
“-…-”,/*X**/
“-.-”,/*Y**/
“--…”“/*Z*/
};
字符[100],新闻字符串[100];
国际奥委会;
int main(){
//printf(“莫尔斯电码[%d]=%s\n”,2,莫尔斯电码[2]);
printf(“输入文本(最多100个字符):”;
fgets(美国贸易署,100,标准DIN);
printf(“\n输入摩尔斯电码:\n”);
对于(int i=0;i
请注意,我在注释中放置了一个*,在那里我遇到了输出错误。这是我打印出来时的样子:

我在网上寻找解决方案,我发现有人做了同样的事情,但他宣布他的“摩尔斯电码”版本如下:

char*morseCode[]={/*这里的字符串*/};
当我这样做的时候,一切工作都很完美,输出结果完全符合预期。
为什么制作
morseCode
指针可以解决这些问题?我以为任何带有
char
数据类型的数组都会立即成为指针?这是我应该一直做的最佳实践吗?

char-morseCode[26][4]
只为每个字符串分配四个字节。C中的字符串必须以空字符结尾。字符串文本,如
“-”
自动包含此字符。有些字符串有四个非空字符,例如
“-”
。因此,当包含空字符时,它们需要五个字符。由于您使用
[4]
定义了数组,因此数组中没有足够的空间容纳空字符,因此未包含空字符。这会在打印字符串时导致错误

您可以通过将
[4]
更改为
[5]
来修复它


更改为指针是有效的,因为字符串文字不是用来初始化数组的,而是放在内存中,并创建指向它们的指针。当他们初始化数组时,如果空字符不合适,则将其忽略。当它们被放入内存时,包含了空字符。

代码的问题是
char[26][4]
类型的第二维度(4)不够大,无法包含某些字符串的内容,因为其中一些字符串由四个可打印字符加上一个字符串终止符组成。当您使用这样的字符串来初始化一个数组元素时,只使用前四个字符,使该元素没有终止符。未定义的行为是由于试图将其中一个未终止的元素当作字符串来使用而导致的。这个问题可以通过将声明更改为

char morseCode[26][5] = /* ... */
在任何情况下为字符串终止符留出足够的空间

为什么制作
morseCode
指针可以解决这些问题

制作
morseCode
一个指针数组解决了这个问题,因为该数组包含指向字符串文本的指针,这些字符串文本总是正确终止,而不是直接包含字符

我以为任何具有char数据类型的数组都会立即成为指针

没有。没有专门与
char
数组相关的特殊行为。通常,您可能会想到数组的属性,即在几乎所有上下文中,当对数组值表达式求值时,生成的数组会自动转换为指向数组第一个元素的指针。这并不意味着数组和指针是一回事,特别是,这并不意味着
char*[26]
char[26][4]
相同。前者的元素是指针(x86_64上各有8个字节)。后者的元素是四个
char
s的数组(4个字节,不考虑体系结构)

这只是我应该一直做的最佳实践吗


最好的做法不是将指针优先于数组,也不是将指针数组优先于数组数组。你需要学习并理解其中的差异。然后,您应该选择在任何给定编程情况下更合适的选项。

不要弄乱字符串,而是执行类似于
int index=uString[i]-“A”的操作。
。在继续操作并引用无效索引之前,还应确保输入不超出允许的范围。这一行包含初学者犯下的一个常见且不幸的错误:
for(int i=0;i
每次通过循环计算字符串的长度。在进入循环之前,通过计算一次长度并保存结果来修复它