#include <stdio.h>
void main(){
int a = 5;
int* b = &a;
int* c = &b;
printf("%d\n",&a==b);
printf("%d\n",&b==c);
printf("%d\n",a==*b);
printf("%d\n",b==*c);
}
输出是
1
1
1
0
为何最后一个是0?
还有两行忘了加
printf("%d\n",b);
printf("%d\n",*c);
另外 markdown 怎么贴代码
1
Andiry 2015-08-17 05:59:17 +08:00
int **c = &b
|
2
pimin 2015-08-17 08:14:45 +08:00
int* c = &b;
这句可以编译通过么 |
3
zhangchioulin 2015-08-17 08:32:27 +08:00
为什么我不能编译通过
|
4
Fulminit 2015-08-17 08:35:23 +08:00 via Android
b 是指向 a 的指针
b 的值是 a 的指针地址 c 是指向 b 的指针 c 的值是 b 的指针地址 那么 c 解引用之后就是 b 的指针地址,自然和 b 的值不相同。 (好久没写C了有错误请指出,谢谢) |
5
colorsand 2015-08-17 08:41:47 +08:00
c里边的数组指针和指针数组比较难理解
|
6
ljbha007 2015-08-17 09:04:38 +08:00
1楼就给出了正解
c里存的是b的地址所以*取出来的值是b的值 也就是a的地址 b里存的是a的地址 所以*取出来的值是a的值 也就是5 |
7
lizhiqing1996 2015-08-17 09:06:17 +08:00
c是一个整型指针,怎么存进一个指针型指针的?
|
8
nozama 2015-08-17 09:19:35 +08:00 via Android
和平台有关吧,应该64位系统上就会出现这个结果。sizeof(int) != sizeof(int*),于是*c本来应该是一个64位的指针值,但是int只有32位,所以被截断了。
|
9
canautumn 2015-08-17 09:20:58 +08:00
无视warning的话可以编译通过。具体为啥不等你要查C标准是怎么规定的了,不过写这种不规范的代码有啥意义吗?
|
10
xiaocaibaozi 2015-08-17 09:22:08 +08:00
同新路过,不过我这里的GCC碉堡了,即没给我报c类型的错,还给我输出了四个一。
|
11
linux40 2015-08-17 09:45:53 +08:00 via Android
看一楼,别的不用看了。
|
12
DiamondY 2015-08-17 10:15:28 +08:00
用楼主的代码,使用 VC6 编译,有 3 个警告;
用 1 楼的方式替换掉代码后,有 0 个警告; 但我用 VC6 运行得出的结果,却两种方式都是 4 个 1 ……囧 也就是说,单从值上面说,(b==*c )这个判断条件是 true 的; 只不过,楼主把 c 定义成指向 int 的指针,*c 出来的是 int ,而 b 却是指向 int 的指针,两个数值类型不一样 |
13
DiamondY 2015-08-17 10:18:42 +08:00
贴出 VC6 下编译的警告:
int a = 5; int* b = &a; int* c = &b; (warning C4047: 'initializing' : 'int *' differs in levels of indirection from 'int ** ') printf ("%d\n",&a==b ); printf ("%d\n",&b==c ); (warning C4047: '==' : 'int ** ' differs in levels of indirection from 'int *') printf ("%d\n",a==*b ); printf ("%d\n",b==*c ); (warning C4047: '==' : 'int *' differs in levels of indirection from 'int ') |
14
chensonglu 2015-08-17 10:37:28 +08:00
定义的时候得用 int **c = &b ,因为 c 是一个二级指针,否则编译不通过。改完之后你会发现最后结果就是 1 了。
|
15
weyou 2015-08-17 10:46:31 +08:00
楼主的程序肯定有警告,其他同意 @nozama , 楼主应该是在 64bit 系统上运行的程序。 *c 发生了截断,因为 int* 和 int 的 size 在 64bit 系统上是不同的。
|
16
w99wen 2015-08-17 11:04:53 +08:00 3
对于指针的问题。
你可以这么理解。 比如有一个仓库,里面有很多东西。 那么你想要用这个仓库,所以你需要知道这个仓库的地址是什么。 指针就是仓库的地址。因此指针的内存占用是很小的。因为他只是一个地址的标记(貌似是 4B ,好久没弄过 C/C++了)。 而真实的仓库内容可能非常大。可能有 1G 大小。 那么在你说的这个情况中,这个仓库就是那个 int a = 5 ,也就是 5 这个值。 而这个地址就是那个指针 int* b 。 我们都可以用这个仓库的地址去找到仓库。然后对仓库进行改动。 然而怎么通过地址(也就是指针 b )找到仓库的真实内容(也就是 a 实际里面存了什么值)那。就是通过*符号。类似的,也可以用&得到仓库的地址。 在你的代码中: 你先用&a ,把仓库 a (也就是 int 值 5 )的地址给了 b 去存储。那么你*b 得到的自然是仓库 a 的内容。 你又用&b ,把 b 的地址给了 c ,那么*c 地址对应的应该是 b 的内容。也就是 a 仓库的地址。( a 仓库的地址 b 也看做是一个仓库) 所以你要是想从 c ,得到 a 的内容。你应该是**c ,这才是 a 仓库的内容。 应该明白的点: 指针就像是个地址。我们能通过这个地址得到我们想要的东西。得到一个东西的地址的方法是用&,而由一个地址拿到那个东西的方法是用*。 比如一个 int 值 5 ,他在内存中, 5 可以用&得到 5 的地址。我们把 5 的地址存起来,放在指针 b 里面。注意, b 也是在内存中, b 存储的是 5 的地址, b 也是有一个地址的,随意我们还可以用&得到 b 的地址。然后存储到另一个指针 c 里面。 这时候。我们用*c ,得到的是 c 存储的地址对应的内容,也就是 b 指针的内容,也就是 5 这个值的地址。因为*c 是 b 的内容, 5 的地址。所以要再用一次*,也就是**c ,才能得到 5 这个值。 我是不是蛋疼。 |
17
wlee1991 2015-08-17 11:10:02 +08:00
正确写法应该是这样的:
{% codeblock lang:c %} #include <stdio.h> int main (int argc, const char * argv[]) { int a = 5; //a is int int * b = &a; //b is a pointer to int int * * c = &b; //c is a pointer to int * int * * * d = &c; //d is a pointer to int * * printf ("a = %d, &a = %p\n", a, &a ); printf ("b = %p, &b = %p\n", b, &b ); printf ("c = %p, &c = %p\n", c, &c ); printf ("d = %p, &d = %p\n", d, &d ); printf ("*b = %d\n", *b ); printf ("**c = %d\n", **c ); printf ("***d = %d\n", ***d ); printf ("%d\n", &a == b ); printf ("%d\n", &b == c ); printf ("%d\n", &c == d ); printf ("%d\n", a == *b ); printf ("%d\n", b == *c ); printf ("%d\n", c == *d ); return 0; } {% endcodeblock %} |
18
wlee1991 2015-08-17 11:11:48 +08:00
`#include <stdio.h>
` `int main (int argc, const char * argv[]) { ` ` int a = 5; //a is int ` int * b = &a; //b is a pointer to int ` int * * c = &b; //c is a pointer to int * ` int * * * d = &c; //d is a pointer to int * * ` ` printf ("a = %d, &a = %p\n", a, &a ); ` printf ("b = %p, &b = %p\n", b, &b ); ` printf ("c = %p, &c = %p\n", c, &c ); ` printf ("d = %p, &d = %p\n", d, &d ); ` ` printf ("*b = %d\n", *b ); ` printf ("**c = %d\n", **c ); ` printf ("***d = %d\n", ***d ); ` ` printf ("%d\n", &a == b ); ` printf ("%d\n", &b == c ); ` printf ("%d\n", &c == d ); ` ` printf ("%d\n", a == *b ); ` printf ("%d\n", b == *c ); ` printf ("%d\n", c == *d ); ` ` return 0; `} |
20
wlee1991 2015-08-17 11:14:19 +08:00
```c
#include <stdio.h> int main (int argc, const char * argv[]) { int a = 5; //a is int int * b = &a; //b is a pointer to int int * * c = &b; //c is a pointer to int * int * * * d = &c; //d is a pointer to int * * printf ("a = %d, &a = %p\n", a, &a ); printf ("b = %p, &b = %p\n", b, &b ); printf ("c = %p, &c = %p\n", c, &c ); printf ("d = %p, &d = %p\n", d, &d ); printf ("*b = %d\n", *b ); printf ("**c = %d\n", **c ); printf ("***d = %d\n", ***d ); printf ("%d\n", &a == b ); printf ("%d\n", &b == c ); printf ("%d\n", &c == d ); printf ("%d\n", a == *b ); printf ("%d\n", b == *c ); printf ("%d\n", c == *d ); return 0; } ``` |
21
wlee1991 2015-08-17 11:15:51 +08:00
我就不信弄不粗来
` ` ` #include <stdio.h> int main (int argc, const char * argv[]) { int a = 5; //a is int int * b = &a; //b is a pointer to int int * * c = &b; //c is a pointer to int * int * * * d = &c; //d is a pointer to int * * printf ("a = %d, &a = %p\n", a, &a ); printf ("b = %p, &b = %p\n", b, &b ); printf ("c = %p, &c = %p\n", c, &c ); printf ("d = %p, &d = %p\n", d, &d ); printf ("*b = %d\n", *b ); printf ("**c = %d\n", **c ); printf ("***d = %d\n", ***d ); printf ("%d\n", &a == b ); printf ("%d\n", &b == c ); printf ("%d\n", &c == d ); printf ("%d\n", a == *b ); printf ("%d\n", b == *c ); printf ("%d\n", c == *d ); return 0; } ` ` ` |
22
testlc 2015-08-17 11:19:53 +08:00
手动 markdown 好毅力 哈哈
|
24
Banio 2015-08-17 16:18:29 +08:00
In function 'main':
[Warning] initialization from incompatible pointer type [enabled by default] [Warning] comparison of distinct pointer types lacks a cast [enabled by default] [Warning] comparison between pointer and integer [enabled by default] 1 1 1 1 用的 dev cpp 5.1 |
25
oska874 2015-08-17 17:13:57 +08:00
32bit linux,64 bit cygwin,用 gcc 4.8+编译,都是编译有 warning ,但是结果都是 4 个 1 。
别用 vc 6 了,我们搞工控的都是 vs 2013 了。 |