C语言指针(大白话+图文聊指针)

提示:这篇文章连接性很高,建议从头看到尾,如果觉得文章不好,不用浪费时间,建议跳过找到适合自己的文章去看
致读者-谢谢阅读


一、指针

前言:c语言的指针在学习中确实比较难,指针是C语言它强大的原因,因为可以访问到电脑内存的任何地方


二、什么是指针?

指针就是一个地址,当int a = 10 ; int * p = &a; 时候,就把a的地址取出来给了p存着。p是指针,所以说指针就是地址一点也不过,就像int a = 10; a 是整数一样。p也叫指针变量。


三、指针的定义以及初始化

int main()
{
因为指针是存地址的,要接收地址值,地址值怎么来,请看下面
	int a = 0;
	int* p;	//这是指针的定义 
//&是取地址符号,像普通的数据类型:int,float,char,double是需要用取地址符号去取值的
	p = &a; //这是指针的赋值 
	return 0;
}

总结:

  1. 指针赋值一定要赋予地址值,并不可以赋值一个数字或者其他的。
  2. 指针也是一个变量,所以也要内存去存指针是这样存储的 在这里插入图片描述
    指针变量p也有空间,所以p指针他的存放地址存在了BFDAC7里面了,然后p的空间用来存A的地址AFED05了

四、指针的取值

指针有存值也有取值 *p就是取值方式

int a = 10;
int *p = &a;
printf("%d\n",*p);//10

五、指针的大小

指针的大小是看系统多少位而定的,与他是指针的数据类型(int ,float, char等)无关
如果是32位的系统则为4个字节,64位的系统则位8个字节
在这里插入图片描述


六、指针的大小(有趣)

#include <stdio.h>

int main(){
	char str[100] = {"woshiyigehaoren"};
    //用int指针去读char类型数据
	int *p1 = str;
	char *p2 = str;
	printf("%c\t %c\n",*(p1+1),*(p2+1));
	printf("%p\t %p\n",p1,p1+1);
	printf("%p\t %p\n",p2,p2+1);
	return 0;
}

在这里插入图片描述

由结果可以看出,不管你指针是什么类型,你都可以指向其他类型的数据,前面的int 类型 和 char类型,float只是代表这个指针的读单元的长度,int就一下子走4个字节的长度,float就一下子走8个字节,char一下子走1个字节,然而像结构体这样的数据类型,那就只能看结构体里面占多少长度了。


七、野指针

野指针:不知道他指向哪里,指向了什么(比较危险)

野指针的产生

1. 指针的未初始化他的指向一无所知
#include <stdio.h>

int main(){
	int arr[10] = {1,2,3,4,5,6,7,8,9};
	float *p = NULL;
	int *p1;
	char *p2;
	printf("%p\n",p);
	printf("%p\t %p\n",p1,p2);
	return 0;
}

在这里插入图片描述

2.指针越界访问也会变成野指针
3. 指针指向的空间释放
#include <stdio.h>

int* demo( )
{
	int a = 5;
	return &a;
}
int main()
{
	int* p = demo();
	return 0;
}

看图说明在这里插入图片描述

野指针的避免

如果野指针不幸指向了你自己玩的QQ的内存了,他做出的操作都是未知的,或者说QQ程序的停止运行,或者是其他的问题所以怎么产生野指针,就该怎么规避野指针的问题,加多点指针的判断或者及时设置为NULL很有必要

八、二级指针(指针的指针)

指向指针的指针,那就是二级指针
看图就懂了
在这里插入图片描述

int main()
{
	//这里的%X是输出十六进制地址,当打印指针的时候,那就是打印指针里面的值,
	//像用%d打印a一样,打印的是a的值 
	int a = 10;
	int* p = &a; //指针的赋值 
	int* p1 = &p;
	printf("%X\n",&p); //62FE08
	printf("%X\n",p1); //62FE08
	printf("%X\n",&a); //62FE14
	printf("%X\n",p);  //62FE14
	return 0;
}
  1. 是不是你承认了这个int *p1就是二级指针了,虽然原理是这样,但是定义的时候不应该这样定义。
  2. 按照现在错误的做法是:*p1 得到的是 p里面的值,如果**p1那就得到了 *p的值也就是a = 10; 这样的想法没毛病,但是他作为一个一级指针,使用二级的时候会报错,在dev++中输出结果时强制停止了我的做法。所以正确的做法是
  3. 用int **p
    在这里插入图片描述

总结:

  1. 二级指针他必须存的是指针的地址,不可以存其他变量的地址
  2. 如果这个是一个二维数组arr[i][j],那么也可以存二维数组的arr[i]的地址(若不懂请看我的C语言数组的深度分析)

九、指针函数与指针作为参数

返回指针的函数(在数据结构与算法中常见) 先看代码

int* init(int* p)
{
	p = (int *)malloc(sizeof(int));//开辟一个4个字节大小的空间,把该空间强转为int类型
	if(p == NULL){
		//开辟空间失败 
		return NULL;
	} 
	return p; 
}
int main()
{
	int *p = NULL;
	p = init(p);
	return 0;
}

总结

  1. 像指针作为参数,其实就是把指针指向的值传给函数的形参接收,最后对该地址的值进行操作
  2. 在这里,init§ 就是把p指向的地址值传给init的函数,然后int *p = 地址值 被形参接收
  3. 指针函数,返回的是指针,就像int函数一样,最后return是返回对应类型的值

十、数组相关

以下的内容如果有需要,可以去查看我的这个链接(不用全部看完直接跳到相关的即可)
点击查看与数组相关的指针内容

1.数组指针
2.指针数组
3.数组作为参数传递(类似指针)

十一、结构体相关

以下的内容如果有需要,可以去查看我的这个链接(不用全部看完直接跳到相关的即可)
点击查看与结构体相关的指针内容

1.结构体指针

  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值