在C中寻址

时间:2013-12-11 12:40:22

标签: c

#include<stdio.h>
#include<stdlib.h>   
int main(int argc, char *argv[])
{
    int x = 2;
    int *pointer2 = &x;
    int number = &x;
    printf("%x\n",number );
    printf("%x\n",number+1 );
    printf("%x\n",pointer2 );
    printf("%x\n",pointer2+1);

    return EXIT_SUCCESS;
}

我从gcc得到一个警告,“初始化从指针生成整数,没有强制转换[默认情况下启用]”,但是当我编译时,得到以下输出:

5da24540
5da24541
5da24540
5da24544

显然,上面的事情并没有发生,因为我们可以在前两行输出中看到地址只增加1而第二种情况增加4。同时请解释&amp;返回可以分配给其他变量(如int)的地址,或者它是self中的指针,只能指定给指针类型。

5 个答案:

答案 0 :(得分:7)

number是一个int,使用x的地址初始化(从地址“生成int而无需投放” - 警告告诉您,这可能不是你想要什么) - 如果你增加它,它将增加1。

pointer2是指向int的指针(使用x的相同地址初始化),以int大小为增量递增(这种行为称为“指针算术”。

答案 1 :(得分:1)

警告是因为这项任务:

int number = &x;

您正在为int*分配int,这不是您应该做的。 (1)将x的值分配给number,或者(2)将number的类型更改为int*(链接pointer2)并分配地址x

或者(3)如果您确实要将x的地址分配给number,请使用类型转换。

// (1)
int number = x; // Assign value of x.
// (2)
int* number = &x; // Assign address of x.
// (3)
int number = (int)&x; // Assign address of x and cast to int.

你的第二个问题与指针运算有关。

您的number变量是int,这意味着如果您将其递增(+ 1),它实际上会增加1。

你的pointer2变量是int*,这意味着如果你递增它,它会增加int*的大小(32位系统上4个字节,64位上8个字节)系统)。

这样做完了,这样你就可以通过简单地递增指针来迭代指针数组。

编译器发出警告有两个原因:

1)编译器不会隐式处理类型不匹配,因为标准是这样说的。而这反过来是因为从指针类型转换到另一种类型具有罕见的用例。大多数时间这样的作业都是偶然发生的,作者只是搞砸了间接的程度(*的数量。)

2)标准禁止这个的另一个原因是int是4个字节(在大多数实现中),int*可以是4个或8个字节,具体取决于编译的平台。

答案 2 :(得分:0)

编译器不会将数字从int转换为指针。警告说“从指针生成整数”,而不是“从整数生成指针”,因此number仍然是int。它是指针(x的地址)已被“转换”为普通整数。

答案 3 :(得分:0)

您收到警告,因为不能保证int类型可以保存指针值(例如,您在int为16位但指针值为32位的系统上) ;如果你添加一个演员,你告诉编译器你知道你在做什么(即使你不知道):

int number = (int) &x;

这告诉编译器是的,你真的想要取x的地址并将其视为普通整数。请注意,存储到number的值可能会被截断。

也不保证所有指针类型具有相同的大小和表示; IOW,指向int的指针可能与指向char的指针大小不同,指针可能与指向struct的指针大小不同。在大多数现代桌面和服务器架构上,它们是相同的,但仍有一些奇怪的架构在那里它们不是。

至于为什么你在添加中得到不同的结果......

向指针添加1会给出指向类型的下一个对象的地址; IOW,如果你有一个指向int的指针,添加1将为你提供下一个可用int的地址,即当前地址的sizeof (int)字节。如果你有一个指向10个元素int数组的指针,那么加1会得到下一个10个元素数组int的地址,它是当前10 * sizeof (int)个字节地址。

这就是数组索引的工作原理。表达式a[i]被解释为*(a + i);也就是说,计算i之后的a'元素的地址,并取消引用结果。

答案 4 :(得分:-1)

对“数字”赋值进行类型转换并尝试这样,

int x = 2;
int *pointer2 = &x;
int number = (int)&x;

这样可行。