C 在printf和格式说明符中使用符号(&;)

C 在printf和格式说明符中使用符号(&;),c,C,在printf。。。它起作用了。为什么呢?格式说明符之间也有所不同,例如在scanf中使用%c或%d时,不需要在

printf
。。。它起作用了。为什么呢?格式说明符之间也有所不同,例如在
scanf
中使用
%c
%d
时,不需要在
中输入
&
(与号)符号。为什么会发生这种情况?它与数据类型有关吗?哪些格式说明符得出了这种结果


(很抱歉我的英语不好。我不是以英语为母语的人,这是我第一次来这里)。格式说明符需要指向字符串的指针。当与
scanf
一起使用时,它必须是一个
char
数组,包含足够的字符,用于输入的单词加上表示字符串结尾的尾随空字节。在
printf()
中,它必须是以null结尾的
char
数组

使用指向
char
变量的指针不起作用,因为它没有空字节的空间。通过在变量外部写入,导致了未定义的行为

#include <stdio.h>
#include <stdlib.h>

int main() {
    char  a;
    printf("What? \t");

    scanf("%s", &a);

    printf("U have to %s", &a);
    return 0;
}
您可以使用
%c
读取和写入单个字符,而不是多个字符组成的字符串

char word[100];
scanf("%s", word);
printf("%s\n", word);

在语句
chara中
a
是字符变量&要扫描字符变量,请使用
%c
格式说明符

char letter;
scanf("%c", &letter);
printf("%c\n", letter);
如果您想使用
%s
进行扫描,那么您的输入应该是类似
char buf[10]
的char缓冲区。例如

scanf("%s",a);/* %s expects base address of char buffer, not single char */
scanf(" %c",&a);/* this is correct */
当您使用%c或%d时,您不需要在printf中输入(&(和)符号吗?无需向
printf()
提供地址
,因为
printf()
的工作是打印而不是扫描。例如

char a[10];
scanf("%s",a);
那么,如果您打印地址,您可以使用
%p

char input;
scanf("%c",&input);/* here you need &, As scanf() will store input char into
                      address you provided i.e &input */
printf("%c",input);/*here no need &input, bcz input char already stored,
                     printf will just print the char*/

这里您看到的是一个经典的代码示例,它似乎可以工作,但原因是错误的

让我们回顾一下关于
printf
scanf
的一些事情。格式说明符
%d
用于
int
类型的值。可以读取如下所示的整数:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char  a;
    printf("What? \t");

    scanf("%s", &a);

    printf("U have to %s", a);
    return 0;
}
printf("%p",a);/*a is char buffer */
int i;
scanf("%d", &i);
scanf("%s", &s[0]);
你可以像这样把它打印出来:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char  a;
    printf("What? \t");

    scanf("%s", &a);

    printf("U have to %s", a);
    return 0;
}
printf("%p",a);/*a is char buffer */
int i;
scanf("%d", &i);
scanf("%s", &s[0]);
为什么一个人使用
&
,而另一个人不使用?C使用所谓的“传递值”。如果我们写

printf("%d\n", i);
我们将把
i
的值传递给
scanf
。但我们不希望将
i
的(旧)值传递给
scanf
,我们希望
scanf
读取新值,并将其存储到
i
中。换句话说,我们希望
scanf
实际上将
i
的新值传递给我们。为此,我们将传递
scanf
一个指针,指向变量
i
,我们希望它存储刚刚读取的整数。这就是
&
所做的——它生成一个指向
i
的指针

另一方面,当我们调用
printf
时,传递参数的常规方法工作得很好。我们确实希望将
i
的值传递给
printf
,以便它可以打印出来。如果我们打电话

scanf("%d", i);    /* WRONG */
它不起作用,因为
printf
需要一个
int
,而这里我们错误地给它一个指向-
int
的指针

现在我们了解到,对于具有
%d
的整数,
printf
需要
int
,而
scanf
需要指向-
int
的指针

让我们来谈谈角色。格式
%c
用于字符。我们可以用
scanf
读取一个字符:

printf("%d\n", &i);    /* WRONG */
我们可以用
printf
打印它:

char c;
scanf("%c", &c);
同样,模式是完全相同的
scanf
需要一个指针,以便它可以填充值,因此我们传递
&c
。但是,
printf
只需要值,所以我们传递普通的
c

现在我们来谈谈弦。C中的字符串是一个字符数组。另外,C中的字符串总是以一个特殊的空字符(
'\0'
)终止,该字符标记字符串的结尾。因此,如果我们想要声明一个变量,该变量可以包含长达9个字符的字符串,我们可以编写

printf("%c\n", c);
这给了我们9个字符的空间,加上终止的
'\0'

但是数组在C语言中是特殊的:无论何时将数组传递给函数,或者无论何时执行任何需要数组“值”的操作,都会得到一个指向数组第一个元素的指针(编译器会自动为您生成)

这意味着要使用
scanf
%s
读取字符串,我们可以调用:

char s[10];
“但是
在哪里?”你问。“我以为您在呼叫
scanf
时总是需要
&
!”

嗯,不完全是。调用
scanf
时,始终需要一个指针。事实上,当您调用scanf(“%s”,s)
时,就好像您编写了

scanf("%s", s);
printf("%s\n", s);
当您将
%s
scanf
一起使用时,它需要一个指向几个字符中第一个字符的指针,即指向字符数组开头的指针,在那里它应该开始写入它读取的字符串。(它如何知道数组有多大?如果用户键入的字符串太长而无法放入数组,该怎么办?我们马上就到这些点。)

当然,您也可以使用
%s
打印字符串,如下所示:

#include <stdio.h>
#include <stdlib.h>

int main() {
    char  a;
    printf("What? \t");

    scanf("%s", &a);

    printf("U have to %s", a);
    return 0;
}
printf("%p",a);/*a is char buffer */
int i;
scanf("%d", &i);
scanf("%s", &s[0]);
这又一次,就像你写的一样

scanf("%s", s);
printf("%s\n", s);
%s
printf
一起使用时,它需要一个指向应开始打印的几个字符中的第一个字符的指针,直到找到终止的
'\0'
字符为止

因此
%s
对于
printf
scanf
是特殊的,因为字符串是特殊的(因为数组是特殊的)。使用
%d
%c
以及几乎所有其他格式说明符,当调用
scanf
时,通常需要
&
,而当调用
printf
时,通常不需要
&
。但是对于
%s
,您通常不希望eit使用
&