指针---C语言(一)

简介: 指针---C语言(一)

前言:


 接下来我们进入C语言里的重头戏---指针。指针是一个很好用的东西,学好指针,无异于打下半片江山。


一.指针基础


 指针实际上是用来指向内存空间的一个变量。可能读者会觉得博主说得轻描淡写,我们先抛开先前对指针的恐惧,一步一步来讲,先从内存的基础讲起。


1.1内存单元

 内存是存取数据的一块大空间,我们知道,无论是什么事物,不好好利用都会有挥霍完的一天,相应的,要想高利用率的使用好内存空间,计算机前人们在设计的时候,就把内存空间划为一个一个小小的内存单元。


 那又如何区分这些长的一样的内存单元呢?在生活中,一栋栋商品房,房型差不多,如何让住户知道自己买的房间在哪里咧,假设有亲戚朋友要来我家,如何让他们知道我住哪里呢?我想,给个编号,给个地址不就好了~,现实中如此,计算机也如此,使用一个个编号给内存单元定义地址。


 这个编号是使用地址线(电线)的通电,不通电这两种状态转换成数字信号1,0给内存单元编号,这个编号也就是它们的地址啦。


 补充:32位电脑有32根地址线,每一根地址线可以产生0或1的数字信号,总共有2的32次方种组合,也就是可以管理2的32次方个内存单元。64位电脑就可以管理2的64次方个内存单元。


1.2内存单元和指针的大小

 那么一个内存单元多大合适呢?在以前我们常说4G、8G内存的电脑。我们姑且来算一下吧,假如一个内存单元只能存储一个bit位,那么32位机器内存大小为2的32次方个bit位:



  二进制第33位的1代表2的32次方,我们现在转换成Gb单位需要除以8(Byte)、除以1024(Kb)、除以1024(Mb)、除以1024(Gb)。



 由于程序员的除法取商,再除1024就是0了。所以现在是转换到Mb的单位,512Mb就是0.5G,这未免也太小了吧,听过最小的内存也是4G~,那一个内存单元从一个bit位变成一个字节呢?0.5G乘以8变成4G,可以接受~


 总结:计算机中一个内存单元是一个字节的大小。


 指针是存放内存单元地址的,一个地址的产生前面也说过。如果是32位平台,就用32根地址线生成32个数字信号来编号,那一个地址就是32个bit位,所以指针大小就是4个字节;如果是64位平台,指针大小为8个字节,这是固定的,不会根据数据类型改变指针大小。


 总结:指针大小如果在32位平台下是固定4个字节,在64位平台下是固定8个字节。


二.指针变量


 如何创建指针变量呢?请看值一段代码:

#include <stdio.h>
int main()
{
    int a = 0;
    int* pa = &a;
    *pa = 10;
    printf("%d\n", a);
    return 0;
}

2.1指针类型

 和创建普通变量是一样的,指针类型+变量名创建整型指针变量pa。&取地址操作符取出整型变量a的地址放到指针变量pa里面,*解引用pa的意思是找到pa存放的地址对应的内存单元,也就是找到了a,*pa相当于a。


 char*、short*、int*、float*、double*的大小分别是多少?都是4个字节的空间大小(32位),那char*类型的指针变量也可以存放整型变量的地址是毋庸置疑的,但这样做对吗?我们看代码:



 将a的地址放到char*的指针里面是能放进去的,只是编译器会有一个警告,报的是类型不兼容:



 这就是我们这里要讲的指针类型的意义:


指针变量的类型决定了指针解引用时改变多少个字节

指针变量的类型决定了指针加减运算时跳过多少个内存单元

 我们使用整型指针可以把-1完全变成0,而使用字符指针却改不成,这是为什么呢?请看:



 *pc只改了一个字节,(内存中用十六进制表示,两个十六进制位等于一个字节,16是2的四次方),所以a的补码为0xffffff00;打印的时候转换成原码~

  以上解释就是指针类型决定指针访问权限。还有一个指针决定指针加减运算跳过多少个内存单元的问题,博主简单说一下。


 一个指向整型的指针+1,指针变量里的地址会指向哪一个内存单元呢?我们看代码:



 整型a的起始地址是c4,本来a占有的内存单元有c4、c5、c6、c7这四个内存单元,一个内存单元一个字节,整型变量是四个字节大小嘛。然后使用它的首地址代表a的地址,整型值10就放在这四个内存单元里。p存放的值是a的地址,所以&a和p是一样的。


 打印p+1不是等于c5,而是c8,为什么呢?这里我们就得了解指针类型决定指针跳过多少个内存单元。可以这样理解,整型指针加1的意思是:指向下一个整型(当然下一个不一定是整型),只是这样说而已。



2.2野指针

 野指针就像野孩子一样,没有人管,这是非常危险的。野指针的常见情况如下:


没有初始化的局部指针变量。

指针指向的变量销毁掉了。

数组越界访问。

 局部变量没有初始化是随机值,一个局部指针变量如果没有初始化,那它也是一个随机值;指针变量是存放地址的变量,随机值存放在指针里面会被当成地址看待。如果此时不小心对指针进行了解引用操作,就会对不属于我们的内存单元里的内容进行修改,造成破坏,导致程序挂掉。


 指针指向的空间释放掉了,指针就变成了野指针。请看代码:



 a是test函数里的局部变量,在test函数里a存在,然后返回a的地址,a出了代码块,生命周期结束,被释放掉了,可是*p还是接收到a变量的地址,但a已经不属于我们了,此时p就是野指针。


 数组越界访问变成野指针在后面讨论指针和数组的关系时讲~


避免野指针

在创建指针变量的时候,如果不知道指向谁,初始化为NULL(空指针)

指针使用完后,赋值成空指针

在使用指针之前,用if测试指针现在放的是不是NULL,因为空指针不能解引用

相关文章
|
14天前
|
存储 C语言
C语言 — 指针进阶篇(下)
C语言 — 指针进阶篇(下)
20 0
|
14天前
|
存储 C语言 C++
C语言 — 指针进阶篇(上)
C语言 — 指针进阶篇(上)
26 0
|
20天前
|
存储 程序员 C语言
C语言指针的概念、语法和实现
在C语言中,指针是其最重要的概念之一。 本文将介绍C语言指针的概念、语法和实现,以及如何使用它们来编写高效的代码。
13 0
|
21天前
|
存储 C语言
【C语言】深入解开指针(三)2
【C语言】深入解开指针(三)
|
21天前
|
存储 程序员 C语言
【C语言】深入解开指针(二)2
【C语言】深入解开指针(二)
【C语言】深入解开指针(二)2
|
21天前
|
存储 C语言
【C语言】深入解开指针(一)1
【C语言】深入解开指针(一)
|
22天前
|
C语言 索引
基于C语言的函数指针应用-消息命令处理框架
基于C语言的函数指针应用-消息命令处理框架
11 0
|
29天前
|
存储 人工智能 编译器
C语言指针详解
指针运算,指针和数组,二级指针
C语言指针详解
|
29天前
|
存储 C语言
C语言第二十四弹---指针(八)
C语言第二十四弹---指针(八)
|
29天前
|
编译器 C语言
C语言第十九弹---指针(三)
C语言第十九弹---指针(三)