一丶认识指针/为什么要学习指针
[需求]编写自定义函数func,将main函数中的两个整形变量的值交换
void func(int a,int b)
{
//交换传进来的a,b的值
int temp=a;
a=b;
b=temp;
}
int main(int argc, const char * argv[])
{
int a=10,b=20;
func(a,b);
printf("%d %d\n",a,b);//10 20
return 0;
}
[注]指针是为了帮助我们实现跨内存访问
二丶指针的定义
类型符*指针变量名;
例子:int *i;
[注]指针变量中存的是地址
三丶指针的初始化
[注]刚定义出来的指针变量,如果不进行初始化,指针变量的值是不确定的,我们称这样的指针为“野指针”
int a;
int *i = &a;//这里是定义一个指针变量i,同时给i赋值为&a
//一旦指针变量i中存有一个地址,i就指向了a
//一旦指针变量i指向了普通变量a,就可以通过i来访问a中的数据
*i //取出i指向的a中的数据
*i = 20 //改变i指向的a中的数据
四丶指针的赋值
int a,b;
int *ppi = &a; //ppi指向了a
ppi = &b; //ppi指向了b
[注]指针变量的赋值,是为了改变指针变量的指向
[注]通过对指针变量取*,可以访问指针变量所指向的内存单元的数据,所访问数据的内存单元大小是由指针本身的类型决定的
五丶指针变量所占内存大小
int *p1;
char *p2;
double *p3;
printf("%ld\n",sizeof(p1));//8
printf("%ld\n",sizeof(p2));//8
printf("%ld\n",sizeof(p3));//8
//在64位系统下,不同类型的指针变量占8字节内存
//在32位系统下,不同类型的指针变量占4字节内存
六丶指针和函数——指针变量要作为函数的参数
[指针作为函数参数]如果需要在一个函数中访问另一个函数中的数据,这是就需要使用指针(传入数据的地址,用一个指针变量接收)
void foo(int *a)//a=&b
{
printf("%d\n",*a);
*a=20;
}
void main(void)
{
int b;
foo(&b);
}
七丶指针和数组
1.指针加1
[注] 指针变量加1,实际是加了指针变量的类型所对应字节数
2.指针和数组的关系
int a[10]={1,2,3,4,5,6,7,8,9,10};
int *p;//这是个野指针
p=a;//一旦数组名赋值给指针变量,指针变量就可以当数组名使用(指针变量中存的是数组首元素的地址)
//数组名,代表数组中首元素的地址
//a==&a[0]
数组传参,数组名作为参数传参,需要通过指针变量接收
数组传参
(1)数组传参,可以用一个指针变量接收
void pri(int *p)
(2)数组传参,也可以用一个数组接收,但是在函数内部,数组名会立即退化成指针变量
void pri2(int ap[100])//参数部分,数组大小没意义
int ap[100] 可以理解成 int *ap
[注] 以上两种接收方式,都无法知晓数组中元素的个数,必须在传入数组名的同时传入数组元素的个数
void pri(int *p,int n)
void pri2(int ap[],int n)
[注] 在函数中返回一个数组名,需要用指针类型的返回值类型
例如:返回一个 int a[10];
int * fun(void)
{
int a[10];
return a;
}
八丶const关键字修饰指针
const关键字可以修饰变量(普通变量,指针变量)
const修饰普通变量,被修饰的普通变量 就变为常量(不能直接通过赋值语句修改变量的值)
int const a;//a成了常量
const int a;//a成了常量
a=10;//错
//const修饰的普通变量,变为“只读”变量
const修饰指针变量,被修饰的指针变量有两种情况
int *const pi;(锁定的是地址)//因为const直接修饰的是pi,所以pi不能变,但是*pi可以变
pi=&b;//错
*pi=100;//对
int const * pi;(锁定的是值)//因为const直接修饰*pi,所以*pi不能变,但是pi可以变
九丶高级指针用法
1.数组指针
int (*arr)[4];
//这是一个数组指针,指针名为arr,用来指向一个数组(int[4])
//数组首元素的地址&array[0]或者array
//数组的首地址&array
arr=&array;
[注] 数组指针常和二维数组配合使用
2.指针数组
//用来批量定义指针变量
int *arr[4];
//这是一个数指针数组,数组名为arr,数组arr具有4个元素,每个元素是一个指针变量(int*)
//arr[0],arr[1],arr[2],arr[3]
3.函数指针
[注] 函数指针,本质还是一个指针,是用来指向一个函数的指针
//定义一个函数指针
int (*p)(int);
//这是一个指针变量p,用来指向一个函数,这个函数必须是返回值类型为int,带有一个int参数的函数
p=foo;//将函数foo的首地址存入函数指针变量p中
//使用p调用存储在p中的函数
p(10);
[需求] 保存10个函数的首地址,需要定义函数指针数组
int (*p)(int)[10];
p[0]=foo;
p[1]=func;
......
4.二级指针
int ** pp;//定义了一个二级指针pp,用来指向一个一级指针的
//[需求]--[访问]一级指针变量所在内存单元的数据
//需要使用 二级指针pp来访问一级指针变量p的数据
// 可以使用二级指针变量 改变 一级指针变量 中存的地址(oc中会用到)
int a=10;
int *p=&a;
pp=&p;//二级指针变量pp指向一级指针变量p
*pp=&b;//通过二级指针变量pp修改 所指向的一级指针变量p 中存的地址(让一级指针变量p指向变量b)
网友评论