【C语言】【指针1】指针难?看这个就够了!

简介: 【C语言】【指针1】指针难?看这个就够了!

再过几天就是霜降了,关于指针的知识大家有没有学会呢?

接下来,我会整理一下指针的相关的知识

不过,我希望各位观众,大家要明白一个事实:知识是可以学会的,指针属于知识,指针也是可以学会的!!!


1.内存和地址

1.1内存

1.1.1电脑中内存与电脑其他部分关联性:

1.1.2内存有着不同单位进行换算:

内存最小单位:比特(bit),一个比特位可以存放一个二进制位

1Byte = 8 Bit

1KB = 1024Byte

1MB = 1024KB

1GB = 1024MB

1TB = 1024GB

1PB = 1024TB

内存单元:1个字节(Byte)

![在这里插入图片描述](https://ucc.alicdn.com/images/user-upload-01/128d9583ebca4d649cfd813dbb3730a9.

1.2编号的理解:

为了便于管理,我们给每个内存单元一个不同的编号。

编号的实现依赖于电脑硬件的约定俗称,而并不需要电脑进行存储。

如果有32根地址总线,那么就有2的32次方种不同的编号,因而就实现了内存地址的编号!!!

内存单元的地址 = = 单元编号 = = 指针

2.地址

2.1 取地址符

当我们想看某个变量的地址时候,我们可以写取地址符进行取地址操作

取地址符号:&

2.2指针变量和地址

当我们创建一个整形变量时候,会占用四个字节,当我们进行取地址操作时候,电脑会取地址哪一个呢?

答案是首地址,并且是内存中较低的那个地址

2.2.1指针变量

2.2.2指针变量的解引用

形式:* name

可以利用地址来修改指针指向的地址的内容

2.3指针变量的大小

同学们可以先猜一下指针变量的大小

下面直接代码来得出答案:

是不是没想到呢?怎么可能都是8啊!!!

答案简单,因为都是地址,地址都是由相同数量的2进制数字组成的,这个环境是64位二进制环境,转换成二进制数字就是64位,也就是64个bite位,也就是8个字节啊!

当然,如果平台是32位环境的话答案就是4字节,指针类型大小跟类型没关系,只跟平台环境有关,并且同一环境中类型大小是相同的!!!

3.指针类型的意义

有同学可能就想问了,明明指针大小都是一样的,区分指针类型有什么意义啊?

我们通过举两个方面的例子来探索其中的奥秘!

3.1指针的解引用中指针类型的意义

下面,我们通过一段代码,来了解一下指针不同类型的意义,注意观察对比!!!

注意:

1.那么,有些同学可能就想问了,char*p1可以存的下int num2 的地址吗?当然可以!因为地址的大小都是一样的

2.我们发现int类型的解引用修改了四个字节的内存,但是char类型的解引用修改了一个字节的内存!!!

结论:

1.指针类型有意义:我们发现,不同类型的指针类型是有意义的

2.访问权限的不同:同时,还可以证明不同类型的指针类型解引用的访问权限是不相同的,比如int类型的指针解引用操作可以访问4个字节,而char类型的指针解引用操作只可以访问1个字节

3.2指针中的±整数操作

我们发现,p1没有正常访问到数组数值,p2却正常访问到了数组的第二个值!

结论:

1.指针类型是有意义的

2.不同的指针类型步长是不同的

3.3数组访问

一般我们在访问数组时候,会通过下标进行访问,如下面的这种情况:

但是,我们也可以使用地址对数组进行访问:

那为什么数组可以这样地址加一访问呢?

原来,数组的地址由低到高依次排列,并且是连续的,这样,我们在首地址已经知道的情况下,就可以通过不断整型加一进行依次访问!!!

4.const修饰指针

const是用来限制指针的作用范围的,能够避免在不必要的地方使用。

比如:我们想要修改a的值,发现直接修改被限制了,但是我们可以通过指针修改啊!

所以:

4.1如果我们在指针的号前面加上const,限制的就是p:

4.2如果我们在指针的*号后面加上const,限制的就是p:

5.指针+,-整数的操作

5.1指针加减整数的操作

我们这里可以再讲一下关于数组的例子:

也可以写成这样哈:

5.2指针减指针的操作

在这里,指针减指针有个前提条件,就是使用时候必须得保证两个指针变量指向同一块空间,这样才能又意义,否则就因不确定中间的内存间隔而失去了意义!

5.3自主模拟实现strlen函数:

方法一:

方法二:

6.野指针

所谓的野指针,指的是容易越界访问,访问不确定,指针存在随即地址的指针。

6.1野指针的形成原因:

  • 指针未初始化
  • 数组访问超出范围
  • 指针指向空间被释放

6.1.1指针未初始化

编译器报错:

6.1.2数组超出范围

如果指针越界访问,同样会造成野指针的情况

正常情况下:

如果越界访问:

6.1.3指针指向的空间被释放

这是因为:当解引用a时候,发现a所指向的地址被电脑释放了,因而所输出的数字是错误的。

6.2如何规避野指针呢?

野指针的发生像火灾一样,我们可以规范人们的行为减少火灾发生的可能性,但不可能绝对性的避免。下面可以给大家几条建议来提高指针的安全性:

  • 指针初始化
  • 小心指针越界
  • 指针变量不再使用时,及时置为NULL
  • 避免返回局部变量的地址

6.2.1指针初始化:

6.2.2小心指针越界

6.2.3指针变量不再使用时,及时置为NULL

正确的写法:

7.assert断言

用在运行时确保程序符合条件

必须要包含头文件:assert.h

assert的运行逻辑是如果判断为真,不会起任何作用,返回值非零;如果判断为假,终止报错,返回值为零。

assert的开关是#define NDEBUG

下面我们可以通过几行代码来体验一下:

8.指针的使用和传址调用

8.1传值调用与传址调用

两者的区别是什么?传值传的是一个数值,传址则直接把地址传过去。

为了更好的理解这两个词,我们用一个题目来做区分

题目:写一个函数,实现两个变量的数值调换

咱们先不做这个题目,先让大家判断一下下面的代码是不是传值调用:

我想大家应该猜到答案了,这不属于传值调用,因为main函数内部进行的交换。

那下面我们来正式的解决这个题目,有同学可能会写出下面的代码:

但是结果真的对吗?

好像我们发现没有交换,那到底问题出现在哪里呢?

原来,当我们创建一个自定义函数,自定义函数内的变量是当我们进入自定义函数时临时创建的,自定义函数内的变量的值是传入值的一份临时拷贝,当在自定义函数当中完成运算,自定义函数种的变量的值也会随之销毁,也就是说,实际上的num1和num2并没有发生交换!!!那么这种仅仅传入数值,并且新建一个变量拷贝一份数值的调用情况,我们可以称之为传值调用。显然,在本题目当中该方法并不适用。

那我们可以换一种方法:传址调用

看,两者成功调换了数字。

总结:

同过上面的案例,我们就可以得出以下结论,

1.当我们要修改函数外部参数时候,我们需要用到传址调用

2.当我们不修改函数外部参数,仅仅在内部做一些比较排序打印等等的工作并不影响外部参数的数值时候,我们可以选择传值调用。

8.2strlen函数的模拟实现

首先,我们来回顾一下strlen函数的功能吧:

strlen函数功能:是用来计算字符串长度大小的库函数,这其中不包含字符串后尾的“\0”.

我们用代码来实现一下:

当然,我们依靠指针学到的知识也可以模拟实现一下:

好了,为了避免内容过多,我们暂时先说到这里吧,很快就会更新下一期指针内容哦~

相关文章
|
1月前
|
存储 C语言
【C语言篇】深入理解指针3(附转移表源码)
【C语言篇】深入理解指针3(附转移表源码)
37 1
|
28天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
45 0
|
27天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
16 2
|
27天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
27天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
1月前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
1月前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
1月前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
C语言
C语言指针(3)
C语言指针(3)
13 1
|
1月前
|
C语言
C语言指针(2)
C语言指针(2)
14 1