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
这将打印字符串