C语言 为什么在使用预定义的字符数组时初始化多维字符数组失败?

2skhul33  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(156)

我是C新手,根据here的不同解释,尝试用不同的方法来初始化字符数组,发现了一个差异,根据我从上一个线程或其他资源中学到的东西,我无法解释。在gdb中如下所示的行下面的断点处停止:

char myCharArray1[] = "foo";
char myCharArray2[] = "bar";
char myCharMultiArray[2][10] = {myCharArray1, myCharArray2};
char myCharMultiArrayLiteral[2][10] = {"foo", "bar"};

在gdb中,我注意到以下几点:

ptype myCharMultiArray
type = char [2][10]
ptype myCharMultiArrayLiteral
type = char [2][10]
ptype myCharMultiArray[0]
type = char [10]
ptype myCharMultiArrayLiteral[0]
type = char [10]
info locals
myCharArray1 = "foo"
myCharArray2 = "bar"
myCharMultiArray = {"\364\360\000", "\000\000\000"}
myCharMultiArrayLiteral = {"foo", "bar"}

为什么myCharMultiArraymyCharMultiArrayLiteral的内容不同?myCharMultiArray\364\360中的数字从何而来?
如果我试图解释为什么会发生这种情况,从我目前所读到的,它可能与以下想法有关:
1.我无意中试图修改一个字符串

  1. myCharArray1myCharArray2实际上不是char [4]类型(不管gdb告诉我什么),它们只是指向字符串常量中第一个字符的指针(即“f”和“b”分别存储的地址)。
    1.创建一个新的字符数组myCharMultiArray需要一些内存,而这些内存所在的地址与myCharArray1myCharArray2的存储地址无关,并且char myCharMultiArray[2][10] = {myCharArray1, myCharArray2};的语法实际上是试图移动myCharArray1myCharArray2的数据,而不是复制它们。
    添加一个相关主题的链接(但仍然找不到重复的)。
  • 数组到指针衰减
0sgqnhkj

0sgqnhkj1#

首先,请使用这个:What compiler options are recommended for beginners learning C?
之后像gcc这样的编译器会告诉你代码是 invalid C
错误:从“char *”初始化“char”会从指针生成整数而不进行强制转换[-Wint-conversion]
您调试的是无效的C,因此,仅仅因为使用非标准编译器设置进行编译,就试图理解编译器在“宽松模式”下允许通过的内容没有多大意义。
具体地说,你的问题归结为C语言不允许我们在初始化/赋值时复制数组,为什么要这样设计,这是一个很长的故事,也没有太多的基本原理。你只需接受C语言不允许这样做,你的第一个数组确实是char[4]类型,但是当在大多数表达式中使用时,它会退化为char*(因此编译器错误中为“from char*“)。
char数组初始值设定项列表需要char项作为初始值设定项,因此“error:初始化'char'“。即使它是一个2D数组,它仍然需要char初始化器,但允许嵌套大括号,这是一个很好的做法。因此,
{ {'f', 'o', 'o', '\0'}, {'b','a','r','\0} },这是正确的C语言,尽管这样写很痛苦。因此,字符串常量被允许作为初始化的替代形式。
在字符串文字的情况下,是的,它们本身被认为是数组,但是C中的数组初始化规则提到字符串文字是具有特殊初始化规则的特殊情况。
因此char myCharMultiArrayLiteral[2][10] = {"foo", "bar"};是合适的。

相关问题