c语言 指针 (7.25)

一、指针是什么

插图 1‘40’‘

电线控制电信号—转换数字信号产生二进制序列

在这里插入图片描述
在这里插入图片描述

二、指针和指针类型

指针类型的意义

1、
指针类型决定了指针进行解引用操作时,能访问空间的大小
int* p;*p 能够访问4字节
char
p;*p能够访问1字节(只认为p是字符)
double
p ;*p能访问8字节

int main()             
{
	printf("%d\n",sizeof(char*));                 //都是存放地址,32位下,都是4字节
	printf("%d\n",sizeof(short*));
	printf("%d\n",sizeof(int*));
	printf("%d\n",sizeof(double*));
	printf("%d\n",sizeof(float*));
	return 0;
}

2、
指针类型决定了,指针走一步走多远(指针步长),单位字节。
int* p;p+1(访问下一个整型)–>4个字节(间隔)
char* p;p+1–>1个字节
double* p;p+1–>8个字节

三、野指针

1、概念:

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

2、成因:

(1)指针未初始化,(局部变量不初始化,默认随机值)

局部指针变量,被初始化为随机值
(犹如流浪者,想睡哪睡哪)

int main()
{
	int a;//局部变量不初始化也默认为是随机值
	int* p;//局部指针未初始化,默认是随机值
	*p =20;
	return 0;
}

(2)指针越界访问

(喝了假酒,住了别人家的房子)

int main()
{
	int arr[10]={0};
	int* p=arr;
	int i=0;
	for(i=0;i<10;i++)
	{
		*(p++)=i; //指针范围超出数组范围时,p就是野指针
	}
	return 0;
}
int main()
{
	int a[10]={0};
	int* p=a;
	for(i=0;i<=12;i++)
	{
		*p=i;
		 p++;   //p为指针
		//上述两行代码等价于*p++;
	}
	return 0;
}

(3)指针指向的空间释放

(就像 之前是自己的房子,要住的时候突然成别人的了)

int* text()
{
	int a=10;  //局部变量,出作用域自动销毁
	return &a;
}

int main()
{
	int* p=test(); //a仅仅为局部变量,超出范围自动销毁,所以找不到该空间
	*p =20;
	return 0;
}

3、如何避免野指针

(1)指针初始化

把某值的地址给它
不知道给什么指针时,赋予空指针(NULL)

int main()
{
	int a=1;
	int b=10;
	int* pa=&a;  //初始化
	int* p=NULL; //不知道赋值什么的时候一种方法,空指针
	return 0;
}

(2)小心指针越界

(3)指针指向空间释放,可使其置为NULL

(4)指针使用前检查有效性

四、指针运算

1、指针±整数

用来改变要访问的地址

举例:用指针来访问数组

int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int i=0;
	//int sz=sizeof(arr)/sizeof(arr[0]);          不清楚元素个数时,可以使用
	int* p=arr;
	for(i=0;i<10;i++)
	{
		printf("%d\n",*p);
		p++;
	}
	return 0;
}

int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int i=0;
	//int sz=sizeof(arr)/sizeof(arr[0]);          不清楚元素个数时,可以使用
	int* p=arr;
	for(i=0;i<5;i++)
	{
		printf("%d\n",*p);
		p+=2;    //只访问1,3,5,7,9(每次间隔2个)
	}
	return 0;
}

int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	int i=0;
	//int sz=sizeof(arr)/sizeof(arr[0]);          不清楚元素个数时,可以使用
	int* p=&arr[9];  //将最后一个元素放入p中
	for(i=0;i<5;i++)
	{
		printf("%d\n",*p);
		p-=2;    //倒序访问(因为将数组的最后一个元素放入,且-=2,每次左移)10,8,6,4,2(每次间隔2个)
	}
	return 0;
}

2、指针-指针

得到的是两指针中间的元素个数(大地址-小地址)
中间元素个数有问题,可以理解为两地址间的距离

小地址-大地址)的绝对值两地址间的距离

不同类型的指针不可相减(例如,char指针和int指针不可相减),否则得到的是不可预知的值

int main()
{
	int arr[10]={1,2,3,4,5,6,7,8,9,10};
	printf("%d\n",&arr[9]-&arr[0]);
	
	return 0;
}

实用方法:求字符串的长度

int my_strlen(char* str)
{
	char* start =str;
	char* end =str;
	while(*end!='\0')
	{
		end++;
	}
	return end-start;    
}

int main()
{
	char arr[]="bit";
	int len=my_strlen(arr);
	printf("%d\n",len);
	return 0;
}

3、指针的关系运算

指针比较大小(指针的关系运算)

类似for循环的判定

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

五、指针和数组

数组可以通过指针来访问

//关于数组名
int main()
{
	int arr[10]={0};
	printf("%p\n",arr);  //地址-首元素地址
	printf("%p\n",&arr[0]);
	retuurn 0;
}
int main()
{
	int arr[9]={0};
	int* p=arr;
	int i=0;
	for(i=0;i<10;i++)
	{
		*(p+i)=i;   //放入整型元素
	}
	for(i=0;i<10;i++)
	{
		//printf("%d\n",arr[i]);  //输出整型元素
		printf("%d\n",*(p+i));//输出整型元素 ,两者输出相同
	}
	return 0;
}

六、二级指针

int main()
{
	int a=1;
	int* pa=&a;
	int** ppa=&pa;//ppa为二级指针
	int*** pppa=&ppa;//pppa为三级指针
	**ppa=20;   //**ppa即为a的值
	printf("%d\n",**ppa);
	printf("%d\n",a);   //和上方输出内容相同
	return 0;
}

七、指针数组(本质是数组)

指针数组(用来存放指针的数组)

int main()
{
	int a=10;
	int b=20;
	int c=30;
	int i=0;
	int* arr2[3]={&a,&b,&c};  //指针数组
	for(i=0;i<3;i++)
	{
		printf("%d\n",*(arr2[i]));  //通过对地址解引用操作可得a,b,c的值,arr2[i]就是地址
	}
	return 0;
}

整型数组(用来存放整型)
字符数组(用来存放字符)

数组指针(本质是指针)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值