概述
1. 什么是指针
C语言中指针是一种数据类型,指针是存放数据的内存单元地址。
计算机系统的内存拥有大量的存储单元,每个存储单元的大小为1字节,为了便于管理,必须为每个存储单元编号,该编号就是存储单元的“地址”,每个存储单元拥有一个唯一的地址。
指针变量除了可以存放变量的地址外,还可以存放其他数据的地址,例如可以存放数组和函数的地址。
2. 指针的定义和初始化
格式:数据类型符 *指针变量名[=初始地址值]。
功能:定义指向“数据类型符”的变量或数组的指针变量,同时为其赋初值。
定义说明:
1. “*” 表示定义的是一个指针变量,指针变量的前面必须有 “*” 号;
2. 在定义指针变量的同时也可以定义普通变量或数组等其它变量;
3. “数据类型符” 是指针变量所指向变量的数据类型,可以是任何基本数据类型,也可以是其他数据类型;
4. “初始地址值” 通常是 “&变量名” “&数组元素” 或 “一维数组名”,这里的变量或数组必须是已定义的;
5. 在定义指针变量时,可以只给部分指针变量赋初值;
6. 指针变量的初始化,除了可以是已定义变量的地址,也可以是已初始化的同类型的指针变量,也可以是NULL(空指针);
7. 指针变量初始化时,指针变量的“数据类型符”必须与其“初始地址值”中保存的数据的类型相同;
8. 不能用auto类型的地址去初始化static型指针。
3. 指针变量的使用
1. 给指针变量赋值
格式:指针变量=地址型表达式
“地址型表达式”即运算结果是地址型的表达式。C语言规定,变量地址只能通过取地址运算符获得,即“&”,其运算对象是变量或数组元素名,运算结果是对应变量或数组元素的地址。
需要注意的是,虽然地址是一个整数,但是C语言中不允许把整数看成“地址常量”,所以此处的“地址型表达式”不能是整数。
2. 使用指针变量
格式:指针变量名
需要使用地址时,可以直接引用指针变量名。
3. 通过指针变量引用所指向的变量
格式:*指针变量名
“*指针变量名” 代表其指向的变量或数组元素,其中的“*”称为指针运算符。需要注意的是,这种引用方式要求指针变量必须已经定义且有值。
4. 指针的基本运算
1. 取地址运算符 &
取地址运算符“&”的功能是取变量的地址,它是单目运算符。取地址运算符的运算对象必须是已经定义的变量或数组元素,但不能是数组名。运算结果是运算对象的地址。
2. 指针运算符 *
指针运算符“*”的功能是取指针变量所指向地址中的内容,与取地址运算符“&”的运算是互逆的,它是单目运算符。指针运算符的运算对象必须是地址,可以是已赋值的指针变量,也可以是变量或数组元素的地址,但不能是整数,也不能是非地址型的变量。运算结果就是地址对应的变量。
取地址运算符和指针运算符的优先级和结合性:
1. 取地址运算符、指针运算符和自增、自减等单目运算符的优先级相同;
2. 所有单目运算符的结合性为从右至左。
5. 指针的算术运算
指针变量可以进行的算术运算包括:
1. 指针变量 ± 整数;
2. 指针变量++ 与 ++指针变量;
3. 指针变量-- 与 --指针变量;
4. 指针变量1- 指针变量2;
由于指针运算符*与自增运算符++、自减运算符--的优先级相同,结合方向都是从右至左,因此需要注意以下各种形式的含义不同。
6. 指针的关系运算
两个类型相同的指针变量可以运用关系运算符比较大小,表示两个指针变量所指向地址位置的前后关系,即:前者为小,后者为大。
需要注意的是,如果两个指针变量不是指向同一个数组,则比较大小没有实际意义。
7. 指针变量的引用
1. 通过指针变量访问整型变量
2. 指针变量作为函数参数
普通变量作为函数的参数传递时是按值传递,实参与形参不共享内存。指针变量作为函数参数时是地址传递,共享内存,“双向传递”。
以下是按值传递的情况:
以下是按地址传递的情况:
8. 指针和数组
数组的指针是指向数组在内存的起始地址,数组元素的指针是指向数组元素在内存的起始地址。
1. 当指针变量指向一维数组,可以采用以下两种方法:
(1). 在数据定义语句中用赋初值的方式:*指针变量=数组名;
(2). 在程序中用赋值的方式:指针变量=数组名;
2. 当指针变量指向一维数组元素,可以采用以下两种方法:
(1). 在数据定义语句中用赋初值的方式: *指针变量=&数组名[下标];
(2). 在程序中用赋值的方式: 指针变量=&数组名[下标];
3. 当指针变量指向一维数组,利用指针变量引用一维数组元素的方法如下:
(1). 引用下标为0的数组元素:*(指针变量+0) 或 *指针变量 或 指针变量[0];
(2). 引用下标为 i 的数组元素:*(指针变量+i) 等同于 指针变量[i] 或者 指针变量[i] 等同于 数组名[i];
4. 当指针变量指向一维数组元素,利用指针变量引用数组元素的方法如下:
(1). 引用下标为 i 的数组元素:*(指针变量 + 0) 或 *指针变量;
(2). 引用下标为 i-k 的数组元素:*(指针变量 - k);
(3). 引用下标为 i+k 的数组元素:*(指针变量 + k);
上面的总结文字看起来有枯燥,下面两张图看起来会更生动和形象一些。
还有下面这张:
9. 指针和字符串
将指针变量指向字符串的方法如下:
1. 在数据定义语句中用赋初值的方式:*指针变量=字符串;
2. 在程序中用赋值的方式:指针变量=字符串;
需要注意的是,这两种方法并不是将字符串赋予指针变量,而是将存放字符串的连续内存单元的首地址赋予指针变量。
当指针变量指向字符串时,则可以利用指针变量处理字符串,处理方式有以下几种:
1. 处理整个字符串
(1). 输出整个字符串:printf("%s",指针变量);
(2). 输入整个字符串:scanf("%s",指针变量);
#include "stdio.h"
int main(){
char *string = "I love China";
printf("%s",string);
// I love China
return 0;
}
2. 处理字符串中的单个字符
(1). 输出整个字符串:printf("%c",指针变量);
(2). 输入整个字符串:scanf("%c",指针变量);
#include "stdio.h"
int main(){
char *string = "I love China";
for(;*string!='