为什么在C语言中,指针可以在不进行解引用的情况下打印其内容?

20 浏览
0 Comments

为什么在C语言中,指针可以在不进行解引用的情况下打印其内容?

这个问题在这里已经有了答案

什么是\"指针解引用\"?

如何在C中打印这个字符串

C++最权威的书籍指南和列表

我创建了一个程序,发现两件事情

  1. 我使用指针地址打印整个单词,它可以工作,但当我用*s替换s时,它就不能工作了(这是为什么?) (我在printf中使用地址,而不是*s的内容)
  2. 当我使用指向指针的指针打印字符时,我什么都打印不出来(我是说当我用%c替换%s时)

我的代码:

#include
int main ()
{
    char str[10]="PinkFloyd";
    char *s;
    char **s1;
     s=&str[0];
     s1=&s;
     printf("the word is using pointer to pointer %s",*s1); //why if I used %c does not print the first character 
     printf("\n");
     printf("the word is using s pointer %s",s); // why if I had replaced with *s does not print anything
    return 0;
}

admin 更改状态以发布 2023年5月20日
0
0 Comments

%s格式说明符打印由参数指向的以空字符结尾的字符串。这意味着它从参数中的地址开始,每次打印一个字符,直到达到0(不是字符,而是实际数字值0)为止。

在您的情况下,s1是一个指向char指针的指针,字符串的第一个字符,因此反引用的*s1是指向以空字符结尾的字符串的指针。变量s是一个指向char的指针,因此反引用的*s是一个字符。

如果您使用了用于打印以空字符结尾的字符串(%s)的格式说明符并传递了一个常规字符,则会将数字值(所有字符都是数字值)传递给printf方法,并尝试读取它,就好像它是应该从中读取字符串的内存地址。%c另一方面期望数字是单个字符,而不是内存地址。

如果要打印第一个字符(%c),则对于s1,您必须使用**s1,对于s,您必须使用*s。如果要打印整个字符串(%s),则必须指向要打印的字符串的第一个字符,因此对于s1,将是*s1,对于s,您必须使用s(它已经是指向char的指针)。

// Print the entire string
const char *s = "Some String";
printf("%s", s);
// Prints:
// Some String
// Move the pointer and start inside the string
printf("%s", s + 5);
// Prints:
// String
// Print a single character
printf("%c", *s);
// Prints:
// S
// Create a pointer to a pointer to s
const char **ps = &s;
printf("%s", *ps);
// Prints:
// Some String
// Print the first character
printf("%c", **ps);
// Prints:
// S

在上面的示例中,s==*ps,因此当您反引用指向指针的指针时,您最终得到的是指向某个东西的指针。您可以在此处阅读有关printf-类函数的不同格式说明符的更多信息:https://en.cppreference.com/w/c/io/fprintf#Parameters

0
0 Comments

你不需要使用*打印一个字符串,因为实际上printf会为你做这件事。

当你使用%sprintf一起使用时,你并没有实际上将你的字符串传递给printf。你传递的是指向该字符串第一个字符的指针,printf会负责遍历字符串并打印出它的所有字符。

这与在C语言中处理字符串的方式并没有任何不同。字符串是数组,但数组在C语言中是“二等公民”,这基本上意味着你永远不会将它们全部传递。几乎在C语言中的每个库函数工作与字符串一起使用时都是使用指向它们第一个字符的指针。

如果你调用了

printf("%s", *s);      /* WRONG */

它就不起作用。 *s会给你指向指针的内容,它是字符'P'。但%s想要的是一个指针,而不是一个字符。

你也许还会发现这个问题及其答案有趣。

0