#include <stdio.h>
int main()
{
int i = 10;
//指针
int* pi = &i;
//*是解引用操作符
printf("*pi=%d\n", *pi);
//通过解引用操作符改变i的值
*pi = 15;
printf("a=%d\n", i);
return 0;
}
运算结果:*pi=10
a=15
C指针:从根本上看,指针是一个值位内存地址的变量,其作用是用于储存变量的地址。最后一句是重点,指针的实质是储存地址的变量。
计算机会划分成一个个内存单元,每个内存单元都有一个编号,这种编号叫机器地址。
1个内存单元大小为1byte(字节)
比如32位电脑中,地址线有32根,而每根地址线都有正负脉冲(0和1),那么32位地址从:
0000 0000 0000 0000 0000 0000~1111 1111 1111 1111 1111 1111
共有2^32个地址序列,换算过来是4GB,也就是说一个32位电脑就有43亿个字节用来储存地址。
而这43亿个内存地址都是有编号的,比如从1~43亿编号,这就像酒店中的房间,每个房间都有编号,指针实质上就是这些门牌编号。
上述程序图示:
所以从本质上讲指针就是地址,就是内存单元的编号。
存放指针的变量就是指针变量
指针用到的操作符:
1.取地址操作符:&
2.解引用操作符:*,也叫间接运算符
*作用是找到储存在右值中的值
规定:pi = &i我们把i的地址赋给pi,我们称pi“指向”i
*pi= val val是pi指向的值
以上两式合起来等价于pi = val;
例如: nurse = 22;
ptr = &nurse //指向nurse的指针
val=*ptr //把ptr指向的地址上的值赋给val
声明指针
int* pi;
//pi是指向int类型变量的指针
当有多个指针变量:int *pi, *pg, *pt;
//int说明pi指向的对象是int类型的
pi拿到a的4个字节中第一个最小的地址
不管什么类型的指针,都是在创建指针变量
指针变量的大小取决于一个地址存放时需要多大空间
编写程序时,可以认为变量有两个属性:名称和值。计算机编译和加载程序后,认为变量也有两个属性:地址和值。地址就是变量在计算机内部的名称。
简言之,普通变量把值作为基本量,把地址作为通过&运算符获得的派生两,而指针变量把地址作为基本量,把值作为通过*运算符获得的派生量。
类比:
我们把内存看成有一排楼房的居民楼,这些楼房最初也有着自己的地址编号,就像某栋某单元某号。
后来,来了a b 两个人买房,a 选择int类型的房子,地址号001~004正好满足a先生的需求,int类型是4个单元房子合成一个的大房子,属于整形区的房子,买过房子之后,001~004就称为a先生的家。在现实生活中我们也会如此,别人问那是谁家,我们会说那是张三的家,那是李四的家,而不会去报他家在地球上的经纬度。a先生买过房子之后,酒吧自己家乱七八糟的东西搬进了新房子,这些东西就是值,10,这就是int a = 10;的存放类比。
同理b先生没a先生有钱,所以买了char类型的房子,char类型是一个单元格,也就是一个字节,字符类型的房子,房产商将地址号为009的房子给了b先生,过户到b先声明下,此后009房间不再叫009,而是叫b先生家。然后b把东西'k'放进去,这就是char b = 'k'的类比。
后来a家有急事不在家但需要装修,需要物业进入家中,我们把指针p等价成物业,物业找业主的家是不会找到谁家谁家的,他们只会找到a先生在几栋几单元,从原始地址序列找到a先生的家,a先生家的地址在计算机上我们用&a表示,物业找到a的家,要先知道在那部分的房子,一查是int型的房子,然后直接对接。这就是int* p = &a;
这个*我们可以看做a家里的钥匙,物业拿着钥匙*打开a的房子,然后装修师傅装修了一通,加减家具,那么屋子里的东西肯定变了,原来的值10变成了现在的15,这个变化是通过物业引起的,而不是a的变化,物业拿着钥匙把a的东西从10变化到15,这就是解引操作*p = 15
#include <stdio.h>
int main()
{
int a = 10;
int* p = &a;
printf("*p=%d\n", *p);
*p = 15;
printf("a=%d\n", a);
return 0;
}
运行结果: