代码背后的解释,如果我在代码的printf部分使用%s而不是%c [复制]

问题描述 投票:2回答:4

这个问题在这里已有答案:

所以我很好奇解释为什么我在我的代码上得到不同的结果,如果我在我的printf部分使用%s。我知道工作的人应该使用%s而不是%c。

#include <stdio.h>

int main() {
    int i;
    char str1[12] = "Hello world!";
    printf("str1==%c\n", str1); 
    return 0;
}

我试过多次编译并获得一些不同的结果,有时介于:str1 == ,str1 ==,str1 ==(这个空白区实际上是这个网站无法显示的一些图标)

c++ c
4个回答
7
投票

在这种情况下,str1衰败到char*。随着%c你告诉printf这是一个char,它不是。指定错误的格式是未定义的行为,因此无法保证发生的事情(它可能会导致程序崩溃,甚至更糟糕的事情)。最可能发生的是它试图将该指针解释为char,这可能导致不可打印的符号。


5
投票

这里

printf("str1==%c\n", str1);

格式说明符%c期望char类型的参数但是提供的参数str1是char数组并且它衰减到char*类型,编译器应该已经报告了警告消息,如果你可以用-Wall这样的标志编译你好像被忽略了。用以下最小标志编译代码很好

gcc -Wall -Wextra -Werror -pedantic test.c

警告:format指定类型'int'但参数的类型为'char *' [-Wformat]

使用%s而不是%c

printf("str1==%s\n", str1);

4
投票

%c意味着性格,但str1不是char。因此,你要求printfstr1解释为不是。当你这样做时,你得到的结果没有明确定义。


3
投票

我假设你有关于指针的基本知识。如果不是请read about it first

代码中的“str1”是指向char数组的指针,它指向数组的第一个元素('H')。

%c修饰符用于输入char值并打印该值的ASCII表示。在这种情况下,它是'H'。

另一方面,%s修饰符的设计类似于以下方式:

1. take input a pointer to char
2. make a copy of the pointer. let it be cpointer.
3. if the value of the memory location stored in the cpointer is NULL('\0') goto 7 .
4. print the value of the memory location stored in the cpointer.
5. increament cpointer so that it point to the next element of the char array.  
6. goto 3.
7. end printing char array.

结果,它将打印整个字符串。如果你想知道它是如何在字符串的末尾找到'\ 0'的。它可以因为,当我们在声明一个char数组时指定一些值(例如:char str [] =“abc”)时,编译器会自动在最后添加一个空字符。出于这个原因,我们必须指定char数组大小比它将存储的字符串的长度大1。所以你声明应该是:

char str[13] = "Hello world!";

另外,当我们在声明char数组时赋值时,我们不需要指定数组的大小。它由编译器自动确定。所以下面的代码也可以。

char str[] = "Hello world!";
© www.soinside.com 2019 - 2024. All rights reserved.