C语言指针概述和运算

一、地址的含义、指针概念的提出

cpu在处理数据前,向地址总线发出状态,状态被内存接受,内存就会选中一个区域。根据CPU发出的动作,决定这个区域的数据是读是写。

想保存地址的数据,要解决哪些问题

  1. 容量够不够与cpu的寻址能力有关
    32bit的cpu最大只能有2^32 = 4G的内存。一般来说,C语言直接操作的是OS,所以容量跟操作系统的位数有关

  2. 找到此地址时,由于区域的最小单位是1B,而C语言(高级语言,不是汇编)提供了很多数据类型,所以操作这个区域,必须知道这个区域个数。

所以,他们首先提出了一种单独的新的类型,假设是pointer a。但是这只能解决第1个问题,不能解决第二个,所以最后提出了这种:int *a,用*来提升这个变量为地址,同时用*的外围指向第二个问题。

指针的概念

  1. 是数据类型,不过是一种特殊的数据类型。它有二元含义,一个是容量,一个是如何激活区域(即这区域有多少个)。
char *p1;	
// p1是变量名,*把它升级为指针类型。*的左边是char,char回答了如何激活区域(激活多少个区域)
// p1的大小与前面的char没有任何关系,写int的还是一样,是与系统有关的,因为它存的是地址(地址是那个编号,也就是一串数字)。地址的大小永远只与位数有关。
// *p1的*前面有类型,那么这个*的作用是变量类型提升符;如果前面没有,那么*表示访问第一块元素,即*p1[0]
//*p1与p1[0]等价,[]的写法是偏移多少位

char *p1;  	// p1的名字提升为地址
char a[5]; 	// a的名字提升为数组名(常量)

*p1     	// 以p1为首地址,访问第0个元素
p1[6]  		// 以p1为首地址,偏移6个元素的大小,访问对应的空间

char *s1[5];	// 有5个元素,每个元素存了“一把钥匙”
char (*s2)[5];	// 先升级为地址,5个char,5个char地访问

二、指针的运算

指针的运算的数学含义很弱,主要是逻辑的含义。

  1. 指针和数字
char *p1 = (char*)0x800000;

p1 + 1 //指加的一个单位,也就是`p1的首地址 + 1个单位的大小(sizeof(char))`
  1. 指针和指针
    指针之间类型要一样,有不一样的,有的编译器会报错,有的会警告
int* p2 = (int *)0x800000;
int* p3 = (int *)0x80000C;

// 指针相减,是指针里面的地址相减,再除以数据类型的长度,可以用来算两个地址之间有多少个元素
p3 - p2 = (0x80000C - 0x800000) / sizeof(数据类型) = 3

三、指针是一种数据类型,数组是地址的常量

指针变量是映射关系,而数组则是相等关系(相当于别名)。

int data[5];	// 相当于下面这句
int *const data = 首地址;
&data // 非法使用,因为data和地址已经是相等的了,所以没有任何变量存了data等于的值的地址,所以取它的地址非法。最后是由编译器来定义行为

SUFE大二在读