定义
指针的说明
- 字节是最⼩的存储单元,⼀个字节称为⼀个存储单元(内存单元),
- 不同数据类型所占⽤的存储单元不等
- 为了正确访问内存单元,每个内存单元都有⼀个编号。内存单元的 编号称作地址
- 内存单元中的内容才是我们关注的数据
指针的好处
- 为函数提供修改调用变量的灵活手段
- 让函数有多个返回值
- 改善某些子程序的效率:在数据传递时,如果数据块较大(比如数据缓冲区或比较大的结构),这时就可以使用指针传递地址而不是实际数据,既提高传输速度,又节省大量内存
- 为动态数据结构(二叉树、链表)提供支持
访问方式
数据访问⼀般分为直接访问和间接访问。
- 直接访问:直接访问内存单元中的内容。例如: a = 20; b = 2 * a等
- 间接访问:通过内存单元编号以及数据所占字节数访问内存中数据,指针是间接访问的常⽤⽅式
格式
使用
- 指针类型转换符:%p
- 取址运算符:&
- 取值运算符:*
- 指针变量定义时 ,*只起修饰作⽤,告诉编译器p是指针
- 指针变量取值时 ,*代表访问内存地址为p的存储区域
指针的算术运算,只有+-
//指针的类型决定一次移动几个字节,如int会移动4个,char会移动1个
int * p = &a;
p++;//向高位移动4个字节
p--;//向低位移动4个字节
指针与数组
数组:用连续内存空间存储数据的构造类型
数组名:数组元素首地址
int array[3] = {1,3,8};//array恒等于&array[0]
指针可以当数组名使用:
p[1] = 3;//恒等于a[1]、恒等于*(p+1)、恒等于*(a+1)
指针与数组的区别
- 所占空间不同:指针所占空间只于操作系统位数有关,64位系统中指针占8个字节,32位系统中占4个字节;数组所占空间与元素个数和类型有关。
- 数组名是常量地址不能重定向(不能赋值);指针可以重定向
指针与字符串
c语言使用字符数组保存字符串,数组名同时也是数组的首地址
char string[10] = “iPhone”;
char *p = string;
printf("string = %s\n",p);//打印字符串
printf("string = %c\n",*p);//打印字符串第一个字符
printf("string = %c\n”,*(p+1));//打印字符串第二个字符
指针数组:存放指针的数组
char *strings[3] = {“iOS", “Android", “Win8"};//可以⽤指针修改字符数组,但不可修改常量字符串
结构体指针:指向结构体变量的指针
结构体相当于变量,定义在main函数外,相当于是一个全局变量,定义在main函数内部是一个局部变量(作用域)
结构体指针定义
格式:结构体名 * 指针名 = &指向的那个结构体名
结构体指针访问成员:
(*p).sex ='m';
p->sex ='m';
//(*p)对指针取值后是结构体变量,.sex是访问成员变量
//使用指针可以直接访问结构体成员变量p->sex
结构体数组与指针
结构体数组的数组名是⼀个结构体指针常量
Stu stus[3] = {0};
Stu * p = stus;//p为结构体指针变量,stus为数组名
(p+i)->num;//使用指针p访问下标为i的元素的成员变量num
void printStudents(Stu * pstu, int count);//函数操作结构体数组时,需要传入首地址和元素个数
预编译指令
宏定义
- 预编译时进行替换
- 宏定义命名规则:纯大写或k+驼峰命名法;例:MAX 或 kMax
- 宏是常量
- 宏定义后面是没有 , 的
//普通宏
#define PI 3.1415926 //#define是宏定义指令,PI代表宏名,3.1415926是预编译时会被替换的内容
//带参数的宏
#define MUL(A,B) ((A)*(B)) //加括号是为了防止受操作符优先级的影响
条件编译:按不同的条件,编译不同的代码
//方式一:如果标识符被#define过,编译器编译带入代码段1,否则编译2
#ifdef 标识符
代码段1
#else
代码段2
#endif
//方式二:如果标识符未被#define过,编译器编译带入代码段1,否则编译2
#ifndef 标识符
代码段1
#else
代码段2
#endif
//方式三:如果标识符被#define过,编译器编译带入代码段1,否则编译2
#if 常量表达式
代码段1
#else
代码段2
#endif