为什么要在其声明中强制转换指针?
Why typecast a pointer at its declaration?
不确定我的问题措辞是否正确,也不确定如何最好地解释我想回答的问题,所以请耐心等待。
在定义微控制器寄存器时,你会这样写:
#define io_register (*(volatile unsigned char *)0x25)
我在这里也找到了这行代码:Pass a hex address to a Pointer Variable
int *pointer = (int *) 0x00010010;
我知道指向 int 的指针被声明在 = 符号的左边,但为什么会有类型转换 *(int ) 对吗?
与 #define 相同,我知道 0x25 处的值正在被取消引用,但为什么我不能这样写:
#define io_register *(0x25)
或
int *pointer = 0x25;
我在这里错过了什么?请随时改写或更正我所犯的任何错误,我仍在努力思考指针和寄存器。
需要强制转换,因为0x00010010
不是指针而是整数(它是int
、unsigned int
或long int
中第一个可以表示值 65552) .
只有值为 0
的整数常量表达式可以隐式转换为指针(即不进行强制转换);结果指针将是空指针。
自然会写
#define io_register *(0x25)
但是你不能使用那个io_register
来访问地址0x25的内存,因为那个0x25
不是一个指针——它是一个整数。
在 C 中并不真正访问地址;相反,一个取消引用指针以获取指定 对象 的 lvalues,然后获取该对象的值,或为其设置一个新值。
有
int *pointer = (int *) 0x00010010;
你告诉指针指向内存中的绝对地址,该地址的值可以用 *pointer
取消引用。
有
int *pointer = 0x25;
编译器不喜欢那样,因为 0x25 是一个整数但指针不是整数,它是一个整数指针。
任何赋值操作的一个重要先决条件是数据类型兼容性。换句话说,方程 (int *pointer = 0x25;)
LHS (int *pointer)
的数据类型必须与方程 的计算结果的任何数据类型兼容RHS(0x25)
.
比如LHS和RHS都是int
类型,那么将RHS的整数值赋值给LHS.
就没有问题了
但是,在这个表达式中:
int *pointer = 0x25;
您在 LHS 和 int
[=43 中有 int *
数据类型=] RHS 中的数据类型。因此,LHS 和 RHS 之间存在不兼容性。这就是为什么你需要将 RHS 转换为 (int *)
.
演员表取消警告。这就是它在这些声明中的作用。否则它将被隐式转换,并省略警告。代码或程序执行没有区别。
#define io_register *(0x25)
*(0x25)
在任何情况下都不是指针,使用时 io_register
表示:乘以 0x25。
int x = 10 io_register;
这意味着:int x = 10 *(0x25);
不确定我的问题措辞是否正确,也不确定如何最好地解释我想回答的问题,所以请耐心等待。
在定义微控制器寄存器时,你会这样写:
#define io_register (*(volatile unsigned char *)0x25)
我在这里也找到了这行代码:Pass a hex address to a Pointer Variable
int *pointer = (int *) 0x00010010;
我知道指向 int 的指针被声明在 = 符号的左边,但为什么会有类型转换 *(int ) 对吗?
与 #define 相同,我知道 0x25 处的值正在被取消引用,但为什么我不能这样写:
#define io_register *(0x25)
或
int *pointer = 0x25;
我在这里错过了什么?请随时改写或更正我所犯的任何错误,我仍在努力思考指针和寄存器。
需要强制转换,因为0x00010010
不是指针而是整数(它是int
、unsigned int
或long int
中第一个可以表示值 65552) .
只有值为 0
的整数常量表达式可以隐式转换为指针(即不进行强制转换);结果指针将是空指针。
自然会写
#define io_register *(0x25)
但是你不能使用那个io_register
来访问地址0x25的内存,因为那个0x25
不是一个指针——它是一个整数。
在 C 中并不真正访问地址;相反,一个取消引用指针以获取指定 对象 的 lvalues,然后获取该对象的值,或为其设置一个新值。
有
int *pointer = (int *) 0x00010010;
你告诉指针指向内存中的绝对地址,该地址的值可以用 *pointer
取消引用。
有
int *pointer = 0x25;
编译器不喜欢那样,因为 0x25 是一个整数但指针不是整数,它是一个整数指针。
任何赋值操作的一个重要先决条件是数据类型兼容性。换句话说,方程 (int *pointer = 0x25;)
LHS (int *pointer)
的数据类型必须与方程 的计算结果的任何数据类型兼容RHS(0x25)
.
比如LHS和RHS都是int
类型,那么将RHS的整数值赋值给LHS.
但是,在这个表达式中:
int *pointer = 0x25;
您在 LHS 和 int
[=43 中有 int *
数据类型=] RHS 中的数据类型。因此,LHS 和 RHS 之间存在不兼容性。这就是为什么你需要将 RHS 转换为 (int *)
.
演员表取消警告。这就是它在这些声明中的作用。否则它将被隐式转换,并省略警告。代码或程序执行没有区别。
#define io_register *(0x25)
*(0x25)
在任何情况下都不是指针,使用时 io_register
表示:乘以 0x25。
int x = 10 io_register;
这意味着:int x = 10 *(0x25);