目录
前言
本座身为斗帝,参悟过无数的天阶斗技。今日所学的C语言,吾认为最重要的即为对于指针的理解。只有将指针这一内容参悟理解,才能真正深入理解C语言的核心。
正文
1.内存与地址
在理解指针前,我们要先了解内存与地址:
如果把上⾯的例⼦对照到计算机中,⼜是怎么样呢? 我们知道计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是 8GB/16GB/32GB 等,那这些内存空间如何⾼效的管理呢?
其实也是把内存划分为⼀个个的内存单元,每个内存单元的大小取一个字节。其中,每个内存单元,相当于⼀个学⽣宿舍,⼀个字节空间⾥⾯能放8个⽐特位,就好⽐同学们住的⼋⼈间,每个⼈是⼀个⽐特位。
即一个内存单元==1字节==8比特位
而每个内存单元也都有⼀个编号(这个编号就相当于宿舍房间的⻔牌号),有了这个内存单元的编 号,CPU就可以快速找到⼀个内存空间。生活中我们将门牌号称为地址,在计算机中我们也将内存单元的编号称为地址。而在C语言中赋予了这个地址一个新的名称----指针。
所以我们可以理解为:内存单元的编号==地址==指针
2.指针变量与地址
2.1取地址操作符(&)
如:
int a=1;
这个代码就是创建了一个整形变量a,用于存放整数1。而这个整形变量a需要向内存申请4个字节的地址,其中每个字节都有地址。
那么,如何获得这些字节的地址呢?
这⾥就得学习⼀个操作符(&)----取地址操作符
&a就可以获得a所占4个字节中地址较⼩的字节的地址。
虽然整型变量占⽤4个字节,我们只要知道了第⼀个字节地址,顺藤摸⽠访问到4个字节的数据也是可⾏的。
2.2指针变量
int a=1;
int*p=&a;
这里的变量p就是一个指针变量,用于存放整形变量a的地址。
指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址。
2.3如何拆解指针变量类型
int a=1;
int*p=&a;
char a='x';
char*p=&a;
2.4解引⽤操作符
int a=1;
int*p=&a;
*p=0;
2.5指针变量的⼤⼩
指针变量做为一个变量也是有大小的,那么一个指针变量的大小是多少呢?
在32位的环境下一个地址的大小为32个比特位,指针变量是⽤来存放地址的,那么指针变量也得能存放这32个比特位的信息,所以32位环境下一个指针变量的大小为32个比特位,即4个字节。而在64位的环境下,一个地址的大小为64个比特位,所以一个指针变量的大小为64个比特位,即8个字节。
2.6指针变量类型的意义
2.7void* 指针
2.8野指针
当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使⽤这个指针访问空间的时候,我们可以把该指针置为NULL。因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问, 同时使⽤指针之前可以判断指针是否为NULL。
我们可以把野指针想象成野狗,野狗放任不管是⾮常危险的,所以我们可以找⼀棵树把野狗拴起来, 就相对安全了,给指针变量及时赋值为NULL,其实就类似把野狗栓起来,就是把野指针暂时管理起来。
2.9传值调⽤和传址调⽤
学习指针的⽬的是使⽤指针解决问题,那什么问题,⾮指针不可呢?
那就是在函数中使用指针。
假设我们要使用一个函数将两个变量的值交换,我们可能会这样写:
#include <stdio.h>
void swap(int a,int b)
{
int x=0;
x=a;
a=b;
b=x;
}
int main()
{
int a=1,b=2;
printf("a=%d,b=%d\n",a,b);
swap(a,b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
我们是不是会认为交换后输出结果是:a=2,b=1
但实际上是:
可以看出这里的变量a与变量b的值并没有交换。
为什么呢?
其实是在函数swap中创建了两个新的形参a和b来接收实参a和b的值,这两个新的形参是在内存中开辟了新的空间,。当函数结束时就会销毁形参a b,不会影响实参的值。
这就是为什么主函数中a b的值没有改变。
#include <stdio.h>
void swap(int* a,int* b)
{
int x=0;
x=*a;
*a=*b;
*b=x;
}
int main()
{
int a=1,b=2;
printf("a=%d,b=%d\n",a,b);
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
改进的函数的输出结果: