06.C语言——指针


一、指针及其大小

1.指针就是地址
指针变量就是存放指针的变量(所谓的指针)

2.指针大小
32位平台:4字节
64位平台:8字节

二、指针类型

意义:
1.指针类型决定了:指针解引用的权限有多大

int a=0x11223344;
int b=0x11223344;
int *pa=&a;
char*pb=&b;


*pa=0;  a的内容全部改为0
*pb=0;  b的第一个字节改为0    00223344

2.指针类型决定了:指针走一步,能走多远(步长)

int arr[]={1,2,3,4};     假设首地址是0x0057FB80;
int *parr=arr;
printf("%p\n",parr+1);   结果:0x0057FB84
char *parr1=arr;
printf("%p\n",parr1+1);  结果:0x0057FB81

三、野指针

野指针:指向的位置是不可知的(随机的、不正确的、没有明确限制的)

1.产生野指针的原因
①指针未初始化
②指针访问越界
③指向的指针释放

2.如何避免野指针
①指针初始化
②小心指针越界
③指针指向空间释放,即使置NULL
④指针使用之前检查有效性

四、指针运算

1.指针±整数

2.指针-指针
指向同一块空间的两个指针相减,得到两个指针之间的元素个数

五、指针和数组

六、二级指针

存放一级指针(指针变量)地址的指针

int a=10;
int *pa=&a;        拿到a的地址
int* *ppa=&pa;     ppa是一个地址(*ppa)  存放的是整型指针(int**ppa;              拿到pa的地址
**ppa=20;          可以访问pa指向的地址的内容

七、指针数组

指针数组:本质是数组,存放指针(指针变量)的数组

int a=1;
int b=2;
int *pa=&a;
int *pb=&b;
int* arr[2]={pa,pb};     arr是一个数组,元素个数2个   元素类型为 int* 的指针

应用场景:二维数组

int arr1[]={1,2,3};
int arr2[]={4,5,6};
int arr3[]={7,8,9};

int * parr[]={arr1,arr2,arr3};
int i=0;
for(i=0;i<3;i++){
	int j=0;
	for(j=0;j<3;j++){
		printf("%d ",*(parr[i]+j));         == printf("%d ",parr[i][j]);
	}
	printf("\n");

}


八、const

int a=10;
int b=20;
const int * pa=&a;        const*的左边,修饰的是*pa   即不能*pa远程修改内容,但是可以修改pa的值
*pa=10;  err
pa=&b;

int * const pa1=&a;  const*的右边,修饰的是pa1  即不能修改pa的值,但是可以*pa远程修改内容
*pa1=30;   
pa1=&b;err


九、字符指针

char c='t';
char * pc=&c;

本质是把这个字符串的首字符h的地址存放在*str中
char * str="hello";
printf("%c\n",*str);     结果:输出h4

笔试题

在这里插入图片描述

十、数组指针

数组指针是一个指针,指向的是一个数组的地址

int arr[5]={1,2,3,4,5};
int (*parr)[5]=&arr;            *parr是一个指针,指向的是一个数组,数组元素个数5个,元素类型int

double * d[5];
double * (*pd)[5]=&d;            *pd是一个指针,指向的是一个数组,数组元素个数5个,元素类型double *

应用

void Print(int (*parr)[3][3],int r,int c){
	int i=0;
	for(i=0;i<r;i+){
		int j=0;
		for(j=0;j<c;j++){
			printf("%d ",*(*(parr+i)+j));
		}
		printf("\n");
	}
};

int arr[3][3]={{1,2,3},{4,5,6},{7,8,9}};
Print(arr,3,3);

十一、数组名

&数组名表示的是数组的地址,而不是数组首元素的地址
&数组名1,跳过的是整个数组

十二、函数指针

指向函数地址的指针

void Print(int a){
	printf("%d\n",a);
}

定义
void (*pPrint)(int)=&Print;
void (*pPrint1)(int)=Print;

调用
pPrint(10);
(*pPrint)(10);

十三、函数指针数组

也叫转移表
存放函数指针的数组

void Print(int a){
	printf("%d",a);
}

void (*pPrint)(int)=Print;
void (*pPrint1)(int)=Print;

void (*pPrintarr[2])(int)={pPrint,pPrint1};

十四、指向函数指针数组的指针

是一个指针,指向的是一个数组,数组元素都是函数指针

void Print(int a){
	printf("%d\n",a);
}

void (*pPrint)(int)=Print;
void (*pfarr[2])(int)={Print,Print};
void (*(*ppfarr)[2])(int)=&pfarr;

十五、回调函数

是通过函数指针调用的函数。把一个函数指针作为参数

总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值