#include<stdio.h>
void main()
{
int *c=12345;
printf("dec:%d hex:%x", c ,&c); // (1)
}
第(1)行打印
dec:12345 hex:8af123
其中8af123
显然是随机和机器相关的地址。
当我放入
printf("dec:%d", *c); // (1)
显然,它失败了。
所以我的问题是根据理论概念:
*c
应保留值12345
,但事实并非如此。为什么? 在此代码中:
#include<stdio.h>
void main()
{
char *c='a';
printf("address store in c:%d value point by c:%c address of c:%x", c,*c ,&c); //Focus line
}
输出是:
adderess store in c:9105699 value point by c:a address of c:8af564
*c
而不是c
? 我正在使用gcc编译器4.4.3。
答案 0 :(得分:11)
int *c=12345;
你刚刚制作了一个指向(可能)无效地址12345
的指针。
如果您将c
(无*
)传递给printf
,则表示您正在传递指针。因此,printf
只会看到数字12345
,并打印出来。它无法知道那应该是一个指针。
如果您将*c
传递给printf
,则解除引用指针 - 您正在传递内存地址12345
的值。
由于这不是一个有效的地址,因此取消引用操作将在到达printf
之前崩溃(确切地说,将表现为未定义)。
答案 1 :(得分:1)
所以我的问题是根据理论概念
*str
保持值12345
但事实并非如此。为什么?
int *c=12345;
与:
相同int *c;
c=12345;
不与:
相同int *c;
*c=12345;
这里有C语言的语义怪癖。 *
属于声明,但它仅适用于该特定变量。
您可以通过将*
放在数据类型旁边来澄清int* c = 12345; // Don't format your declaration like this,
// see next example as to why
属于声明的事实:
int* a, b, c; // a is a pointer to int, b and c are plain int
// it is the same as:
int *a; int b; int c;
// and **not**
int *a; int *b; int *c;
如果这样做,在同一语句中声明多个变量时会遇到麻烦:
*
所以,你只需要知道*c
属于声明。没有任何问题,因为除非您首先为c
分配了有效地址,否则无法安全地分配 char *c='a';
printf("%d %c %x", c,*c ,&c); //Focus line
。
为什么它在* c中存储'a'而不是c?
a
您正在声明指向内存位置97的char的指针(97
的ascii值为97)。
然后尝试将指针打印为数字(应打印c
,但见下文),内存位置97的值作为字符(c
在此阶段是无效指针,因此结果未定义,指针c
的地址(97
是位于堆栈上的aout变量)。
当我编译这段代码时,我得到了一个
警告:初始化使得整数指针没有强制转换
将c
分配给字符指针{{1}}时。
当我在cygwin中运行此代码时,我从未定义的行为中获得了Segmentation错误。