引用内存时数据类型之间的区别是什么?

Sal*_*ati 1 c types

我参加了面向机器编程的课程,在引用内存地址时,我在理解数据类型时遇到了一些问题.例如,如果我想访问位置0x40020000上的一块内存.我会这样写的.

#define NAME_OF_THE_REGISTER *((unsigned int *)(0x40020000))
Run Code Online (Sandbox Code Playgroud)

但是使用其他一些数据类型有什么区别?例如unsigned short或unsigned char.我知道它们有不同的范围,但是如果我将这个特定代码更改为unsigned short,我仍然可以访问内存,一切正常.

在我的大学提供的"示例"代码中,他们似乎喜欢在unsigned char,volatile unsigned char,unsigned int,volatile unsigned int等之间切换,我无法弄清楚原因.例

#define     PORT            0x40020000
#define     PORTNAME        ((volatile unsigned int *)      (PORT))
#define     PORTOFFSET1     ((volatile unsigned short *)    (PORT + 0x4)) //offset to access Output register 
Run Code Online (Sandbox Code Playgroud)

使用它们之间的优点和缺点是什么?

Ste*_*mit 5

考虑这种内存布局:

100  01 02 03 04
104  05 06 ff ff
108  07 08 09 10
Run Code Online (Sandbox Code Playgroud)

在一个32位的小端机器上,代码

printf("%d\n", *(char *)104);
printf("%d\n", *(short int *)104);
printf("%d\n", *(int *)104);
printf("%u\n", *(unsigned int *)104);
Run Code Online (Sandbox Code Playgroud)

可能打印

5
1541
-63995
4294903301
Run Code Online (Sandbox Code Playgroud)

(如果不明显,这些数字的来源是它们分别是十进制表示:0x05,0x0605,0xffff0605被解释为有符号的int,0xffff0605被解释为无符号的int.)

所以,是的,您投射指针的类型决定了编译器将如何访问和解释内存.(严格地说,它决定了编译器如何生成代码,以及生成的代码将如何访问和解释内存.)

  • 的大小指向的键入(char,short,int,long,等等),将决定了多少字节访问.(根据硬件的不同,它还将确定是否存在任何对齐限制.)
  • 指向类型是有符号还是无符号将决定如何解释指向的内存.(可以肯定的是,区别的重要部分在于或其余代码如何在以后解释这些值.例如,无论您是使用打印%d还是%u最终都会产生与选择签名相同或更多的差异或无符号类型.)
  • 是否volatile使用类似的限定符可能不会最终产生差异.