C 是否总是必须使用指针来处理地址?
Does C always have to use pointers to handle addresses?
据我了解,C 必须处理地址的所有情况都涉及指针的使用。例如, & 操作数创建一个指向程序的指针,而不是仅仅将裸地址作为数据给出(即它永远不会在不首先使用指针的情况下给出地址):
scanf("%d", &foo)
或者当使用 & 操作数时
int i; //a variable
int *p; //a variable that store adress
p = &i; //The & operator returns a pointer to its operand, and equals p to that pointer.
我的问题是:C 程序总是必须使用指针来管理地址,这是有原因的吗?是否存在 C 可以单独或使用其他方法处理裸地址(地址的数值)的情况?或者那是完全不可能的? (由于系统架构,内存分配在每个 运行 时间期间和期间发生变化等)。最后,地址因内存管理而改变是否有用?如果是这样的话,这就是为什么总是需要指针的原因。
我想弄清楚在 C 标准化语言中是否必须使用指针。不是因为我想使用其他东西,而是因为我想确定使用地址的唯一方法是使用指针,而忘记其他一切。
编辑:由于部分问题已在 Eric Postpischil、Michał Marszałek、user3386109、Mike Holt 和 Gecko 的评论中得到解答;我将在此处对这些位进行分组:是的,由于不同的因素,使用裸地址几乎没有用处(指针允许许多操作,每次程序 运行 时地址可能会更改,等等)。正如 Michał Marszałek 指出的(无双关语意),scanf() 使用指针,因为 C 只能处理副本,因此需要指针来更改所使用的变量。即
int foo;
scanf("%d", foo) //Does nothing, since value can't be changed
scanf("%d", &foo) //Now foo can be changed, since we use it's address.
最后,正如 Gecko 提到的,指针是用来表示间接的,这样编译器就可以区分数据和地址。
John Bode 在其回答中涵盖了大部分主题,所以我会标记那个。
int i; //a variable
int *p; //a variable that store adres
i = 10; //now i is set to 10
p = &i; //now p is set to i address
*p = 20; //we set to 20 the given address
int tab[10]; // a table
p = tab; //set address
p++; //operate on address and move it to next element tab[1]
我们可以通过指针向前或向后移动来对地址进行操作。我们可以设置和读取给定地址。
在 C 中,如果我们想从函数中获取 return 值,我们必须使用指针。或者使用函数中的 return 值,但那样我们只能得到一个值。
在 C 中我们没有引用,因此我们必须使用指针。
void fun(int j){
j = 10;
}
void fun2(int *j){
*j = 10;
}
int i;
i = 5; // now I is set to 5
fun(i);
//printf i will print 5
fun2(&i);
//printf I will print 10
C 允许您将指针转换为整数。 <stdint.h>
header 提供了一个 uintptr_t
类型,其中 属性 任何指向 void
的指针都可以转换为 uintptr_t
并返回,结果将比较等于原始指针。
Per C 2018 6.3.2.3 6,将指针转换为整数的结果是implementation-defined。 Non-normative 注释 69 说“将指针转换为整数或将整数转换为指针的映射函数旨在与执行环境的寻址结构保持一致。”
因此,在地址是简单编号方案的机器上,将指针转换为 uintptr_t
应该 给你自然机器地址,即使标准不需要它。但是,在某些环境中,地址更复杂,将指针转换为整数的结果可能并不简单。
一个指针是一个地址(或者更准确地说,它是地址的抽象)。指针是我们在 C 中处理地址值的方式。
在一些域之外,“裸地址”值本身没有用处。我们对地址的兴趣不如该地址处的对象。 C要求我们在两种情况下使用指针:
- 当我们希望函数写入参数时
- 当我们需要跟踪动态分配的内存时
在这些情况下,我们并不真正关心地址值实际是什么;我们只需要它来访问我们感兴趣的对象。
是的,在嵌入式世界中,特定地址值是有意义的。但是您仍然使用指针来访问这些位置。就像我上面说的,指针 是 我们的目的地址。
据我了解,C 必须处理地址的所有情况都涉及指针的使用。例如, & 操作数创建一个指向程序的指针,而不是仅仅将裸地址作为数据给出(即它永远不会在不首先使用指针的情况下给出地址):
scanf("%d", &foo)
或者当使用 & 操作数时
int i; //a variable
int *p; //a variable that store adress
p = &i; //The & operator returns a pointer to its operand, and equals p to that pointer.
我的问题是:C 程序总是必须使用指针来管理地址,这是有原因的吗?是否存在 C 可以单独或使用其他方法处理裸地址(地址的数值)的情况?或者那是完全不可能的? (由于系统架构,内存分配在每个 运行 时间期间和期间发生变化等)。最后,地址因内存管理而改变是否有用?如果是这样的话,这就是为什么总是需要指针的原因。
我想弄清楚在 C 标准化语言中是否必须使用指针。不是因为我想使用其他东西,而是因为我想确定使用地址的唯一方法是使用指针,而忘记其他一切。
编辑:由于部分问题已在 Eric Postpischil、Michał Marszałek、user3386109、Mike Holt 和 Gecko 的评论中得到解答;我将在此处对这些位进行分组:是的,由于不同的因素,使用裸地址几乎没有用处(指针允许许多操作,每次程序 运行 时地址可能会更改,等等)。正如 Michał Marszałek 指出的(无双关语意),scanf() 使用指针,因为 C 只能处理副本,因此需要指针来更改所使用的变量。即
int foo;
scanf("%d", foo) //Does nothing, since value can't be changed
scanf("%d", &foo) //Now foo can be changed, since we use it's address.
最后,正如 Gecko 提到的,指针是用来表示间接的,这样编译器就可以区分数据和地址。
John Bode 在其回答中涵盖了大部分主题,所以我会标记那个。
int i; //a variable
int *p; //a variable that store adres
i = 10; //now i is set to 10
p = &i; //now p is set to i address
*p = 20; //we set to 20 the given address
int tab[10]; // a table
p = tab; //set address
p++; //operate on address and move it to next element tab[1]
我们可以通过指针向前或向后移动来对地址进行操作。我们可以设置和读取给定地址。
在 C 中,如果我们想从函数中获取 return 值,我们必须使用指针。或者使用函数中的 return 值,但那样我们只能得到一个值。
在 C 中我们没有引用,因此我们必须使用指针。
void fun(int j){
j = 10;
}
void fun2(int *j){
*j = 10;
}
int i;
i = 5; // now I is set to 5
fun(i);
//printf i will print 5
fun2(&i);
//printf I will print 10
C 允许您将指针转换为整数。 <stdint.h>
header 提供了一个 uintptr_t
类型,其中 属性 任何指向 void
的指针都可以转换为 uintptr_t
并返回,结果将比较等于原始指针。
Per C 2018 6.3.2.3 6,将指针转换为整数的结果是implementation-defined。 Non-normative 注释 69 说“将指针转换为整数或将整数转换为指针的映射函数旨在与执行环境的寻址结构保持一致。”
因此,在地址是简单编号方案的机器上,将指针转换为 uintptr_t
应该 给你自然机器地址,即使标准不需要它。但是,在某些环境中,地址更复杂,将指针转换为整数的结果可能并不简单。
一个指针是一个地址(或者更准确地说,它是地址的抽象)。指针是我们在 C 中处理地址值的方式。
在一些域之外,“裸地址”值本身没有用处。我们对地址的兴趣不如该地址处的对象。 C要求我们在两种情况下使用指针:
- 当我们希望函数写入参数时
- 当我们需要跟踪动态分配的内存时
在这些情况下,我们并不真正关心地址值实际是什么;我们只需要它来访问我们感兴趣的对象。
是的,在嵌入式世界中,特定地址值是有意义的。但是您仍然使用指针来访问这些位置。就像我上面说的,指针 是 我们的目的地址。