C语言之指针

指针
一,指针是什么
1,地址与指针
地址指向变量单元
地址形象化地称为“指针”


2,间接访问与直接访问
直接按变量名进行的访问,称为“直接访问”方式
将变量的地址存放在另外一个变量中,然后通过该变量来找到此变量地址,进而访问此变量,称为“间接访问”


3,指针和指针变量
一个变量的地址称为该变量的“指针”
一个变量专门用来存放另一个变量的地址,称为指针变量。指针变量的值是地址


二,指针变量
1,定义指针变量
类型名 *指针变量名
例:int *pointer_1,*pointer2;


1),指针变量前面的“*”表示该变量的类型为指针型变量。指针变量名是pointer_1和pointer_2,而不是*pointer_1和*pointer_2
2),在定义指针变量时必须指定基本类型
3),指向整形数据的指针类型表示为“int*”,读作“指向int的指针”或简称“int指针”
4),指针变量中只能存放地址(指针),不要将一个整数赋给一个指针变量。


2,引用指针变量
1)给指针变量赋值
p = &a;
这时指针变量p的值是变量a的地址,p指向a。
2)引用指针变量指向的变量
printf("%d",*P);
其作用是以整数形式输出指针变量p所指向的变量的值,即变量a的值
*p = 1
3)引用指针变量的值
printf("o%",p);
作用是以八进制数形式输出指针变量p的值,如果p指向了a,就是输出了a的地址。即&a


3,两个有关的运算符
1)& 取地址运算符。&a是变量a的地址
2)* 指针运算符(或称“间接访问”运算符),*p代表指针变量p指向的对象


4,指针变量作为函数参数(重要)
指针变量作为函数参数作用是将一个变量的地址传送到另一个函数中


main(){
swap(pointer_1,pointer_2)
}


void swap(int *p1,int *p2){
   int temp;
   temp = *p1;
   *p1 = *p2;
   *p2 = temp;
}
交换a和b的值,而p1和p2的值不变




main(){
swap(pointer_1,pointer_2)
}


void swap(int *p1,int *p2){
   int *temp;
   temp = p1;
   p2 = p1;
   p1 = temp;
}
结果:未能实现如期的交换
分析:
A,C语言中实参变量和形参变量之间的数据传递是单向的“值传递”方式。使用指针变量作为函数参数时同样要遵循这一规则。不可能通过执行调用函数来改变实参指针变量的
值,但是可以改变实参指针变量所指变量的值。
B,函数的调用可以仅且可以得到一个返回值,而使用指针变量作参数,可以得到多个变化了的值。


三,通过指针引用数组
1,数组元素的指针
1)指针可以指向变量,也可以指向数组元素。所谓数组元素的指针就是数组元素的地址
2)数组元素的引用可以使用下标法,也可以使用指针法
3)在C语言中,数组名(不包括形参数组,形参数组不占据实际的内存单元)代表数组中首元素的地址。需要注意的是数组名不代表整个数组,只代表数组首元素的地址。
p = &a[0]
p = a;


int *P = &a[0];


2,通过指针引用数组元素
1)下标法,例如a[i]的形式
2)指针法,如*(a+i)或*(p+1),a是数组名,p是指向数组元素的指针变量


3,数组名作为函数参数
C语言调用函数时虚实结合的方法都是采用“值传递”方式,当用变量名作为函数参数时传递的是变量的值,当用数组名作为函数参数时,由于数组名代表的是数组首元素地址
,因此传递的值是地址,所以要求形参为指针变量
例如存在一个数组a,则a[i]和*(a+i)无条件等价的
注:实参用数组名,形参可用数组名,也可用指针变量名。


4,通过指针引用多维数组(以二维数组为例)
1)二维整形数组int a[3][4],a数组包含3行,即3行元素:a[0],a[1],a[2],而每一行元素又是一个一维数组,它包含4个元素。
可以认为二维数组是“数组的数组”,即二维数组a是由3个一维数组所组成的
2)a[0],a[1],a[2]既然是一维数组,而C语言又规定类数组名代表数组首元素地址,因此a[0]代表一维数组a[0]中第0列元素的地址,即&a[0][0]
3) a[0]+1代表a[0][1]元素的地址
4)a[0]和*(a+0)等价,a[1]和*(a+1)等价,a[i]和*(a+i)等价。因此,a[0]+1和*(a+0)+1都是&a[0][1]。注意*(a+0)+1和*(a+0+1)不是同一个地址
分析:a[0]的内容是一个地址,那么a是二维数组首元素地址。那么*(a+0)是地址的内容,所以相等
5)*(a[i]+j)与*(*(a+i)+j)是a[i][j]的值
6) 非常重要:*(a+i)和a[i]是等价的,都是地址
7)a+1和*(a+1)是一样的
注:不要把&a[i]简单理解为a[i]元素的物理地址,因为不存在a[i]这样一个实际的数据存储单元。它只是一种地址的计算方法,能得到第i行的首地址,&a[i]和a[i]的值
是一样的
5,指向多维数组元素的指针变量


四,通过指针引用字符串
1,字符串的引用方式
1)%s
2)%c


char string[]="I love China!";
printf("%s\n",string);
printf("%c\n",string[7]);


2,字符指针的定义
char *string = "I love China";
printf("%s\n",string);
C语言中对字符串常量是按字符数组处理的,在内存中开辟了一个字符数组用来存放该字符串常量,但是这个字符数组是没有名字的,因此不能通过数组名来引用,
只能通过指针变量来引用
对字符指针变量string初始化,实际上是把字符串第1个元素的地址赋给了指针变量string,使string指向字符串的第1个字符


注:字符串的定义
正确的
char *string = "I love China"
char *string;
string = "I love china"


错误的
char *string;
*string = "I am a student";


3,字符指针作函数参数
函数的形参和实参可以分别用字符数组名或字符指针变量


4,使用字符指针变量和字符数组的比较


五,函数指针
1,什么是函数指针
程序中定义了一个函数,在编译时,编译系统为函数代码分配一段存储空间,这段存储空间的起始地址(又称入口地址)称为这个函数的指针
定义如:int (*P)(int,int)


2,用函数指针变量调用函数
main(){
  int max(int,int);
  int (*p)(int,int);
  p=max;
  int c=(*p)(a,b);
}


int max(int x,int y){


}


类型名(*指针变量名)(函数参数表列);


3,用指向函数的指针作函数参数
指向函数的指针变量的一个重要用途是把函数的地址作为参数传递到其他函数


六,返回指针值的函数
定义返回指针值的函数的一般形式为:
类型名 *(函数名)(参数列表);


七,指针数组
1,什么是指针数组
一个数组,若其元素均为指针类型数据,称为指针数组
2,定义形式
类型名 *数组名[数组长度]
例如:int *p[4] //[]优先级高于*
下面的定义是错误的
int (*p)[4];//这是指向一维数组的指针变量
3,适用场合
指针数组比较适合用来指向若干个字符串,使字符串处理更加方便灵活


4,指向指针数据的指针
指向指针的指针----指向指针数据的指针变量


八,内存分配函数





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值