C C++最新【C语言】【指针】,36岁老码农现身说法

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  1. 虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可行的
  2. 我们通过取地址操作符( & )拿到地址
  3. 我们只要拿到了地址(指针),就可以通过地址(指针)找到地址(指针)指向的对象,这⾥必须学习⼀个操作符叫解引⽤操作符( * )
int a=12; int b; int \*p; int \*\*ptr;
p=&a; //&a 的结果是一个指针,类型是int\*,指向的类型是
//int,指向的地址是a 的地址。
\*p=24; //\*p 的结果,在这里它的类型是int,它所占用的地址是
//p 所指向的地址,显然,\*p 就是变量a。
ptr=&p; //&p 的结果是个指针,该指针的类型是p 的类型加个\*,
//在这里是int \*\*。该指针所指向的类型是p 的类型,这
//里是int\*。该指针所指向的地址就是指针p 自己的地址。
\*ptr=&b; //\*ptr 是个指针,&b 的结果也是个指针,且这两个指针
//的类型和所指向的类型是一样的,所以用&b 来给\*ptr 赋
//值就是毫无问题的了。
\*\*ptr=34; //\*ptr 的结果是ptr 所指向的东西,在这里是一个指针,
//对这个指针再做一次\*运算,结果是一个int 类型的变量。

指针的大小

在这里插入图片描述
我们可以简单理解,32位机器( X86 )有32根地址总线,每根线只有两态,表⽰0,1【电脉冲有⽆】,那么⼀根线,就能表⽰2种含义,2根线就能表⽰4种含义,依次类推。32根地址线,就能表⽰2^32种含义,每⼀种含义都代表⼀个地址。
同理64位机器( X64 )

由此可得

  • 32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。
  • 同理64位机器,假设有64根地址线,⼀个地址就是64个⼆进制位组成的⼆进制序列,存储起来就需要8个字节的空间,指针变的⼤⼩就是8个字节

指针运算

  • 指针 ± 整数
    因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺藤摸⽠就能找到后⾯的所有元素,例下述例子。指针每加1实质上是往后移这个指针类型大小的字节数,具体情况可看下一个例子。
#include <stdio.h>
//指针+- 整数
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int \*p = &arr[0];
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
for(i=0; i<sz; i++)
{
printf("%d ", \*(p+i));//p+i 这⾥就是指针+整数
}
return 0;
}

再比如指针ptr 的类型是int*,它指向的类型是int,它被初始化为指向整型变量a。接下来的第3句中,指针ptr被加了1,编译器是这样处理的:它把指针ptr 的值加上了sizeof(int),在32 位程序中,是被加上了4,因为在32 位程序中,int 占4 个字节。由于地址是用字节做单位的,故ptr 所指向的地址由原来的变量a 的地址向高地址方向增加了4 个字节。由于char 类型的长度是一个字节,所以,原来ptr 是指向数组a 的第0 号单元开始的四个字节,此时指向了数组a 中从第4 号单元开始的四个字节。

char a[20];
int \*ptr=(int \*)a; //强制类型转换并不会改变a 的类型
ptr++;

总的来说一个指针ptrold 加(减)一个整数n 后,结果是一个新的指针ptrnew,ptrnew 的类型和ptrold 的类型相同,ptrnew 所指向的类型和ptrold所指向的类型也相同。ptrnew 的值将比ptrold 的值增加(减少)了n 乘sizeof(ptrold 所指向的类型)个字节。就是说,ptrnew 所指向的内存区将比ptrold 所指向的内存区向高(低)地址方向移动了n 乘sizeof(ptrold 所指向的类型)个字节。

  • 指针 ± 指针
    指针和指针进行加减:两个指针不能进行加法运算,这是非法操作,因为进行加法后,得到的结果指向一个不知所向的地方,而且毫无意义。两个指针可以进行减法操作,但必须类型相同,一般用在数组方面。
//指针-指针
#include <stdio.h>
int my\_strlen(char \*s)
{
char \*p = s;
while(\*p != '\0' )
p++;
return p-s;
}
int main()
{
printf("%d\n", my\_strlen("abc"));
return 0;
}

指针类型

指针的类型很多,是枚举不完的,于是我们只需要将几种重要的指针类型给琢磨清楚,别的就只需要稍加观察就能立即理解了。
要理解复杂类型其实很简单,一个类型里会出现很多运算符,他们也像普通的表达式一样,有优先级,其优先级和运算优先级一样。原则就是,从变量名处开始,根据富豪的优先级,既可以退出指针的类型。

int p;//最朴实无华的整型变量
int\* p;//从p开始,与\*结合,说明p是一个指针,再与int结合,说明指针所指向的元素是整形,所以p是一个返回整型类型的指针
int p[3];//从p开始,与[]结合,说明p是一个数组,再与int结合,说明数组里的元素是整形的,所以p是由整型类型组成的的数组
int\* p[3];//从p开始,[]的优先级比\*高,所以p先与[]结合,是一个数组,再与\*结合,说明数组里的元素是指针类型,最后与int结合,说明指针所指向的元素是整形,所以p是一个由指向整形元素的指针组成的数组
int(\*p)[3];//从p开始,先与\*结合,是一个指针,再与[]结合,说明这是一个指向数组的指针,再与int结合,说明数组里的元素是整形的,所以p一个指向由整形元素组成的数组的指针,是数组指针
int\*\* p;//从p开始,先与右边的\*结合,说明是一个指针,再与左边的\*结合,说明这是一个指向(左\*)指针的(右\*)指针,再与int结合,说明(左\*)指针的返回类型是整形的,所以p是一个返回整型类型的指针的指针
int p(int);//从p开始,与int结合,说明是一个有一个整形变量参数的函数,再与左边的Int相结合,说明这个函数的返回类型是整形,说明p是一个返回整型类型且有一个整形变量参数的函数
int\* p(int);//从p开始,与int结合,说明p是一个有一个整形变量参数的函数,再与\*结合,说明这个函数的返回的是一个指针,再与int结合,说明这个指针的返回的是整形类型,所以这是一个返回的是一个整型类型指针的函数
int (\*p)(int);//从p开始,与\*结合,说明p是一个指针,再与int结合,说明是指向一个有一个整形变量参数的函数的指针,再与int结合,说明函数的返回类型是整形,所以p是一个指向一个返回整型类型且只有一个整形变量参数的函数的指针
int \*(\*p(int))[3];//从p开始,与int结合,说明指针指向的是一个有一个整型变量参数的函数,再与\*结合,说明函数返回的是一个指针,再与外面的[]结合,说明指针指向的是一个数组, 再与\*结合,数组里的元素是指针,再与int结合,说明p是一个返回指向一个返回类型为整型的指针类型组成的数组的指针的函数

这是绝大多数会用到的指针类型,如果上述指针类型都能够很好地理解了,其他的指针理解也就有了规律。
规律大致如下:

指针的类型

从语法的角度看,你只要把指针声明语句里的 指针名字 去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。for example:
char* p 的指针类型是 char*
char** p 的指针类型是 char**
int* p[3] 的指针类型是 int* ()[]
以此类推…

指针所指向的类型

从语法上看,你只须把指针声明语句中的 指针名字和名字左边的指针声明符* 去掉,剩下的就是指针所指向的类型。

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

5%以上C C++开发知识点,真正体系化!**

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值