C 使用间接运算符获取值

C 使用间接运算符获取值,c,arrays,pointers,C,Arrays,Pointers,如果值存储在一个地址中,那么这个声明做什么 int a = 10; 它将值存储在a或&a的地址中。如果它将值存储在a的地址中,那么为什么我们不能像这样使用间接寻址来处理这个变量: printf("%d", *a); printf("%d", *b); // print 4 int a = 4; 如果不是,那么我们如何说每个值都有一个唯一的地址,并且我们可以使用间接运算符访问它们 < > >编辑:如果我认为间接指向只在指针上使用,则考虑如下: int b[10]; b[0] = 4;

如果值存储在一个地址中,那么这个声明做什么

int a = 10;
它将值存储在a或&a的地址中。如果它将值存储在a的地址中,那么为什么我们不能像这样使用间接寻址来处理这个变量:

printf("%d", *a);
printf("%d", *b);  // print 4
int a = 4;
如果不是,那么我们如何说每个值都有一个唯一的地址,并且我们可以使用间接运算符访问它们

< > >编辑:如果我认为间接指向只在指针上使用,则考虑如下:

int b[10];
b[0] = 4;  // Give it some value
现在我们知道b[0]是一个标量,可以在需要标量值的任何地方使用。但在这种情况下,我们可以像这样使用间接方式:

printf("%d", *a);
printf("%d", *b);  // print 4
int a = 4;
我们可以在这个标量变量上使用指针,但不能在没有数组的变量declare上使用指针,这一点并不有趣

在我看来,编译器会自动为变量declare生成一个间接寻址,如下所示:

printf("%d", *a);
printf("%d", *b);  // print 4
int a = 4;
因此,间接寻址是不可能的,因为我们在它上面放置了另一个间接寻址,它是不合法的,除非变量声明如下:

int a = 4; 
int *b = &a; 
int **c = &b;

编辑2:你可以用
scanf(“%d”和&a)
作为证据,证明将值存储在a的地址而不是a中。

直到某一点你是对的:
a
存储一个
int
并住在
&a
地址

但间接寻址只能用于指针。所以你可以做这两件事中的任何一件

int a = 10;
int *p = &a;
printf("%d", a);
printf("%d", *(&a));
printf("%d", *p);

当变量的类型为
int
(而不是
int*
)时,编译器知道它需要为您执行间接寻址,您不应该试图让它执行。也就是说,当你有
inta=10
,编译器将值存储在一个内存位置,该位置由
&a
(忽略寄存器)表示,并且它知道当您写入
printf时(“%d\n”,a)
需要自动获取存储在
&a
中的值,而无需考虑告诉它取消引用某些内容


当变量类型为
int*
(例如
int*p
)时,有两种方法可以读取值:

  • 获取保存在
    p
  • 获取存储在
    p
这是两种不同的操作,因此需要两种符号:

int  a = 10;
int *p = &a;
int *q = p;
int  r = *p;

当然,
p
也有自己的地址。

这里的问题不是很清楚,所以我只解释一下情况

每个(全局)变量都位于内存中的某个位置。当它被赋值时,该值将在内存中变量的位置上显示

如果在C语言中使用变量,那么实际上使用存储在变量位置的值

一种方法是,如果
&
获取一个对象的地址,并且
*
取消引用(跟随)一个指针,那么
*&a
与简单地
a

相同

int a = 10;
编译器分配足够大的内存来容纳
int
。必须对该位置进行标识(该位置位于该特定位置,即地址)并贴上标签(该位置称为
a
),然后在该位置存储数据。标签使您更容易访问。如果语言的设计方式使您只能通过指针访问位置(即取消引用以获取值),那么将很困难

你可以这样说,你生活在一块可以精确定位纬度和经度的土地上。但最好为那个位置、我的房子等保留一个名字,而不是每次都提到纬度/经度。name和longi/lati都指同一事物

a
是标签
&a
更像longi/lati


编辑:关于
intb[10]
。数组名称不是简单的标签。它们还充当指针,因此您可以使用
*
取消对它们的引用。首先,您不能对任何没有指针类型的对象使用间接运算符

记住,C中的声明是基于表达式的类型,而不是对象的类型;宣言

int a = 10;
int *p = &a;
表示表达式
a
的类型为
int
,并将计算为
10
(至少在有人为其指定不同的值之前)。所以当你写作的时候

printf("%d\n", a);
编译器知道如何检索绑定到表达式
a
的内存位置中存储的值。将此视为直接访问

现在考虑声明

int a = 10;
int *p = &a;
此声明表示表达式
*p
具有类型
int
,并将计算为当前指向的
p
的值(在这种情况下,
*p
将计算为
10
,因为
p
是用
a
的地址初始化的);间接运算符是声明的一部分(并绑定到声明符
*p
,而不是类型说明符
int
)。变量
p
是指向整数的指针,它存储另一个整数变量的地址(在本例中,变量
a
的地址)。因此,如果我们想要访问整数值,我们必须取消引用
p

printf("%d\n", *p);

这是对值
10
的间接访问;我们不是通过变量
a
访问它,而是通过指向
a
p
访问它

间接运算符的操作数必须是指向类型的指针。数组名称的特殊之处在于它们的行为类似于指针。它不一定将值存储在a或a的地址中
a
可以存储在寄存器中,或者在某些情况下可以完全优化
a
不是地址,它是编译器可能使用内存位置实现的
int
变量。@Caleb:是的,我知道
a
不是地址,但我所说的是它存储了