#include <stdio.h> int main(void) { int a = 3; int* p; //p = &a; *p = a; printf("%d", *p); return 0; }
错误代码:分段错误(核心转储)我知道指针输出操作数的值。为什么p = &a;和*p = a不同?Q2.当声明int* p = &a;时,是否为p = &a,而不是*p = &a?
p = &a;
*p = a
int* p = &a;
p = &a
*p = &a
bprjcwpo1#
我知道指针输出操作数的值。那么p = &a;不也是*p = a;吗?指针不“输出”任何东西。它们存储地址。至于区别,这:
*p = a;
获取a的 * 地址 * 并将其分配给p,而下面的代码:
a
p
获取a的 * 值 *,并将其分配给p * 指向的 *。在上面,解引用操作符*基本上意味着“获取这个指针指向的任何东西”。这也意味着,如果p没有设置为指向任何位置,则会由于取消引用未初始化的指针而触发undefined behavior。在这种特殊情况下,您的代码会崩溃(可能是由于试图访问无效的内存地址),但不能保证会发生这种情况。当声明int* p = &a;时,是否为p = &a,而不是*p = &a?上面声明p的类型为int *,并将其初始化为a的地址。在这种情况下,* * 不是 * 解引用操作符,而是p类型声明的一部分。
*
int *
ryevplcw2#
为什么p = &a;和*p = a不同?p = &a将a的 * 地址 * 存储到p中。*p = a将a的 * 值 * 存储到p * 指向的对象 * 中。写入p = &a后,以下条件为真:
p == &a; // int * == int * *p == a; // int == int
和声明
*p = 5;
完全等同于
a = 5;
*p
在你的代码中,这一行
给了你一个segfault,因为p还没有被指定为指向一个可写的位置。除非显式初始化,否则局部变量1的内容是 * 不确定的 * -它可以是任何内容。当声明了int* p = &a;时,是p = &a,而不是*p = &a?在声明中,*仅用于指示类型;它不会取消引用p,就像int a[N];索引到a或void f(void)调用f一样。因此,声明使用表达式&a(类型为int *)的结果初始化p。C中的声明由两个主要部分组成-一个 * 声明说明符 * 的序列,后面是一个逗号分隔的 * 声明符 * 列表。声明说明符包括类型说明符(int、char、float)、类型限定符(const、volatile)、存储类说明符(auto、static、register)等。声明符包含被声明的事物的名称,沿着关于该事物的数组性、函数性和/或指针性的信息。在宣言中
int a[N];
void f(void)
f
&a
int
char
float
const
volatile
auto
static
register
unsigned long a[N], *p, f(void);
声明说明符是unsigned long,声明符是a[N]、*p和f(void)。a、p和f的类型由声明说明符和声明符的 * 组合 * 指定,因此a的类型是“unsigned long的N元素数组”,p的类型是“指向unsigned long的指针”,f的类型为“不带参数返回unsigned long的函数”。请记住,在声明中,*操作符始终绑定到声明符,而不是类型说明符。宣言
unsigned long
a[N]
f(void)
T* p; // for any type T
始终解析为
T (*p);
这意味着如果你写一个声明
T* p, q;
只有p将被声明为指针; q将被声明为常规的T。如果两者都需要声明为指针,则可以这样写
q
T
T *p, *q;
1.严格地说,我们指的是存储时间为auto的东西;在没有static关键字的块中声明。
2条答案
按热度按时间bprjcwpo1#
我知道指针输出操作数的值。那么
p = &a;
不也是*p = a;
吗?指针不“输出”任何东西。它们存储地址。至于区别,这:
获取
a
的 * 地址 * 并将其分配给p
,而下面的代码:获取
a
的 * 值 *,并将其分配给p
* 指向的 *。在上面,解引用操作符*
基本上意味着“获取这个指针指向的任何东西”。这也意味着,如果
p
没有设置为指向任何位置,则会由于取消引用未初始化的指针而触发undefined behavior。在这种特殊情况下,您的代码会崩溃(可能是由于试图访问无效的内存地址),但不能保证会发生这种情况。当声明
int* p = &a;
时,是否为p = &a
,而不是*p = &a
?上面声明
p
的类型为int *
,并将其初始化为a
的地址。在这种情况下,*
* 不是 * 解引用操作符,而是p
类型声明的一部分。ryevplcw2#
为什么
p = &a;
和*p = a
不同?p = &a
将a
的 * 地址 * 存储到p
中。*p = a
将a
的 * 值 * 存储到p
* 指向的对象 * 中。写入
p = &a
后,以下条件为真:和声明
完全等同于
*p
基本上充当变量a
的别名。在你的代码中,这一行
给了你一个segfault,因为
p
还没有被指定为指向一个可写的位置。除非显式初始化,否则局部变量1的内容是 * 不确定的 * -它可以是任何内容。当声明了
int* p = &a;
时,是p = &a
,而不是*p = &a
?在声明中,
*
仅用于指示类型;它不会取消引用p
,就像int a[N];
索引到a
或void f(void)
调用f
一样。因此,声明使用表达式&a
(类型为int *
)的结果初始化p
。C中的声明由两个主要部分组成-一个 * 声明说明符 * 的序列,后面是一个逗号分隔的 * 声明符 * 列表。
声明说明符包括类型说明符(
int
、char
、float
)、类型限定符(const
、volatile
)、存储类说明符(auto
、static
、register
)等。声明符包含被声明的事物的名称,沿着关于该事物的数组性、函数性和/或指针性的信息。在宣言中
声明说明符是
unsigned long
,声明符是a[N]
、*p
和f(void)
。a
、p
和f
的类型由声明说明符和声明符的 * 组合 * 指定,因此a
的类型是“unsigned long
的N元素数组”,p
的类型是“指向unsigned long
的指针”,f
的类型为“不带参数返回unsigned long
的函数”。请记住,在声明中,
*
操作符始终绑定到声明符,而不是类型说明符。宣言始终解析为
这意味着如果你写一个声明
只有
p
将被声明为指针;q
将被声明为常规的T
。如果两者都需要声明为指针,则可以这样写1.严格地说,我们指的是存储时间为
auto
的东西;在没有static
关键字的块中声明。