7、指针的赋值
注意:在给指针赋值时,要注意类型匹配
int a;
int *p = &a;//&a的数据类型 int *
p:变量 &a:常量
也就是p可以++,&a不能++
&a = &b;//error
p = &b;
案例:实现两个数的交换
值传递:
总结:结果并未发生改变,子函数在程序运行完之后自动将空间释放
地址传递:
8、空指针
没有指向的指针(值为0的指针,就认为该指针没有指向)
值为0的指针用NULL表示
注意:0号地址禁止操作
要操作就要改变指向,如下图所示
9、野指针
不知道指向哪里的指针
局部变量没有初始化的时候,值为随机值
局部指针变量没有初始化就是野指针
如何避免野指针的出现?初始化为NULL
注意:在32OS,所有的指针占4个字节
2、简易计算器
二级指针
二维数组:数组的数组
二级指针:指针的指针
二级指针变量的内存空间存的是一级指针的地址
定义一级指针:
存储类型 数据类型 * 指针变量名;
数据类型:指针所指向的数据类型
二级指针的定义:
二级指针所指向的数据类型:数据类型 *
存储类型 数据类型* * 指针变量名;
注意:
- 指针类型就是将变量名去掉,剩下的就是数据类型
int *p;//数据类型 int *
int **pp;//数据类型 int **
- 指针所指向的数据类型,将(*指针变量名)去掉,就是指针所指向的数据类型
char *p;//指针指向的数据类型 char
char **p;//指针指向的数据类型 char *
char ***p;//指针所指向的数据类型 char **
3、*p所能访问的空间的大小,由p指向的数据类型来决定
char *p;*p所能访问的内存空间的大小为1
int *p;*p所能访问的内存空间的大小为4
int **p;**p所能访问的内存空间的大小为4
指针与一维数组
1、指针的算术元素
总结:
p+n: p+n相对于p向地址增大的方向移动了n个数据
实际的变化 p + sizeof(数据类型)*n
p-n:p-n相对于p向地址减小的方向移动了n个数据
实际的变化 p – sizeof(数据类型)* n
p++:p向地址增大的方向移动1个数据
p--: p向地址减小的方向移动1个数据
p – q;(p和q的数据类型必须一致)这两个指针之间相隔的数据的个数
实际的变化 (p - q)/ sizeof(数据类型)
注意:指针的算术元素只有在操作连续内存空间的时候才有意义
数组名是一个地址常量
p是指针变量,以上这个方法也适用与指针常量,但是++、--除外
为什么数组名[下标]就可以访问数组中的元素
数组名的含义:
- 数组首元素的地址,地址常量,不能对它进行++、-- 类型:数据类型 *
- 代表整个数组 sizeof(arr)/ sizeof(arr[0]);
2、通过指针常量来访问:
指针常量错误案例:
3、通过指针变量来访问
4、访问数组元素
总结:
数组名和指针变量有本质区别:数组名是指针常量,指针是指针变量
指针指向没有发生改变:
指针指向发生改变:
1、求字符串数组的长度
2、实现字符串的拷贝
3、实现字符串的连接
4、求字符串中有几个空格
指针与二维数组
总结:
1、a、&a[0]、&a[0][0]的值是一样的,但是表示的意义不同
a:int(*)[3]:指向一维数组的指针 &a[0]:int * &a[0][0]: int
2、a+1移动了一个数组(12个字节),如果是int **,+1移动四个字节
3、a指向a[0],a[0]又是一个一维数组,所以a指向了一个一维数组
数组指针与指针数组
数组指针:
数组指针:指向数组的指针
1、定义
存储类型 数据类型 (*指针变量名)[元素个数];
int (*p)[3];
存储类型:auto、register、static、extern
数据类型:所指向数组的元素的数据类型
指针的数据类型:数据类型(*)[元素个数];
指针指向的数据类型:int ()[3];
元素个数:所指向的数组中元素的个数
注意:[ ]的优先级比*的优先级高,所以变量名先和谁结合就是什么数据类型
指针+1:移动一个数组
int a[3] = {1,2,3};
int (*p)[3] = &a;//几乎不用,更多的是用来访问二维数组,因为指针访问连续的存储空间才有意义,此时p+1越界
2、数组指针与一维数组之间的关系
指针数组:元素类型为指针的数组
定义:
存储类型 数据类型 *数组名[元素个数];
int *p[3];
p:是数组名,它里面有3个int *类型的元素
案例:
int a[2][3] = {1,2,3,4,5,6}; (指针数组)
char str[20] = “hello”;//编译器分配了20个字节的空间,存放“hello”
str[3] = ‘b’;
char *p = “hello”; p存储在栈区 ,“hello”是字符串常量,存在常量区,所以不能该
*p = k;//error 因为“hello”存储在常量区,不能被修改
思考?
char str[20] = {0};
str = “hello”; //error str是常量
char *p = NULL;
p = “hello”;
char *p[3] = {“hello”,”hi”,”nice”};
p[0]代表的是“hello”的地址
const修饰的指针
const:只读
const是用来修饰常量的 //error
用来修饰变量,使用const修饰的变量只读(不能修改)
int a;//存在栈区
const int a //存在栈区