指针是C语言中的一个重要概念,也是C语言的一个重要特色。
正确而灵活地运用它,可以有效地表示复杂的数据结构,能动态分配内存,指针 提供了一个能力 --直接使用内存,方便地使用字符串,有效而方便地使用数组,在调用函数时能获得1个以上的结果,能直接处理内存单元地址等,这对设计系统软件是非常必要的。
一、指针是什么
计算机的内存是按字节进行编址的 ,一个字节一个地址编号(地址),指针就是地址,地址就是内存单元的编号。
二、指针类型
定义指针变量的一般形式为:
基类型 * 指针变量名;
(1) (2) (3)
说明:
(1)基类型 : 表示的是 指针(地址) 所指向的空间的 数据类型
(2) * : 定义指针变量时,只是用来说明该变量 是指针类型
(3)指针变量名: 就是一个标识符 和 普通变量的命名规则一致
eg:
int a = 10; //
int * p=&a; //定义了一个指针变量p
//定义了一个指向int型数据的指针变量p
//定义了指针变量 意味着 也要开空间
// &a 取地址运算 表示取到a所在空间的起始地址
空间开多大, 取决于 p对应的数据类型,p对应的数据类型 ---指针类型 int*
32位 系统 --- 对应地址大小 统一都是32位 --4个字节
64位 系统 --- 对应地址大小 统一都是64位 --8个字节
对于a这块空间的使用有两种方式
1.直接通过a使用 --- 直接引用
2.间接引用 --- 指针的方式
int a = 10;
int *p = &a;
step1(找): 首先,通过p本身
可以得到 a所在空间的地址 //通过p本身 只是 能找到a
step2(用): 解引用
*p
运算过程:
//step1: 拿出p中地址编号,到内存中寻找
//step2: 从定位处开始 偏移出sizeof(基类型)大小的一块空间
//step3: 将偏移出的这块空间,当做一个基类型变量来看
*p <==运算结果==> 相当于是一个 int型变量
三、指针的最大的一个用法——实现被调用修改主调
eg:
int addOne(int *p)//接收n的地址 { *p=*p+1;//解引用,对n进行操作修改了n的值 } int main(void) { int n=10; addOne(&n);//想要被调修改n这个变量,就把n的地址传过去 printf("%d\n",n);//打印结果是11,主函数中的n被修改了 return 0; }注意:
被调修改主调
1.要修改谁,就传谁的地址
2.在被调函数中,一定要有相应的*p运算
四、指针操作一维数组
int a[10] = {1,2,3,4,5,6,8,9,10};
数组特点:
1.连续性
2.单一性 <--类型一致
3.有序性 <--按顺序存放
数组名
从值的的角度,数组名代表数组首元素的地址 ,首元素地址也是整个数组起始地址
知道了首元素地址就能访问首元素
int *p = a;
= &a[0]; // a[0] 是啥类型 --- 是int类型
//&a[0] 取了一个存放int型数据空间的地址 // int *
指针运算:
p + 1 //表示地址 加了 一个基类型大小
p + N //表示地址 加了 N个基类型大小
p ++
p --
p-q //必须是同类型指针 表示 差了几个基类型
关系运算:
> >= < <= == !=
p > q //地址编号 编号大的 就大
指针操作数组
1.因为数组的特点
只需要知道首元素地址即可
2.指针运算
p+N
3.指针 * 运算
p+i => 第i个元素的地址 i可以是 0 1 2 ...
*(p+i)=> 第i个元素(变量) 等价于 a[i]