C语言指针的深入理解

1、 内存地址

要理解什么是指针需要先理解内存地址。内存地址是用来访问计算机内存的。因为计算机内存通常是由很多小的存储单元组成,内存地址就是用来标识这些小的存储单元。访问内存需要知道内存地址,就像去朋友家需要知道朋友家的地址是一样的。如下图所示,右侧是内存单元,左侧给出了每个内存单元的地址。图中每个单元格可以存储一个byte的内容。
图1

2、 获取变量的内存地址

那么如何获取一个变量的内存地址呢? C语言里提供了获取变量内存地址的方法,在变量前面增加一个&符号就可以获得变量的内存地址。下面程序可以打印出变量a的内存地址。
int a = 10;
printf(“The address of a is %d”, &a);

3、 指针变量

当一个变量中所保存的内容是内存地址时,这个变量被称为指针变量。为了标识某个变量是指针变量,通常在定义这个变量时在变量的前面加一个*号,下面给出了指针变量的定义:
int a = 8;
char c = ‘s’;
int * p; //p是一个指针变量,因为p前面有个 * 号; p中保存了一个内存地址,这个内存
地址存储了一个int类型的数据。
p = &a; //将a的内存地址赋给指针变量p

char * q; //q是一个指针变量,因为q前面有个 * 号; q中保存了一个内存地址,这个内
存地址存储了一个char 类型的数据。
q = &c; //将变量c的内存地址赋给指针q
图2
如上图所示,q和q本身也是变量,所以他们本身也占用内存。p存储的内存地址是0x0000000c(变量a的内存地址),这个内存地址中存储了int类型的数据8,q存储的内存地址是0x00000004(变量c的内存地址), 这个内存地址存储了一个字符’s’。
注意:int类型通常占用四个字节,指针变量也通常占用四个字节,char类型通常占用1个字节。

4、 访问指针指向的内容

在指针前面加上*号,就可以访问指针所指向的内容

printf(“%c”, *q);// 打印出q指向的内容, 输出字符s
printf(“%d”, *p);//打印出p指向的内容,输出数字8

以上程序段执行前的内存映像如下图所示:
图3

5、 修改指针指向的内容

在指针前面加上*号,也可以修改指针所指向的内容

如下两条语句修改指针指向的内容
*p = 10; //修改p指向的内容为10
*q = ‘d’;//修改q指向的内容为’d’
图4

6、 指针变量的初始化和赋值

指针变量在使用前一定要赋值(使其指向某一个内存地址),如果不赋值就访问会导致异常。如下程序段是有问题的:

int *p;

*p = 10; //指针p没有赋值,所以会报错

如下程序段是正确的
int a=8;
int *p;
p = &a; //对p进行赋值使p指向了变量a
*p = 10; //修改变量a为10,此时可以正确地把a修改为10

要改变p指向的内容,可以重新对p进行赋值,如下程序段先让p指向a再让p指向b
int a=8;
int b=9;
int *p;
p = &a; //p指向a
*p = 10;//修改a的值为10
P = &b;//p指向b
*p = 11;//修改b的值为11

7、 指向指针的指针

int **p;
前文出现过,int p, 比较容易理解,就是定义一个指向int类型的指针。那么这里的int **p是什么呢?
对于这种特殊形式,首先可以确定的是p是一个指针,因为p前面不但有
号而且还有两个号,所以肯定是指针。
那么两个
号又是什么意思呢?
把int **p分解为以下形式,和int *p比较,就会看的比较清楚
int * p; //指针p指向 int类型
int p;//指针p指向int类型
其实上面的两种形式区别就在于:指针指向的内容的类型不同,一个指向int
类型一个指向int类型

int a = 10;
int *q;
int **p;

q = &a;//q 指向 a
p =&q; //p 指向q, q是一个int类型指针
该程序段执行完毕后内存映像如下:

图5

发布了2 篇原创文章 · 获赞 0 · 访问量 66

猜你喜欢

转载自blog.csdn.net/hw2169/article/details/103792090