C 如何将字符串输入到指向字符的指针数组中?

C 如何将字符串输入到指向字符的指针数组中?,c,C,我的问题是如何将字符串输入到字符指针数组中?内存是在这里动态分配的还是什么?数组“name”中实际存储了什么 char *name[20]; printf("Enter a string:"); scanf("%s",name); printf("%s",name); 这段代码运行良好。它打印我输入的字符串。怎样才能像对待字符名[20]一样对待字符名[20] 内存是在这里动态分配的还是什么 没有 这段代码运行良好。它打印我输入的字符串。如何才能像对待char name[20]一样对待char*

我的问题是如何将字符串输入到字符指针数组中?内存是在这里动态分配的还是什么?数组“
name
”中实际存储了什么

char *name[20];
printf("Enter a string:");
scanf("%s",name);
printf("%s",name);
这段代码运行良好。它打印我输入的字符串。怎样才能像对待字符名[20]一样对待字符名[20]

内存是在这里动态分配的还是什么

没有

这段代码运行良好。它打印我输入的字符串。如何才能像对待char name[20]一样对待char*name[20]

程序的行为未定义

它未定义,因为它违反了
scanf
printf
函数的要求

C标准规定了
%s
规范,用于
scanf
printf
(引用标准草案文件N1570):

相应的参数应该是指向字符数组初始元素的指针

name
不是字符数组初始元素的指针。它(实际上是一个数组,但是)在衰减之后,是一个指向字符指针数组中字符的初始指针。因此,违反了要求,程序的行为未定义

你所说的“行为未定义”是什么意思

这意味着对程序的行为没有任何保证。就语言而言,该程序可能:

  • 产生你期望的产出
  • 产生你意想不到的产出
  • 生产您想要生产的产品
  • 产生一些你不想要的输出
  • 根本不生产
  • 撞车
  • 不崩溃
  • 在另一个系统上表现不同
  • 在同一系统上表现不同
  • 调试时的行为会有所不同
  • 只有当你在度假时,你的行为才会有所不同
  • 出于任何可能的原因,表现都不一样
  • 毫无理由地表现出不同的行为
  • 行为总是一样的
  • 尽管没有使用过char name[20],但其行为与使用过char name[20]时完全相同
  • 不要那样做
  • 有任何行为

要避免未定义的行为。

scanf
printf
需要一个字符数组,但您给了它一个指针数组。然而,他们无法区分差异,因为他们是可变的。这会导致未定义的行为,因此一切皆有可能

这里可能发生的情况是
scanf
只是将字符写入指针数组的内存中,而
printf
将数据视为字符,因为两个函数都不知道您提供给它的内存块应该存储指针而不是字符。打印出第二个元素可能会给您第五个字符,因为您的系统有四个字节的指针,所以第二个指针元素从第五个字节开始,因此是第五个字符

同样,您的代码表现出未定义的行为,因此上一段只是推测。这些都不是标准所保证的,你永远不应该依赖它。

虽然这是完全正确的,但从我的感觉来看,OP可能需要对这里发生的事情进行更详细的解释

char*name[20]
声明的是而不是一个指向20个字符的数组。它是一个由20个指向内存的指针组成的数组(每个指针被视为指向一个字符或一个字符数组)。声明中的
[20]
已经指定您需要20个元素,前面的(
char*
在您的例子中)指定了这些元素是什么。因此,正确的声明(在您的上下文中)只是
char name[20]

现在编译器发现您需要一个20个字符的内存块,并为您保留内存(在堆栈上,这里没有动态分配)。然后,
char name[20]
是一个连续的保留内存块,可以容纳20个字符

您可以将此块开头的地址设置为
&name[0]
,或者只需
name
。后者只是因为静态数组变量(在您的例子中是20个字符的整个块)是隐式可转换的(不同于)指向该内存块开头的指针,即
char*
。(如果您觉得不理解最后一句话,您可以咨询一下,例如this或google,例如,c中字符数组和字符指针之间的差异

下面说明了正确的代码会发生什么,您的代码会发生什么,以及为什么它是未定义行为(UB),以及为什么它(un)在您的案例中幸运地起作用

使用正确的声明
char name[20]
您可以

?character
表示缓冲区每个单元格中的内容尚未指定,但编译器将其视为字符

当您将其传递到
scanf
中,用户输入,比如“HelloKitty”,此答案将填充到编译器保留的
char[20]
内存块中

这就是你想要的

下面是您通过
char*name[20]
声明实际得到的信息

?指针
表示缓冲区每个单元格中的内容尚未指定,但编译器将其视为指向字符的指针

当您将其传递到
scanf
中,并且用户输入他们的“HelloKitty”时,此答案将填充到编译器先前保留的
char*[20]
内存块中

现在需要更多的关注