C语言一指针详解

Posted SuchABigBug

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言一指针详解相关的知识,希望对你有一定的参考价值。

一、指针是什么

指针是编程语言中的一个对象,利用地址,他的值直接指向存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的成为指针。意思是通过它能找到以它为地址的内存单元

那么通过地址能找到值,地址的内存单元是怎么产生的呢?
如果是32机器,通电之后会产生电信号,点信号有正电和负电,电信号找出数字信号之后,其实就是32个0 1 组成的二进制序列,那么32个01组成的二进制序列有多少种可能性?

00000000 00000000 00000000 00000000
00000000 00000000 00000000 00000001
00000000 00000000 00000000 00000002
… … … 
11111111 11111111 11111111 11111111

这里就有232那么多的地址,这是32位机器上的,
在64位上更大

⚠️注意:

  1. 在32位的机器上,地址是32个0或者1组成二进制序列,那地址就得用4个字节的空间来存储,所 以一个指针变量的大小就应该是4个字节。
  2. 那如果在64位机器上,如果有64个地址线,那一个指针变量的大小是8个字节,才能存放一个地址。
int a = 10; //这个a占4个字节
int* pa = &a; //拿到的是a的4个字节中第一个字节的地址

二、指针和指针类型

  1. 指针类型决定了指针解引用的权限有多大, 如果将一个int型指针的值传到char型指针里,但由于char型只能接受一个字节在这里插入图片描述
    上图中int型指针,p+1为跳过一个整型,也就是4个字节
    而char型指针,pc+1跳过一个字符,也就是1个字节

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

三、野指针是什么,如何避免?

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

野指针的例子:

  1. 指针未初始化,直接非法访问
    在这里插入图片描述
  2. 越界访问
    在这里插入图片描述
  3. 指针指向的空间释放,动态内存开辟释放了
    在这里插入图片描述

那么如何规避野指针?

指针初始化
小心指针越界
指针指向空间释放即使置NULL
指针使用之前检查有效性

四、指针运算

1. 指针的加减运算

在这里插入图片描述

2. 指针减指针

指针和指针相减得到元素个数,前提是:两个指针指向同一块空间
在这里插入图片描述
我们一般实现strlen函数的时候用count++来计算有多少个字符,这里就很好的利用到了指针最后一个数减去最开始来得到有多少个字符。

五、二级指针,三级指针例子

指针间的传递:
在这里插入图片描述
一级指针:*p
二级指针:**pp
二级指针:***ppp
那么我们如何用三级指针取到a地址里的值呢?
我们通过 *(xxx)来解引用里面的三级指针,三级指针再去找二级指针,而二指针内存的地址是一级指针,一级指针内存的是a的地址,最终a的地址内存放的就是值20.

六、指针数组和数组指针

指针数组:存放指针的数组

int arr1[3];
char arr2[3];

上面arr1是整型数组,arr1里放的都是int型
上面arr2是字符数组,arr2里放的都是char型

int* a[10]; 

那么a是一个数组,有10个元素,每个元素是一个整形指针
在这里插入图片描述
数组指针:是指一个指向数组的指针,它其实还是一个指针,只不过是指向数组而已

举个例子:int (*ptr)[10]; 其中,由于[]的优先级高于*,所以必须添加(*ptr)来确保机器能够认出是数组指针.

六、数组和结构体

数组:数组:一组相同类型的元素集合
结构体:也是一些值的集合,但是值的类型可以不同

void print1(struct Stu s){
printf("%c %d %lf %s %d %s \\n", s.sb.c, s.sb.s, s.sb.d, s.name, s.age, s.id);
}

void print2(struct Stu *p){
printf("%c %d %lf %s %d %s \\n", p->sb.c, p->sb.s, p->sb.d, p->name, p->age, p->id);
}

具体结构体代码见:👉🏻 传值vs传址.

上述的调用print1和print2比较哪种方法更好?

函数传参的时候,参数是需要压栈的。如果传递一个结构体对象的时候,结构体过大,参数压栈的系统开销比较大,所以会导致性能下降,因此print2比较合适
在这里插入图片描述在这里插入图片描述
压栈的规则就是,先进后出,后进先出
(函数栈帧的创建和销毁)每一个函数调用都会在内存的栈区上开辟一块空间, 上图中我们可以看到,创建main函数时,就要在栈区分配一块空间,变量abc和调用Add函数都需要创建空间,依次压栈


如果上述文章对你有帮助的话,动动你的手指点个赞哦 Thank you ~ 😃

以上是关于C语言一指针详解的主要内容,如果未能解决你的问题,请参考以下文章

20160211.CCPP体系详解(0021天)

C语言一指针详解

C 语言行指针与列指针详解

C语言指针详解之一

C语言函数指针详解

C语言小妹不懂指针和数组的关系?那就安排指针数组关系详解