C 引用字符串时Printf函数

C 引用字符串时Printf函数,c,printf,C,Printf,如果 为什么 char d[3]; d[0] ='p'; d[1] ='o'; d[2] ='\0'; 不会正常工作 但如果我有 printf("%s\n",d[0]); printf(“%s%s\n”,n[0],n[1]) 它将打印整个字符串?因为 char n[2][4]; n[0][0]=’T’; n[0][1]=’o’; n[0][2]=’m’; n[0][3]=0; n[1][0]=’S’; n[1][1]=’u’; n[1][2]=’e’;

如果

为什么

char d[3];
     d[0] ='p';
     d[1] ='o';
     d[2] ='\0';
不会正常工作

但如果我有

printf("%s\n",d[0]);    
printf(“%s%s\n”,n[0],n[1])

它将打印整个字符串?

因为

char n[2][4];
n[0][0]=’T’; n[0][1]=’o’; n[0][2]=’m’; n[0][3]=0;
n[1][0]=’S’; n[1][1]=’u’; n[1][2]=’e’; n[1][3]=0;

因为

char n[2][4];
n[0][0]=’T’; n[0][1]=’o’; n[0][2]=’m’; n[0][3]=0;
n[1][0]=’S’; n[1][1]=’u’; n[1][2]=’e’; n[1][3]=0;

printf(“%s\n”,d[0])在技术上是不正确的。的文档介绍了各种转换说明符

s

如果不存在l修饰符:const char*参数应为 是指向字符类型数组的指针(指向字符串的指针)。 数组中的字符最多写入(但不包括)一个 终止空字节('\0')

如果启用警告,即
-Wall
,您可能会得到:

 n - is and array of and array of characters. I.e. an array of strings
要了解第二个示例的工作原理,请阅读。詹姆斯·麦克内利斯写道:

<>在C和C++中,数组可以用作指针 第一个要素。实际上,给定一个名为x的数组,您可以替换
&x[0]
的大多数用法仅使用x

[……]

warning: format '%s' expects argument of type 'char *', but argument 2 has type 
         'int' [-Wformat=]
      printf("%s\n",d[0]);
所以
n[0]
等同于
&n[0][0]
,正如
d
等同于
&d[0]
。但是
d
并不等同于
d[0]
printf(“%s\n”,d[0])在技术上是不正确的。的文档介绍了各种转换说明符

s

如果不存在l修饰符:const char*参数应为 是指向字符类型数组的指针(指向字符串的指针)。 数组中的字符最多写入(但不包括)一个 终止空字节('\0')

如果启用警告,即
-Wall
,您可能会得到:

 n - is and array of and array of characters. I.e. an array of strings
要了解第二个示例的工作原理,请阅读。詹姆斯·麦克内利斯写道:

<>在C和C++中,数组可以用作指针 第一个要素。实际上,给定一个名为x的数组,您可以替换
&x[0]
的大多数用法仅使用x

[……]

warning: format '%s' expects argument of type 'char *', but argument 2 has type 
         'int' [-Wformat=]
      printf("%s\n",d[0]);

所以
n[0]
等同于
&n[0][0]
,正如
d
等同于
&d[0]
。但是
d
并不等同于
d[0]
d[0]
是数组中包含的第一个字符,而
printf
需要第一个字符的地址

它是在源代码中使用
d
时得到的地址,或者您可以使用
&(d[0])
显式计算它,数组开头的地址处的字符地址:-)

二维数组工作的原因完全相同:
n[0]
n[0][0]
的地址,与
d
d[0]
的地址相同


如果要将
n[0][0]
(字符)传递给
printf
,则会遇到与传递
d[0]
时相同的问题
d[0]
是数组中包含的第一个字符,而
printf
需要第一个字符的地址

它是在源代码中使用
d
时得到的地址,或者您可以使用
&(d[0])
显式计算它,数组开头的地址处的字符地址:-)

二维数组工作的原因完全相同:
n[0]
n[0][0]
的地址,与
d
d[0]
的地址相同


如果要将
n[0][0]
(字符)传递到
printf
,则会遇到与传递
d[0]
时相同的问题。当您尝试打印字符串
d
时,将数组的第一个字符传递给它:

void f(int* p);

int x[5];
f(x);     // this is the same as f(&x[0])
  • d[0]
    表示“存储在数组
    d
    的索引
    0
    中的对象”。这是文本字符
    'p'
    ,而不是字符串的开头
  • 使用字符串(
    %s
    )将字符传递给
    printf
    ,会导致未定义的行为,并可能导致问题。不要这样做
  • 使用
    printf
    打印字符串时,需要传递一个指向字符串的指针,该指针指向字符串的第一个元素(而不是元素本身)

    这计算为数组
    d
    0
    th索引的地址
    此外,我们可以利用数组降级为该类型指针的事实

    &d[0];
    ^^ ^
    || Index 0
    |array d
    Address of
    
    这意味着我们可以去掉
    &
    []
    运算符,只需传入
    d

    &d[0] == &(*(d+0)) == d
    
    这将打印字符串

    在第二个示例中,使用二维数组
    [][]
    提供了额外的间接级别(相当于
    字符**
    )。
    这意味着,当您调用
    printf
    时,当您传入
    n[0]
    n[1]
    时,实际上是传入指向每个字符串中第一个字符的指针。i、 e.
    &n[0][0]
    &n[1][0]


    当您尝试打印字符串
    d
    时,将数组的第一个字符传递给它:

    void f(int* p);
    
    int x[5];
    f(x);     // this is the same as f(&x[0])
    
  • d[0]
    表示“存储在数组
    d
    的索引
    0
    中的对象”。这是文本字符
    'p'
    ,而不是字符串的开头
  • 使用字符串(
    %s
    )将字符传递给
    printf
    ,会导致未定义的行为,并可能导致问题。不要这样做
  • 使用
    printf
    打印字符串时,需要传递一个指向字符串的指针,该指针指向字符串的第一个元素(而不是元素本身)

    这计算为数组
    d
    0
    th索引的地址
    此外,我们可以利用数组降级为该类型指针的事实

    &d[0];
    ^^ ^
    || Index 0
    |array d
    Address of
    
    这意味着我们可以去掉
    &
    []
    运算符,只需传入
    d

    &d[0] == &(*(d+0)) == d
    
    这将打印字符串