我感兴趣的是,unsigned long long变量是否可以被视为地址,结果似乎是正确的?

int var = 0;
// the variable var's address is 0x7fffffffe4a4 now in my system
unsigned long long ull = 0x7fffffffe4a4;
scanf("%d", ull);  // I try to use ull as var's address and assign a value to var
printf("%d\n", var);  // It seemingly works!

我还做了一个实验,具体如下.

int var = 0;
// the variable var's address is 0x7fffffffe4a4 now in my system
unsigned long long ull = 0x7fffffffe4a4;  
int *ptr = &var;

// First, I want to know whether the memory used by unsigned long long and the one used by a pointer differ
printf("%zu\n", sizeof(ull));  
printf("%zu\n", sizeof(ptr));
// The results are both "8" in my system
// Next I try to assign two different values to var by two ways
scanf("%d", ull);  // I try to use x as an address to assign var
printf("%d\n", var);
scanf("%d", ptr);  // And I also use a normal pointer to assign var
printf("%d\n", var);
// The results were in line with expectations!

看起来unsigned long long变量可以成功地用作指针(尽管编译器警告我参数应该是int*而不是unsigned long long),我想知道…

在硬件级别上,变量和指针有什么不同?这两种类型的对象在存储和使用时是如何处理的?由谁处理这些对象?是否建议执行上述操作?

(归根结底,这是c的一个特性吗?)

推荐答案

在许多(大多数)平台上,指针和(无符号)整数在硬件级别以非常相似的格式存储(在您的系统上,int*指针和unsigned long long都是8字节).然而,从C语言和编译器的Angular 来看,它们是非常不同类型的变量.

他们行为上的一个显著区别是算术.对于整型,像x = x + 1这样的算术运算完全符合您的自然期望.然而,对于指针,这样的操作是以指向类型大小的基本单位执行的.

下面的代码演示了这一点(在具有8字节指针、long long和4字节int的平台上):

#include <stdio.h>

int main()
{
    int myInt = 42;
    int* ptr = &myInt;
    unsigned long long ull = (unsigned long long)ptr;
    printf("%p %016llX\n", (void*)ptr, ull);
    ++ptr;
    ++ull;
    printf("%p %016llX\n", (void*)ptr, ull);
    return 0;
}

输出为:

0000005B8A4FFC10 0000005B8A4FFC10
0000005B8A4FFC14 0000005B8A4FFC11

对于第一行(正如您已经注意到的),两个值是相同的,它们的二进制表示也将是相同的(在这个平台上).但是,请注意,++的增量在这两种类型上的行为不同,因此输出的第二行显示指针增加了4(int的大小),但未签名的整数增加了1.

C++相关问答推荐

想了解 struct 指针和空指针转换

为什么PLT表中没有push指令?

C如何显示字符串数组中的第一个字母

sizeof结果是否依赖于字符串的声明?

通过管道将一个子系统的标准输出发送到另一个子系统的标准输出

由Go调用E.C.引起的内存快速增长

空指针的运行时强制转换

将常量转换为指针会增加.数据大小增加1000字节

为什么此共享库没有预期的依赖项?

如何在C中只对字符串(包含数字、单词等)中的数字进行重复操作?

为什么我从CSV文件中进行排序和搜索的代码没有显示数据的所有结果?

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

为 struct 中的数组动态分配内存时出错

无法访问共享目标文件内的共享指针

如何在双向表中实现线程安全,每个条目仅使用4位,同时避免任何全局锁?

OSDev--双缓冲重启系统

C:面筋蛋白';为什么不刷新窗口?

Matlab/Octave对conv2函数使用哪种方法?

关于不同C编译器中的__attribute__支持

当循环变量在溢出时未定义时,可以进行哪些优化?