C中常用于初始化指针的语法是
int *p = &x;
其中p
是我们的指针,x
是先前声明的变量。遗憾的是,我不理解这种语法:*p
不等于&x
,而是等于x
。那么为什么不是正确的语法
int *p = x;?
在处理指针时,编译器是否只是对常规变量赋值规则进行了异常处理?
答案 0 :(得分:3)
以这种方式阅读
int* p = &x;
即int *是一个类型 - 指向int的指针;
答案 1 :(得分:2)
*
字符具有不同的含义,具体取决于您找到它的位置。我能想到三个含义:
int *x;
在这里,我们正在编写一个变量声明。我们正在创建一个名为x
的变量,其类型为int *
。
int *x = malloc(sizeof(int));
int y = *x;
这里我们使用相同的标记,但请注意它现在在表达式中! (等号的右侧是表达式)。这意味着取消引用。
int *x = malloc(sizeof(int));
int y = *x * *x;
这里我们使用相同的字符进行乘法!
编译器能够使用*
字符周围的上下文来确定我们所处的这三种情况中的哪一种。我们应该有不同的字符来表示这三种情况,但这不是语言,这当然是有争议的。我们有。
答案 2 :(得分:2)
C声明语法无疑令人困惑。 一般遵循"声明遵循使用"的规则,但这不是一个硬性规则。
类型名称int*
表示"指向int
"的指针,但是要定义类型为&#34的对象p
;指向{{1}的指针}",我们不是简单地写出该类型名称,后跟对象的名称:
int
相反,我们写道:
int* p;
表示int *p;
的类型为*p
;由此得出int
必须是p
类型。
您可能已经注意到除了间距之外两个声明都是相同的 - 并且编译器并不关心间距。事实上,有些程序员喜欢写int*
,尽管它并没有严格遵循语法,因为在这种情况下它更清楚。
如果要在单个声明中定义多个对象,区别就变得很重要了:
int* p;
表示int *p, *q;
和*p
都属于*q
类型。和
int
表示int *x, y;
和*x
属于y
类型 - 这意味着int
是x
而int*
是{ {1}}。喜欢将y
放在int
旁边的程序员需要将其分成两行(这无论如何都是个好主意)。
因此,对于对象声明,额外的说明符与定义的名称相关联,而不是与类型相关联。但是初始化程序适用于新创建的对象。所以这个:
*
表示int
的类型为int *p;
,但是:
*p
表示int
本身已使用值int *p = &x;
初始化。
我不会试图证明这是C&C的声明语法应该定义的方式。它有自己的一致逻辑,但它引起了很多混乱。但事实就是如此。
答案 3 :(得分:1)
回到你的宣言。
int *p = &x;
让我们走上半场。 " int * p"告诉编译器变量' p'在内存中有一个位置作为值,它应该被解释为' int'。下半部分'& x',意味着让我获得变量x的内存位置。因此,您可以将变量x'的位置保存在内存中。到代表内存中位置的变量。'
真实世界的比喻是,如果你在街道上有房子,每个房子都有一个地址(其中一个房子将是' x'在你的例子中),你还有一张明信片,&# 39; p,'你可以写一个房子的地址。你不能把房子x放在明信片上。您只能在明信片上放置房子的地址& x。
答案 4 :(得分:0)
int *p = &x;
在声明中以*
作为前缀时,标识符被定义为指向给定类型的指针。例如,p
是指向x
的指针;读它是这样的:
int
p
的指针
p
,指定以下值:the address of x
如果我们想使用p
获取x
的值,我们会执行所谓的解除引用:*p
例如:
int x = 35;
int *p = &x;
printf("x = %d\n", *p); // Prints x = 35
printf("%p\n", p); // Prints the address of x (which is the same as the value of p)
printf("%p\n", &p); // Prints the address of the variable p
答案 5 :(得分:0)
int x = 5; //声明一个整数'x'并用值5初始化它。
int * p1 =& x; //声明指针'p1'&用地址“x”初始化它。
printf(“x =%d \ n”,* p1); //取消引用指针'p1'以获取'x'的值。
int * p2 = NULL; //声明指向int的指针。将其初始化为NULL。
p2 =& x; //将'x'的地址分配给指针'p2'。
printf(“x =%d \ n”,* p2); //取消引用指针'p2'以获取'x'的值。