繁体   English   中英

C中的内存寻址和指针

Memory addressing and pointers in C

提示:本站收集StackOverFlow近2千万问答,支持中英文搜索,鼠标放在语句上弹窗显示对应的参考中文或英文, 本站还提供   中文繁体   英文版本   中英对照 版本,有任何建议请联系yoyou2525@163.com。

这取自C,并基于此。 假设我们有一个32位指针

char* charPointer;

它指向内存中包含某些数据的某个位置。 它知道此指针的增量以1字节为单位,以此类推。另一方面,

int* intPointer;

也指向内存中的某个位置,如果我们增加它,它知道如果我们加1,它应该增加4个字节。

问题是,如果这些指针显然包含一些信息,可以使它们彼此分开,例如char*char* ,那么我们如何能够使用这些指针来寻址全部32位可寻址空间(2 ^ 32)-4 GB。 int* ,所以这不给我们留下32个字节,而是更少。

当我输入这个问题时,我想到了,也许都是语法糖,真的适合编译器吗? 也许原始指针仅为32位,并且与类型无关? 是这样吗

6 个回复

您可能会对编译时间与运行时间感到困惑。

在编译过程中, gcc (或任何C编译器)知道指针的类型,尤其是知道该指针变量指向的数据的类型。 因此, gcc可以发出正确的机器代码。 因此,将int *变量的增量(在具有32位int的32位计算机上)转换为4(字节)的增量,而将char*变量的增量转换为1的增量。

在运行时,编译的可执行文件(它不在乎或不需要gcc )仅处理机器指针,通常是字节地址(或某个字的开头)。

类型(在C程序中)在运行时未知。

其他一些语言(Lisp,Python,Javascript等)要求在运行时知道这些类型。 在最近的C ++(但不是C)中,某些对象(具有虚拟功能的对象)可能具有RTTI

它确实是语法糖。 考虑以下代码片段:

int t[2];
int a = t[1];

第二行等效于:

int a = *(t + 1); // pointer addition

它本身等效于:

int a = *(int*)((char*)t + 1 * sizeof(int)); // integer addition

编译器检查类型之后,它将放弃强制类型转换,仅适用于地址,长度和整数加法。

是。 原始指针是32位数据(或16位或64位,具体取决于体系结构),并且不包含其他任何内容。 无论是int *char *struct sockaddr_in *都只是编译器的信息,它知道递增时实际要添加的数字,以及取消引用时要具有的类型。

您的假设是正确的:要查看如何处理不同类型的指针,请尝试运行以下程序:

int main()
{
    char * pc = 0;
    int * pi = 0;

    printf("%p\n", pc + 1);
    printf("%p\n", pi + 1);

    return 0;
}

您会注意到,向char *添加1将其数值增加1,而对int *进行相同的增加4(这是我机器上int的大小)。

就像您最后所说的那样-C语言中的类型只是一个编译时概念,它告诉编译器如何为可以对变量执行的各种操作生成代码。

最后,指针仅归结为它们指向的地址,一旦编译代码,语义信息就不再存在。

递增int *指针与递增char *的不同之处仅在于,将指针变量声明为int *。 您可以将int *转换为char *,然后它将以1个字节递增。

所以,是的,它们全都是语法糖。 它使某些类型的数组处理更加容易,并使void *用户感到困惑。

1 学习C - 指针和内存寻址

我正在学习C编程,我有一个关于指针的简单问题...... 我使用以下代码来玩指针: 当我打印C的值时,我返回0.但是,当我打印&c(即printf(“&x \\ n”,&c)时,我在内存中得到一个地址... 打印指针时,我不应该在内存中获取地址(即printf(“%x \\ ...

2 内存寻址和指针

每当指针变量加1时,它将指向下一个整数的位置(在这种情况下前面四个字节)作为跨越四个字节的int变量数据。 如何访问每个字节地址并打印存储在其中的值? ...

3 目标C中的地址和指针

所以这就是问题所在。 我有一个方法(或在obj-C中称为消息),我正在传递一个指向对象的指针。 在该方法内部,我将更改该指针指向的对象,并释放旧对象。 我希望实例变量(正在传递到方法中)现在引用分配给它的新值。 在C#这样的语言中,基本上让变量像OUT参数一样工作 所以我 ...

4 使用C变量的内存寻址

如果运行,此程序将输出地址,它们之间的差值为20字节。 由于long和long *数据类型都只分配8字节的信息,为什么它们之间没有8字节的差异? 其他12个字节又去哪里了? ...

5 寻址指针C / C ++的不同方法

我对使用c样式指针访问特定地址有些困惑。 我有32位芯片,正在尝试编程。 我需要在ram中翻转一些东西。 以下解决方案工作正常。 但是,我有点困惑。 我尝试编写一些我认为等效但无法正常工作的子例程。 这种以下方法只能起作用。 下面的方法根本不起作用。 我一直 ...

6 c中的嵌套结构,寻址指针的问题

我有一个编程练习,我必须在其中制作两个结构: Star和Cluster 。 Star必须接受四个参数 - 姓名、第一个数字、第二个数字、第三个数字。 Cluster包含在文件stars.dat中的n - 颗星以及有关该星来自的文件名的信息。 然后编写一个加载函数,它将文件作为参数并返回一个指向从 ...

7 在MPI_Gather C中寻址内存

我正在尝试将数据传递给MPI_Gather 。 我分配内存如下: 然后使用MPI_Gather()获取所有进程以将数据发送到第1级,如下所示: } 我收到错误消息,提示我没有适当分配内存。 ...

8 用于不同存储器寻址方案的C代码的可移植性

如果我理解正确, 0x10c的DCPU-16规范描述了一个16位地址空间,其中每个偏移地址都是一个16位字,而不是大多数其他存储器架构中的字节。 这有一些奇怪的后果,例如我想sizeof(char)和sizeof(short)都会返回1 。 在这种不同的内存寻址方案之间保持C代码可移植是 ...

2012-04-11 14:39:14 4 518   c/ dcpu-16
9 C ++多重继承内存寻址问题

假设它们正确完成,请忽略#include部分。 这也可能是特定于实现的(但是vtable的概念也是如此)但我很好奇,因为它增强了我对多重继承的可视化。 (我顺便使用MinGW 4.4.0) 初始代码: 这是编译的,并生成对象代码。 在我使用的其他一些编译单元中(在包含上述 ...

10 内存寻址

我正在阅读http://duartes.org/gustavo/blog/post/motherboard-chipsets-memory-map ,具体如下: 在主板上,CPU通往世界的门户是将其连接到北桥的前端总线。 每当CPU需要读取或写入存储器时,它都通过该总线进行读取或写入 ...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2021 STACKOOM.COM