Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C语言打印指针_C_Pointers - Fatal编程技术网

用C语言打印指针

用C语言打印指针,c,pointers,C,Pointers,我试图理解指针,所以我写了以下代码: #include <stdio.h> int main(void) { char s[] = "asd"; char **p = &s; printf("The value of s is: %p\n", s); printf("The direction of s is: %p\n", &s); printf("The value of p is: %p\n", p); pr

我试图理解指针,所以我写了以下代码:

#include <stdio.h>

int main(void)
{
    char s[] = "asd";
    char **p = &s;

    printf("The value of s is: %p\n", s);
    printf("The direction of s is: %p\n", &s);

    printf("The value of p is: %p\n", p);
    printf("The direction of p is: %p\n", &p);

    printf("The direction of s[0] is: %p\n", &s[0]);
    printf("The direction of s[1] is: %p\n", &s[1]);
    printf("The direction of s[2] is: %p\n", &s[2]);

    return 0;
}
(gcc的标志是因为我必须是C89)

为什么指针类型不兼容?数组的名称不是指向它的第一个元素的指针吗?因此,如果s是指向“a”的指针,
&s
必须是
字符**
,不是吗? 为什么我会收到其他警告?我是否必须使用(
void*
)强制转换指针才能打印它们

当我跑步时,我会得到这样的东西:

$ ./main-bin
The value of s is: 0xbfb7c860
The direction of s is: 0xbfb7c860
The value of p is: 0xbfb7c860
The direction of p is: 0xbfb7c85c
The direction of s[0] is: 0xbfb7c860
The direction of s[1] is: 0xbfb7c861
The direction of s[2] is: 0xbfb7c862
s的值和它的方向(当然还有
p
的值)怎么可能是相同的呢?

您使用了:

char s[] = "asd";
这里的s实际上指向字节“asd”。s的地址也将指向此位置

如果您使用:

char *s = "asd";
s和&s的值会有所不同,因为s实际上是指向字节“asd”的指针

您使用了:

char s[] = "asd";
char **p = &s;

这里s指向字节“asd”。p是指向字符的指针,并已设置为字符的地址。换句话说,你在p中有太多的间接。如果使用char*s=“asd”,则可以使用此附加间接寻址。

是的,您的编译器预期为void*。把它们丢到空里去*

/* for instance... */
printf("The value of s is: %p\n", (void *) s);
printf("The direction of s is: %p\n", (void *) &s);
换行:

字符s[]=“asd”

致:

char*s=“asd”


事情会变得更清楚

如果将数组的名称作为参数传递给函数,它将被视为传递了数组的地址。So&s和s是相同的参数。见K&R 5.3&s[0]与&s相同,因为它获取数组第一个元素的地址,这与获取数组本身的地址相同

对于所有其他指针,尽管所有指针本质上都是内存位置,但它们仍然是类型化的,编译器将警告是否将一种类型的指针分配给另一种类型的指针

  • void*p说p是一个内存地址,但我不知道内存中有什么
  • char*s表示s是一个内存地址,第一个字节包含一个字符
  • char**ps
    表示ps是内存地址,其中的四个字节(对于32位系统)包含char*类型的指针

cf(K&R的电子书版)

您不能更改静态数组的值(即地址)。从技术上讲,数组的左值是其第一个元素的地址。因此
s==&s
。这只是语言的一个怪癖。

“s”不是“char*”,而是“char[4]”。因此,“&s”不是“char**”,而是“指向4个character数组的指针”。您的编译器可能会将“&s”视为您编写了“&s[0]”,这大致相同,但却是一个“char*”

当您编写“char**p=&s;”时,您试图说“我希望p被设置为当前指向“asd”的对象的地址。但当前没有指向“asd”的内容。只有一个数组包含“asd”


通常,不必要地将指针强制转换为(void*)会被认为是糟糕的样式。但是,在这里,您需要将强制转换为(void*)因为printf是可变的。原型不会告诉编译器在调用站点将指针转换为什么类型。

它不是指向character
char*
的指针,而是指向4个字符数组的指针:
char*[4]
。使用g++它不会编译:

main.cpp:在函数“int main(int,char**)”中:main.cpp:126:错误: 无法在初始化时将“char(*)[4]”转换为“char**”

此外,linux手册页:

p

void*指针参数以十六进制打印(好像由%#x或 %#lx)。 它应该是指向void的指针

您可以将代码更改为:

char* s = "asd";
char** p = &s;

printf("The value of s is: %p\n", s);
printf("The address of s is: %p\n", &s);

printf("The value of p is: %p\n", p);
printf("The address of p is: %p\n", &p);

printf("The address of s[0] is: %p\n", &s[0]);
printf("The address of s[1] is: %p\n", &s[1]);
printf("The address of s[2] is: %p\n", &s[2]);
结果:

s的值为:0x403f00

s的地址是:0x7fff2df9d588

p的值为:0x7fff2df9d588

p的地址是:0x7fff2df9d580

s[0]的地址为:0x403f00

s[1]的地址为:0x403f01


s[2]的地址is:0x403f02

这是错误的。强制转换为void*只是隐藏问题,而不是解决问题。我的第一个想法是,他只是想打印数字以查看编译器分配的值,而强制转换为void将允许他,不管他的声明中存在任何问题。但是,是的,这肯定可以避免问题。强制转换为
void*
对于变量函数中的
%p
格式的参数,语言标准实际上是需要的。这是极少数需要使用C进行强制转换的情况之一。错误会消失,但没有什么会更清楚,因为您的修复避免了对原始问题的解释。@alcuadrado:但s是“a”。您的基本对这一点的误解是根本问题。哎呀,当它发布消息时,我忙着打字。嗨,谢谢你回答这个老问题。幸运的是,在过去的4年里,我学到了很多关于编程的知识。但我认为你的意图是给那些提出这个问题的人一个更好的洞察力。考虑到这一点,我不得不说在用C++编译器编译C代码不是一件好事,它们不是同一种语言,而且混淆了它使错误。haha@alcuadrado哦,没有看到日期,这是史前的!@你在哪里?你能解释一下“方向”在这里是什么意思吗?“s的方向”,我不明白它是什么意思。“指针的“方向”。@zumzum这是OP的约定,它的意思是“地址”,我在回答中已经更正了。谢谢。数组也指特定类型的连续内存地址,因为
s
衰减为指针,我们可以说它是指向
char*
[数组的第一个元素]的指针@CholthiPaulTtiopic-不。首先,这应该是“我们可以说它是指向
char
(不是
char*
)的指针。但是,在某些情况下,您可以将它用作指向
char
的指针,但这并不意味着它是一个。“5.0”可能是一个整数,但它不是
int
char s[] = "asd";
char *p = &s[0];  // alternately you could use the shorthand char*p = s;
char **pp = &p;
char* s = "asd";
char** p = &s;

printf("The value of s is: %p\n", s);
printf("The address of s is: %p\n", &s);

printf("The value of p is: %p\n", p);
printf("The address of p is: %p\n", &p);

printf("The address of s[0] is: %p\n", &s[0]);
printf("The address of s[1] is: %p\n", &s[1]);
printf("The address of s[2] is: %p\n", &s[2]);