这种使用间接寻址的方式是否正确?

时间:2015-06-12 16:21:22

标签: c pointers

我正在观看关于直接和间接参考的大学讲座。

教授刚才说你可以通过*和前面的地址来访问一个确定的地址。在示例中,他给printf("%d", *7);将打印内存地址7中的值。这不是真的,至少它对我来说根本不起作用。

例如,我在地址num0x28cc48处有一个变量2673736。当我执行*b = &num时,我可以使用printf("%d", *b);访问变量的值,但如果我尝试printf("%d", *2673736);printf("%d", *0x28cc48);则无效。

这是讲座,对于那些想要查看它的人:https://youtu.be/Rxvv9krECNw?t=8m45s

我不知道,我认为他的解释被打破了,但可能是我忽略了这一点,所以我愿意从更有经验的人那里了解更多。

3 个答案:

答案 0 :(得分:0)

如果要访问固定地址的存储器(例如,在访问微控制器上的寄存器时常见),请使用如下表达式:

int tmp = *((int*)0x01234567);

答案 1 :(得分:0)

当您在代码中使用*7时,编译器并不知道您要尝试取消引用的内容。另一方面,如果你告诉它*(int*)7,它知道它必须将它作为int去引用。

通常,内存中的位置7甚至无法访问,将地址硬编码到代码中是不好的做法。但是,对于微控制器或嵌入式系统,可能会使用它。

当您说*b = &num时,无论您是在宣誓时间还是之后都这样做,因为int *b = #int *b; *b = #非常不同。实际上,第一种用法与int *b; b = #相同。

这里有一些代码来澄清你可能想要的场景:

#include <stdio.h>
int main() {
    int num = 5;
    int *a = &num;
    int *b; b = &num;
    printf("num = %d, &num = 0x%x", num, &num);
    printf("a = 0x%x, *a = %d", a, *a);
    printf("b = 0x%x, *b = %d", b, *b);
    printf("*0xAAAAAAAA = %d", *(int*)0xAAAAAAAA); // Note: Replace 0xAAAAAAAA with whatever value you get for num from previous executions of this program
}
PS:看看斯坦福在指针和记忆方面的优秀资源可能是值得的。 http://cslibrary.stanford.edu/102/PointersAndMemory.pdf

答案 2 :(得分:0)

由于常数不具有类型,为了使用常数作为地址,您必须使用强制转换告诉编译器地址的类型。

因此,如果在具有某些类型的常量的低内存中有特定的内存地址,则需要使用强制转换指定内存地址,以便编译器知道该内存位置的数据类型。

例如,您可能有一组无符号短路,这些短路是从内存位置8开始的计数器,设备名称从0x700开始,因此您可以像这样访问它们:

unsigned short iVal = *((unsigned short *) 8);  // get unsigned short value at address 8
unsigned short jVal = *((unsigned short *) 10);  // get unsigned short value at address 10
char  *iName = (char *) 0x700;    // get the address 0x700 into a char pointer
char  *jName = (char *) 0x710;    // get the address of 0x710 into a char pointer