我是C的新手,正在尝试用七段显示器编写一些基本的应用程序。在声明绝对地址时,对于8位端口,我可以编写如下内容:
typedef char *port8ptr;
#define OUT_ADR 0x400
#define OUT *((port8ptr) OUT_ADR)
然后简单地写出类似
之类的变量OUT = 0x80;
将十六进制80连接到端口。但是上面的代码究竟是什么意思呢?也就是说,为什么要定义一个指针(第一行),然后将地址转换成一个指向指针的指针(?!)?它显然有效,但我不喜欢使用我无法理解的示例中的代码。
他们进行类型转换的另一种方式是使用
行((unsigned char *) 0x400)
但老实说,我也不这样做。
非常感谢提前!
阿克塞尔
答案 0 :(得分:1)
这里的混淆是第二行 - 你认为它是指向指针的指针,而它实际上是一个指针转换的解引用。
让我们回到基础。保存你有一个角色和指向该角色的指针
char c = 'A';
char *p = &c;
您可以取消引用p并返回c - printf('%c', *p)
将打印A,*p='B'
会将c的内容更改为B.
另一个基本的事情是将一个整数转换为指针 - ((char *)0x400)表示指向地址0x400处字节的指针。
所以第二行实际上意味着'将0x80写入地址0x400处的字节'
答案 1 :(得分:1)
语言B和C之间的最大区别在于C添加了类型。因此,您可以为某处指定一个地址,该类型将告诉编译器是否需要为该值加载一个,两个,四个或更多字节。因此,虽然您可以指向系统中的任何地址,但您需要向编译器添加有关您希望加载的位置的字节数的附加信息。这些都会有不同的负荷:
int x1= * ( unsigned char *) 0x400 ;
int x2= * ( unsigned short *) 0x400 ;
int x4= * ( unsigned int *) 0x400 ;
所以x1
将有0x400
的一个字节数据,而x4
将有四个字节。这就是为什么你告诉编译器地址是什么,然后让它去查看那里的值。
答案 2 :(得分:1)
当你进行所有的预处理时,你会得到这一行:
*((char*)0x400) = 0x80;
让我们剖析一下。 (char *)0x400
表示取数字0x400
并将其转换为“指向char的指针”。基本上它在这里说:让我们创建一个指向地址0x400
的指针。
然后,我们将前面的*
视为“取消引用”,这样你就可以在指针所指向的内存点中写一些东西,在本例中为地址0x400
。然后你在其中写0x80
。