参考https://stackoverflow.com/a/22250138/5783540说:
当你有
时int a = 10;
你做了
&a
原来是:int*
但是为什么指针呢?我知道&a
会给你一个记忆地址,但它不会保留一个地址而只是一个号码10
或者我错了吗?
请阅读:
我知道指针是什么,我知道&
实际上做了什么。我只是困惑于:
To get the address of a, you do: &a (address of a) which returns an int* (pointer to int)
同样,为什么int a
应该成为指针?
修改 多谢你们。我读错了。指针背后没有隐藏的魔力。我的阅读不好......
答案 0 :(得分:1)
&a
字面意思是a
的地址。它是内存中的地址,其中包含整数a
的空格开始。就像您住所的地址一样,您不住在地址中,而是住在该地址所指的空间内。
假设您打印了a
的地址:
printf("%p" &a);
并获取18fec0
此值(内存位置)如下所示:
|18fec0 - Starting point of a (assuming sizeof int is 4 bytes:)|18fec4 - next memory location
|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0...
^ ^
int *a;
是包含指向int的指针的特殊变量。在32位存储器中,sizeof(a)
也将是4个字节。
在64位内存空间中, int 和 int * 的大小不一样:
`int a;`
`sizeof(a) == 4`
`int *a;`
`sizeof(a) == 8`
另外一个例子。考虑:
int a, *pA;//create an int, and a pointer to int
main(void)
{
pA = &a;//setting pointer to address of integer.
... //now, if you were to print each, the value should be the same
printf("%p\n", &a);
printf("%p\n", pA);
return 0;
}
在我的系统上,我得到:
18fec0
18fec0
答案 1 :(得分:1)
指针是存储地址的变量。
例如当int a = 10时;
int *b = &a;
这里b
是一个指针
存储地址,地址10 is stored
。
&a
表示某事的地址。
例如,10存储在地址1234567
中,由于b
,此地址存储在&
中,为什么?
指针也是一个变量,存储在其中的东西(some address
)所以我们可以有另一个指向它的指针(存储它的地址)。
为什么int *:
1 - 因为值存储在内存中,我们应该知道从中读取了多少字节以及如何读取它(int,float,...)。
2 - 当你想增加指针时,它应该知道去哪里(要跳转多少字节)。它无法从int值的中间读取!所以它应该从该值跳转并转到下一个值。
答案 2 :(得分:0)
但是为什么指针呢?我知道& a会给你一个记忆地址但是它 没有地址但10号或我错了?
int *p = &a
- > p
将保留包含10的内存位置的地址,而不是值10本身。
说,a
位于内存地址0x00123456
,因此在该位置(通常)将为a
保留4个字节,并将包含整数值10(假设为32位)为简单起见。)
现在,如果我们使用指针int *p = &a
(int指针p是地址 - a),p
将具有值0x00123456
,其中点到存储a的位置(即值10)。
int **p_ptr = &p;
基本相同。它是指向指向的指针的指针:)
听起来有点奇怪,但它与第一个例子没有什么不同,除了它指向的类型不同(在这种情况下是另一个指针)。
答案 3 :(得分:0)
获取p的地址:
int **pp = &p;
你可以继续:
int ***ppp = &pp;
int ****pppp = &ppp;
...
或者,只有在C ++ 11中,你可以这样做:
auto pp = std::addressof(p);
要在C中打印地址,大多数编译器都支持%p
,因此您只需执行以下操作:
printf("addr: %p", pp);
否则你需要投射它(假设一个32位平台)
printf("addr: 0x%u", (unsigned)pp);
在C ++中你可以这样做:
cout << "addr: " << pp;
答案 4 :(得分:0)
您创建的每个变量都存储在内存中的某个位置。它存储的地方称为它的地址。在地址处,保持变量的值。因此,如果您撰写int a = 10
,a
的地址将会是某个数字。 a的值是你指定的,10。运行此代码以查看我的意思。
#include <stdio.h>
int main() {
int a = 10;
printf("The address of a is: %d\n", &a);
printf("The value of a is: %d\n", a);
return 0;
}
编辑:int a
应该是int*
类型,因为它所持有的数字是地址。 int*
告诉编译器存储的数字在内存中是一个地址,而不仅仅是你声明的一些值。
答案 5 :(得分:0)
前一个答案是正确的,但我认为这无助于解决您的疑虑
在典型的系统中,您可以使用能够保存值的单元格数组来完成内存。每个单元都由CPU在总线上发出所需单元的地址
声明变量时,编译器会在分配给进程的内存块中保留一个区域
从现在开始,CPU可以通过其地址访问该变量。从现在开始,访问变量的唯一方法是使用地址
当您引用变量时,编译器会自动使用该地址来寻址正确的内存位置,然后将该值加载到CPU寄存器以对其进行操作。
但是在很多情况下你需要一个变量的地址而不是它的值
即如果你想修改调用函数中定义的变量:
void bar(int *pointer)
{
*pointer = 1;
}
void foo(void)
{
int a = 0;
bar(&a);
printf("a modified in bar() to %d\n", a);
}
在IT中,保存某种类型的另一个变量的内存地址的变量称为该类型的指针。
为什么指针指针指针....?
例如:
void bar(int **pointer)
{
**pointer = 1;
}
void foo(int **a)
{
bar(a);
printf("a modified in bar() to %d\n", *a);
}
当然有更多有用的用途;-)
以下是一个更现实的例子,我们称之为动态创建数组的函数。
void bar(int **pointer, int nElems)
{
//We got the address of a variable that is a pointer to int
//note that we use a single dereference to access to the
//variable that holds the pointer to int not to the pointed int.
*pointer = malloc(sizeof(int) *nElems) ;
}
void foo(void)
{
int *MyIntArray; //Holds the address where our array starts
bar(&MyIntArray, 10); //Pass the address of our variable so
//bar() can update it with the allocated address
int i;
for(int i=0; i<10; i++)
MyIntArray[i] = i+1;
for(int i=0; i<10; i++)
printf("MyIntArray[%d] = %d\n", i, MyIntArray[i]);
free(MyIntArray);
}