指向字符串的指针以及赋值和解引用之间的区别

时间:2019-07-08 19:10:59

标签: c string pointers printf

在以下代码中:

#include <stdio.h>

int main(void) {
    char* message = "Hello C Programmer!";
    printf("%s", message);

    return 0;
}

我不完全理解为什么没有必要在'*'呼叫中添加printf到消息中。我假设message因为是指向char的指针,所以双引号字符串中的第一个字母将显示{{1 }}。

4 个答案:

答案 0 :(得分:5)

%s格式运算符要求其相应的参数为char *指针。它打印从该地址开始的整个字符串。字符串是一系列以空字节结尾的字符。这就是为什么会打印整个消息的原因。

如果提供数组作为相应的参数,它将自动转换为指向数组第一个字符的指针。通常,每当将数组用作r值时,都会进行此转换。

您不需要使用*运算符,因为该参数应该是指针。如果您使用*message,则只能将'H'字符传递给printf()。如果您使用的是%c而不是%s格式,则可以执行此操作-其对应的参数应为char

答案 1 :(得分:3)

您是正确的,message是一个指针,类型为“ char的指针”或char *。因此,如果您要打印一个字符(单个字符),则肯定需要一个*

printf("first character: %c\n", *message);

在printf格式说明符中,%c需要一个字符,这就是*message给您的字符。

但是您不是要打印单个字符,而是要打印整个字符串。并且在printf格式说明符中,%s期望字符的 pointer ,通常是要打印的多个字符中的第一个。所以

printf("entire string: %s\n", message);

是正确的。

答案 2 :(得分:2)

转换说明符%s用于输出指向第一个字符的字符串(以零字符'\0'结尾的字符序列)的指针,并将其作为参数传递给函数printf。

您可以想象该函数在内部执行以下循环

for ( ; *message != '\0'; ++message )
{
    printf( "%c", *message );
} 

如果将提供表达式*message,则其类型为char,并且函数printf将尝试将其值为字符'H'的值解释为指针的值。结果,该函数调用将具有未定义的行为。

要输出指针message的值,您应该像这样使用转换说明符%p

printf( "%p", message );

或者例如作为整数值

#include <stdio.h>
#include <inttypes.h>

int main(void) 
{
    char *message = "Hello C Programmer!";

    printf( "The value of the pointer message is %" PRIiPTR "\n", ( intptr_t )message );

    return 0;
}

答案 3 :(得分:1)

此外,这里必须使用一个指针。

如果您传递了一个字符,它将按值传递,并且printf将丢失该字符的原始地址。这意味着将无法再访问第一个字符之后的字符。

您需要按值传递指针,以确保保留字符串开头的原始地址。