C语言进阶之旅 (8)新老朋友指针

思维导图

在这里插入图片描述

指针是啥

  • 指针是变量,存变量的地址
  • 变量值在内存中,所以保存的也是内存地址
  • 可以通过地址到到内存中的值
  • 指针大小是(32平台4字节,64平台8字节)

例子

int a=0;//a是变量
//把a的地址个p
int *pa=&a;
*p=10//解引用就能找到a改变他的值

指针类型

  • char
  • short
  • int
  • float
  • long
  • double
  • 指针类型决定太可以访问多位,和能走多长
  • 指针是变量吗,那么他一定开辟了空间,不管类型都是(32平台/64平台)4/8

例子

 int arr=10;
 char *pa=&a;
 *pa=4;

步长

  • char(1字节)
  • int(4字节)
    -(16进制) 0-1-2-3-4-5-6-7-8-9-A(10)-B-C-D-E-F
int main()
{
	int a = 10;
	char* pa =(char*) &a;
	int* pb = &a;

	printf("%p\n", &a);
	//char
	printf("%p\n", pa);
	printf("%p\n", pa + 1);
	//int
	printf("%p\n", pb);
	printf("%p\n", pb + 1);
	return 0;
}

在这里插入图片描述


可操控位数

	int a = 11111111;
	char* pa =(char*) &a;
	int* pb = &a;
     *pa=3*pb=4

*pa的调试结果:

在这里插入图片描述
*pb的结果
在这里插入图片描述

其实类型多少步长就可以操作多少位数,而这个是看他的类型

拓展

  • 16进制
  • 0-1-2-3-4-5-6-7-8-9-A(10)-B-C-D-E-F
  • 16进制

指针初始化

  • 指针需要初始化,不然就是野指针
  • 指针=变量地址
  • 不在放啥时,空指针(指针=NULL)
int a=0;
int*p=&a;
int *P=NULL:

野指针

  • 野指针(指向的地方时随机,不受自己把控,非法访问内存)
  • 造成野指针:
  • 不初始化(那么就随机在内存找一块空间储存)
  • 数组越界
  • 变量释放
  • 好习惯
int *P;
*p=20;
rturn 0;

看编译器都跑不起来直接报错:

在这里插入图片描述

数组越界

int arr[]={1,2,3,4,5,6,7,8,9,10};
int i=0;
for(i=0;i<12;i++)
{
    arr[i]=0;
}

  • 这里数组就10个元素
  • 他越界了,把后面的也改了
  • 野指针

在这里插入图片描述
变量释放

test函数中返回了a的地址,你可以拿到那个地址,但是a是临时变量进函数创建,出函数就释放,所以你现在指向的是,就是野指针,那块空间不属于你

在这里插入图片描述

编程好习惯

  • 每次用完的给他初始化成NULL(空指针)
  • 但是有时候指针太多你会忘了他是不是,加个判断
  • 每次看好数组元素个数在写条件,或用sizeof/strlen求
if*P!=NULL//不是空指针就进入
条件

指针运算

  • 指针加减整数
  • 指针比大小
  • 指针减指针


    指针加减整数
int arr[]={1,2,3,4};
int *p=arr;//数组的地址是数组名
for ( i = 0; i < 3; i++)
{
*p++=0}

结果:

在这里插入图片描述

指针-指针

  • 得到元素个数
  • arr[9]-arr[0]=10-1=9
  • 俩指针必须指向同一块空间
int arr[]={1,2,3,4,5,6,7,8}
printf("%d",&arr-&arr[9]);

结果
在这里插入图片描述
使用场景:
模拟实现strlen


指针比大小

	int arr[] = {1,2,3,4,5,6};
	int* pa = arr;
	int sz = sizeof(arr) / sizeof(arr[0])-1;
	int* pb = arr + sz;
	while (pa<pb)//这里pa和pb比
	{
		printf("%d", *pa);
		*pa++;
	}
}

二级指针

  • 有俩层指向关系
  • 指针就1层
  • (3……)级同理,多少层就有多少指向关系
  • 暂时我看来用到的比较少
int a =0;
int *p=&a;//他指向了int a
int **pa=&p;//他指向了p,然后也指向了a;

你想二级里面是不是放这p的地址,而p的里面放的是a的地址,那么我是不是就可以通过解引用pa找到p然后在找到a

指针和数组

  • 数组的数组名就是地址
  • 那么取地址就等于获得首元素地址
  • 那么我就可以用指针来访问数组,
int main()
 {
         int arr[] = {1,2,3,4,5,6,7,8,9,0};
          int *p = arr; //指针存放数组首元素的地址
          int sz = sizeof(arr)/sizeof(arr[0]);
           for(i=0; i<sz; i++)
           {
       printf("&arr[%d] = %p<====> p+%d = %p\n", i, &arr[i], i, p+i);
           }
      return 0;
 }

后面同理的:
在这里插入图片描述

指针数组

  • 存的是指针的数组
  • 整型数组里面的整型变量的集合
  • 字符数组就是字符变量的集合
  • 那指针就是存指针变量的集合

在这里插入图片描述

总结

  • 指针,现在总体看还是比较简单,但是简单就是基础,好好打地基,然后造高楼
  • 还是多敲代吗多用,就懂了,熟能生巧

本篇文要是那里有错,请大胆指出(评论区或加我QQ(1696912943,给我留面哈哈哈)),博主,钱包不厚,不过脸皮厚,所以不会伤到博主自尊心,你提出错误,博主就涨知识哈哈哈!!!!

持续更新…………

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值