C变量和指针

时间:2016-01-16 21:28:22

标签: c pointers

参考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应该成为指针?

修改 多谢你们。我读错了。指针背后没有隐藏的魔力。我的阅读不好......

6 个答案:

答案 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 = 10a的地址将会是某个数字。 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);
}