指针之 *((volatile unsigned long *)(x))解析
今天重新温习了一下C语言的指针部分,突然想到了经常会碰见的一种宏定义:#define PGAS (*((volatile unsinged long *)(x)))
在解析该宏定义前,先看看指针变量的声明
声明一个int类型的指针变量:int* p;
仅仅是这样定义,这个指针是不能够直接拿来使用的,还必须给它赋值(初始化),例如:
int a = 10;
int* p = &a;
或:
int a = 10;
int* p;
p = &a;
其中,&a表示变量a所代表的内存地址,所以指针变量p存储的是一个内存地址(这个地址要和指针变量p自身的地址区分开),而*p是指针变量p所指内存地址中存储的数据(上述代码中既是变量a的值),经过初始化的指针我们是可以拿来使用的。
例如:给这个指针所指内存地址赋值:*p = 15;
读取这个指针所指地址中存储的数据的值 printf(“d\n”,*p);
运行下面的代码,可以很清楚的了解指针变量的地址和指针变量所指的地址的关系:
void main()
{
int a = ;
int* p = &a; printf("变量 a 的值:%x\n",a);
printf("变量 a 的地址:%x\n",&a);
printf("指针变量 p 的值:%x\n",p);
printf("指针变量 p 的地址:%x\n",&p);
system("pause");
}
运行结果:

从图中可以看出变量a的地址和指针变量p的值是一样的:0x23febc
回归正题:#define PGAS (*((volatile unsinged long *)(x)))
其中,x 是一个常量,代表内存地址值,(volatile unsinged long *)(x) 是把这个常量x强制转换为一个unsigned int 指针,(*((volatile unsinged long *)(x)))表示的是地址x中的数据。
在上面的代码中我们可以进行类似数学公式的带入替换:
int a = 10;
int* p;
p = &a;
一般我们要对指针变量p所指地址赋值或要读取指针变量p所指地址中的数据时,是这样操作的:
int b = *p;
*p = 20;
等价于:
int b = *(&a);
*(&a) = 20;
上面说了&a表示的是变量a的地址,也就是一个无符号整型(unsigned int)常量。
再看一段代码:
#include <stdio.h> #define A (*((volatile unsigned int*)(0x23febc))) void main()
{
A = ;
printf("%d\n",*((unsigned int*)(0x23febc)));
printf("%d\n",A); system("pause");
}

记得刚接触到这种宏定义时,查查资料当时可以弄懂,可是等到下次再遇见时,又不明白了,总之是时而明白,时而糊涂。
以文字的形式记录下来,可以帮自己整理整理思路加深理解和记忆。
指针之 *((volatile unsigned long *)(x))解析的更多相关文章
- C语言之强制类型转换与指针--#define DIR *((volatile unsigned int *) 0x0022)
强制类型转换形式:(类型说明符) (表达式) 举例说明:1) int a; a = (int)1.9; 2)char *b; int *p; p = (int *) b; //将b的值强制转换为指向整 ...
- *(volatile unsigned long *) 语法
#define GPJ2CON (*(volatile unsigned long *) 0xE0200280) 开始对于上面的语法不太理解,但通过拆分,我们可以看的更明白: 1.(unsigned ...
- 嵌入式中的 *(volatile unsigned int *)0x500 解释
C语言中*(volatile unsigned int *)0x500的解释: 如下: (unsigned int *)0x500:将地址0x500强制转化为int型指针*(unsigned int ...
- (*(volatile unsigned long *)详解
(*(volatile unsigned long *) 对于不同的计算机体系结构,设备可能是端口映射,也可能是内存映射的.如果系统结构支持独立的IO地址空间,并且是端口映射,就必须使用汇编语言完成实 ...
- 【嵌入式】——对#define GPBCON (*(volatile unsigned long*)0x56000010)的理解
#define GPBCON (*(volatile unsigned long*)0x56000010) 1:volatile 当计算机需要一个数值的时候,会先把内存中的值读取到寄存器,然后下次在使 ...
- (C)理解#define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
理解 #define write(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b)) 嵌入式系统编程,要求程序员能够利用C语言访问固 ...
- 嵌入式开发(*(volatile unsigned long *)) 认识
一个.说明 (*(volatile unsigned long *)) 这个语句对于不同的计算机体系结构,设备可能是port映射,也可能是内存映射的. 假设系统结构支持独立的IO地址空间.而且是por ...
- gcc -02引起内存溢出'unsigned i'应修订为'volatile unsigned i'
2017-12-13 10:44:19gcc -02引起内存溢出'unsigned i'应修订为'volatile unsigned i' 1.3.100 driver/char/random.cst ...
- #define GPFCON (* (volatile unsigned long * )0x56000050 )
int a; int *p; p = &a; *p = 0x100; //a=0x100 p = (int *)0x56000050; *p =0x100; *( ( int * ) 0x56 ...
随机推荐
- day06 Java面向对象
1.对象内存图 (1)1个对象的内存图:一个对象的基本初始化过程 (2)2个对象的内存图:方法的共用 (3)3个对象的内存图:其中有两个引用指向同一个对象
- SIGGRAPH 2014 之行
当地时间8月8号: 经历十个多小时的飞行,在紧急出口旁的位置上忍受发动机的轰鸣声后,顺利降落温哥华机场.回答完加拿大边检的几个诸如为何而来,打算住哪儿的问题后,比较顺利出关.三十五加元的打车费及百分十 ...
- css笔记08:id选择器之父子选择器
1.父子选择器 (1)01.html <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- [Visual Studio] 开启Visual Studio 2012通过右键菜单创建单元测试(Unit Test)
Visual Studio 2012可以说是迄今为止微软VS开发工具中用户体验最好的产品,无论是速度还是体验以及功能,都非常出色,但是,使用了一段时间后发现有一个之前版本VS都有的功能却在Visual ...
- 采用虚拟命名管道的字符设备和阻塞型I/O实现进程间的通信实现KWIC程序
采用虚拟命名管道的字符设备和阻塞型I/O实现进程间的通信实现KWIC程序专业程序代写c++程序代写
- JSONP与JSON的关系
这篇文章<说说JSON和JSONP,也许你会豁然开朗>写得非常棒,推荐一下 http://kb.cnblogs.com/page/139725/ (大神,对不起,我记录一下,因为你写的真得 ...
- 【安卓面试题】使用SQLiteOpenHelper的getReadableDatabase()获得的数据库能不能,做写的操作
可以! 不要被Readable的意思误导啦,readable是可读的意思,但不代表不能写哦. getReadableDatabase() 会获取用于操作SQLiteDatabase的实例. getRe ...
- Linux下文件的三个时间(Atime,Mtime,Ctime)
文件的三个时间 我们已经很熟悉windows系统了,那么我们在windows下新建一个文件,我们知道它在保存的时候肯定是会保存一下文件的创建时间之类的信息的,那么我们来看看windows下的一个文件保 ...
- javaweb学习总结二十三(servlet开发之线程安全问题)
一:servlet线程安全问题发生的条件 如果多个客户端访问同一个servlet时,发生线程安全问题,那么它们访问的是相同的资源.如果访问 的不是相同资源,则不存在线程安全问题. 实例1:不会产生线程 ...
- PHPnow开启PHP扩展里openssl支持的方法
PHPnow 是 Win32 下绿色的 Apache + PHP + MySQL 环境套件包.简易安装.快速搭建支持虚拟主机的 PHP 环境.更多介绍<PHP服务套件 PHPnow1.5.6&g ...