int  *MFSS_Pointer;
#define       FPGA_ADDR         0x0a0000000//CE2
MFSS_Pointer = (int*)(FPGA_ADDR+4*i);
*MFSS_Pointer = (data_q<<16)+data_i;

第一行定义一个指针,名字是MFSS_Pointer
第二行宏定义,“#”表示这是一条预处理命令,“define”为宏命令。宏定义只是一个方便替换的操作,代码中遇到FPGA_ADDR直接替换为0x0a0000000。说白了#define 并不是进行变量定义,所以就不需要指定“变量”类型了。它只是一个数-符替换工具罢了。
第三行:(FPGA_ADDR+4i)是一个数,(int)(FPGA_ADDR+4i)强制类型转换,把(FPGA_ADDR+4i)转换成一个指向int型的指针(即一个内存,内存没名字,它指向(FPGA_ADDR+4i)这个地址);MFSS_Pointer = (int)(FPGA_ADDR+4i);把这个内存叫做MFSS_Pointer。这是直观理解。总起来就是,指针MFSS_Pointer指向位置(FPGA_ADDR+4i)
第四行*MFSS_Pointer指向的地方赋值。

1.关于C语言指针中 * 的位置

char* a,b;
等价于
char *a;char b;
而不等价于
char *a;char *b;
所以写成
char *a,b;
更不容易引起歧义。

2.取地址运算符和取值运算符

获取某个变量的地址,使用取地址运算符&,如:

char* pa = &a;
int* pb = &f;

如果反过来,你要访问指针变量指向的数据,那么你就要使用取值运算符*,如:

printf("%c, %d\n", *pa, *pb);

这里你可能发现,定义指针的时候也使用了,这里属于符号的「重用」,也就是说这种符号在不同的地方就有不同的用意:在定义的时候表示「定义一个指针变量」,在其他的时候则用来「获取指针变量指向的变量的值」。*

直接通过变量名来访问变量的值称之为直接访问,通过指针这样的形式访问称之为间接访问,因此取值运算符有时候也称为「间接运算符」。
比如:

//Example 01
//代码来源于网络,非个人原创
#include <stdio.h>
int main(void)
{char a = 'f';int f = 123;char* pa = &a;int* pf = &f;printf("a = %c\n", *pa);printf("f = %d\n", *pf);*pa = 'c';*pf += 1;printf("now, a = %c\n", *pa);printf("now, f = %d\n", *pf);printf("sizeof pa = %d\n", sizeof(pa));printf("sizeof pf = %d\n", sizeof(pf));printf("the addr of a is: %p\n", pa);printf("the addr of f is: %p\n", pf);return 0;
}

程序实现如下:

//Consequence 01
a = f
f = 123
now, a = c
now, f = 124
sizeof pa = 4
sizeof pf = 4
the addr of a is: 00EFF97F
the addr of f is: 00EFF970

3.避免访问未初始化的指针

void f()
{int* a;*a = 10;
}

像这样的代码是十分危险的。因为指针a到底指向哪里,我们不知道。就和访问未初始化的普通变量一样,会返回一个「随机值」。但是如果是在指针里面,那么就有可能覆盖到「其他的内存区域」,甚至可能是系统正在使用的「关键区域」,十分危险。不过这种情况,系统一般会驳回程序的运行,此时程序会被「中止」并「报错」。要是万一中奖的话,覆盖到一个合法的地址,那么接下来的赋值就会导致一些有用的数据被「莫名其妙地修改」,这样的bug是十分不好排查的,因此使用指针的时候一定要注意初始化。

4,scanf中取地址符号的使用

int main(void)
{int a;int* p = &a;printf("请输入一个整数:");scanf("%d", &a);//此处需要&printf("a = %d\n", a);printf("请再输入一个整数:");scanf("%d", p);//此处不需要&printf("a = %d\n", a);return 0;
}

程序运行如下:

//Consequence 02
请输入一个整数:1
a = 1
请再输入一个整数:2
a = 2
字符串地址
//Example 03
#include <stdio.h>
int main(void)
{char url[100];url[99] = '\0';printf("请输入TechZone的域名:");scanf("%s", url);//此处也不用&printf("你输入的域名是:%s\n", url);return 0;
}

程序执行如下:

//Consequence 03
请输入TechZone的域名:www.techzone.ltd
你输入的域名是:www.techzone.ltd

数组名其实就是一个「地址信息」,实际上就是数组「第一个元素的地址」

//Example 03 V2
#include <stdio.h>
int main(void)
{char url[100];printf("请输入TechZone的域名:");url[99] = '\0';scanf("%s", url);printf("你输入的域名是:%s\n", url);printf("url的地址为:%p\n", url);printf("url[0]的地址为:%p\n", &url[0]);if (url == &url[0]){printf("两者一致!");}else{printf("两者不一致!");}return 0;
}

程序运行结果为:

//Comsequense 03 V2
请输入TechZone的域名:www.techzone.ltd
你输入的域名是:www.techzone.ltd
url的地址为:0063F804
url[0]的地址为:0063F804
两者一致!

%p是打印地址的

5.指向数组的指针

刚刚我们验证了数组的地址就是数组第一个元素的地址。那么指向数组的指针自然也就有两种定义的方法:

...
char* p;
//方法1
p = a;
//方法2
p = &a[0];

6.指针的运算

当指针指向数组元素的时候,可以对指针变量进行「加减」运算,+n表示指向p指针所指向的元素的「下n个元素」,-n表示指向p指针所指向的元素的「上n个元素」。并不是将地址加1。

如:

//Example 04
#include <stdio.h>
int main(void)
{int a[] = { 1,2,3,4,5 };int* p = a;printf("*p = %d, *(p+1) = %d, *(p+2) = %d\n", *p, *(p + 1), *(p + 2));printf("*p -> %p, *(p+1) -> %p, *(p+2) -> %p\n", p, p + 1, p + 2);return 0;
}

执行结果如下:

//Consequence 04
*p = 1, *(p+1) = 2, *(p+2) = 3
*p -> 00AFF838, *(p+1) -> 00AFF83C, *(p+2) -> 00AFF840

其实使用指针法来访问数组的元素,不一定需要定义一个指向数组的单独的指针变量,因为数组名自身就是指向数组「第一个元素」的指针,因此指针法可以直接作用于数组名:

...
printf("p -> %p, p+1 -> %p, p+2 -> %p\n", a, a+1, a+2);
printf("a = %d, a+1 = %d, a+2 = %d", *a, *(a+1), *(a+2));
...

执行结果如下:

p -> 00AFF838, p+1 -> 00AFF83C, p+2 -> 00AFF840
b = 1, b+1 = 2, b+2 = 3

来源:http://www.techzone.ltd/post/CPointer/

C指针 取地址符 取值符*相关推荐

  1. C++ 笔记(14)— 指针(指针声明、取地址、取值、new/delete、NULL指针、指针运算、指针数组、数组指针、指针传递给函数、从函数返回指针)

    1. 声明指针 指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使用指 针存储其他变量地址之前,对其进行声明. 指针变量声明的一般形式为: type * ...

  2. C语言指针的指针与取地址和*取值

    int n=5;//定义一个变量n int *p=&n;使用&取n首个元素的地址给p 那输出p就可以打印n的首地址. 输出*p就可以打印n的元素:5. *取值: 上面是给p加*取值符号 ...

  3. 变量与指针、取值符与取地址符

    变量与指针.取值符与取地址符 一.基础知识 二.实例 其他 by HPC_ZY 也是偶然,在一个项目中需要多次交换二维数组中的值,逐个操作确实耗时,就想能不能利用指针操作快速交换.成功后写此文,记录分 ...

  4. C++ 中的:“引用” 和“取地址符”的区别和作用

    引用 引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. &作为引用的时候,必须在定义时候就进行初始化,若不进行初始化则会编译报错. int N; int &r ...

  5. 数组名和指针的区别和联系、数组名取地址a

    前言 在很多用到数组名字的地方,编译器都会自动地将其替换为一个指向该数组首元素的指针. 所以,在大多数表达式中,使用数组名其实是在使用一个指向该数组首元素的指针. 数组名其实是种特殊的指针 int m ...

  6. 【C 语言】数组 ( 多维数组操作模型 | 取某个数组元素地址 | 取某个数组元素值 )

    文章目录 一.多维数组操作模型 1.取出某个数组元素地址 2.取出某个数组元素值 总结 一.多维数组操作模型 以 // 声明一个多维数组int array[2][3]; 二维数组为例 ; 1.取出某个 ...

  7. C++指针与地址详解 _0

    指针的概念 ◆ 1."存储器"的概念 文件柜–>文件柜上的抽屉–>抽屉上的编号 对应于: 存储器-–>存储单元-–>存储单元的地址 ◆ 2.存储器的使用 1 ...

  8. 取地址符和解引用符的区别_(&)和解引用(*)运算符的地址以及C中的指针...

    取地址符和解引用符的区别 Here, we are discussing about the two most useful operators with the pointers, why and ...

  9. C语言中 指针变量 取地址符的用法 *指针变量名的用法

    文章目录 总结 Intro Code 图示 总结 众所周知,内存可以看成一个一个相邻的格子(类比Excel),而数据就存储于这些格子之中(size大的变量占用格子数多,size小就占用小).而每个格子 ...

  10. c语言函数变量地址符,C语言中取地址符做函数形参?—— 引用的讨论

    取地址符&做函数形参? C语言强大且危险 引入 这个问题花去了整整一天的研究. 先看一段严蔚敏的<数据结构>中栈的例程: 这里面的&S第一遍看的时候想当然的认为是取了SqS ...

最新文章

  1. python 应声虫怎么做_职场人士如何处理好人际关系:要服从,但不要做毫无主见的应声虫...
  2. AI时代:推荐引擎正在塑造人类
  3. 云计算赋能人工智能,未来的红利在哪?
  4. python基础教程小甲鱼-小甲鱼零基础入门学习Python3视频教程全套96集
  5. 《软件建模技术》课程教学大纲
  6. asp.net+mvc+easyui+sqlite 简单用户系统学习之旅(二)—— easyui的简单实用
  7. 遇到:ORA-27121: UNABLE TO DETERMINE SIZE OF SHAR...
  8. 学习ROS过程中遇到的一些小问题以及解决办法的记录
  9. 三次握手的本质_关于TCP三次握手,这是我见过最好的解读了,通俗易懂
  10. ros melodic控制真实机械臂之获取moveit规划插补点
  11. cf1042d 树状数组逆序对+离散化
  12. SpringAOP底层API之代理对象执行流程
  13. IPHONE手机知识大全(下)
  14. 最全面试题CSS(含答案)
  15. 【html】表格table与表单form
  16. 酒店客房管理系统源代码 java_《宾馆客房管理系统》JAVA源代码
  17. linux申请令牌错误,解决“请求中包含的安全令牌已过期”错误
  18. ruoyi增加导入导出
  19. Office Professional Plus 2019 下载安装激活
  20. 如何混淆JavaWeb代码

热门文章

  1. 云计算业务发展迅速 或成资本角逐新战场
  2. 计算机专业课科目,考研计算机专业课科目有哪些
  3. linux下把文件夹压缩成tar.gz的命令
  4. 手把手教你:人脸识别的视频打码(基于opencv的人脸打马赛克)
  5. 51nod 1459 1212
  6. GDS中如何加logo
  7. 计算机第一级开机密码设置,开机密码怎么设置
  8. 计算机怎么取消账户密码怎么设置,电脑开机密码怎么设置以及取消
  9. python词云库wordCloud中文乱码
  10. R语言对数据进行非参数检验