C与指针-第六章-指针

指针

含义:

在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。

指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址

&操作符:取变量的地址
*操作符:对指针做解引用操作

地址&内存:

计算机的内存由数以亿万技的位(bit)组成,每个位可以容纳0和1.

由于位的标示范围太有限,计算机中为了可以存储较大范围的值,通常把许多个位合成一组作为一个单位。在现代大多数的机器中,常用的是用8个位来组成一个单位,这里成为字节(byte)。1个字节可以存储无符号值0~255,或有符号值-128~127。

其实字节标示的大小也比较有限,为了继续扩大存储的范围,我们把更多个字节组合在一起,作为一个更大的单位。

例如:

int –4个字节 ,32位为4个字节
float –4个字节
long –4个字节
long long —8个字节

需要注意的:
1)内存中的每个位置由一个独一无二的地址标识
2)内存中的每个位置都包含一个值

int a =112,b = -1;
float c = 3.14;
int d = &a;
float
e = &c;

a,b,c,d,e分别表示什么
a是112,b为-1,c为3.14
d是指向int型的指针,这里指向a的地址,a的地址是100,所以d的值为100
e为指向float型的指针,这里指向c的地址,c的地址为108,所以e的值为108

间接访问操作符:

含义:

通过一个指针访问它所指向的地址的过程称为间接访问或解引用指针。

操作符:对应的操作符为*

例如:
我们上面一节中的d为100,d即为间接访问,d的值为int类型,d的值为100,d标示访问内存位置100并查看哪里的值,因此d的右值为112.

未初始化和非法的指针:
下面这个代码有没有问题:

int a; a = 10;

语句描述:这个语句声明创建了一个名叫a的指针变量。
*a = 10表示把12 存储到a所指向的内存位置。

正常编译这个语句没有问题,但是在正常使用的过程中,会存在一些隐患。这里的a没有做初始化,那么a指向哪个地址我们不清楚,所以这个10存储到哪个内存区域,其实我们也不能清楚的知道。

> 如果指针变量是静态的,它会自动初始化为0
> 如果指针变量是自动的,那它根本不会被初始化。

所以当,赋值操作进行时,如果a的初值是个非法地址,这个语句将会出错,程序终止;如果a的初值是个合法地址,那么地址上的值被修改,但是我们不确定那个地址是否是我们想要修改的地方。
所以,在对指针进行间接访问之前,要确保它已经初始化。

空指针:

含义:表示不指向任何东西(地址或内容)
用法:要使一个指针变量位NULL,就需要给它赋一个零值。
想要测试一个指针是否为空,我们需要拿它与零值进行比较。这个零值由源代码约定得出。
指针与零值比较来判断是否为空,我们最好用!这个符号来表示,这样可以排除隐士类型转换,也增强了可读性
例如:

int a = 10;
int *b = &a;
if (!b)
{
printf(“point p is not null\n”);
}

指针的指针:

我们用**来进行表示指针的指针,例如:

int a = 10;
int b = &a;
int *
c = &b;

假设a的地址为101
那么b = 101, b = 10;
**c相当于
(c),我们必须从里向外逐成求值。c访问c所指向的位置,即为变量b,为101,(c)这个间接访问操作,即访问c所指向位置的地址,这里就死&b,就是变量a,值为10.

指针运算:

指针运算包括 算数运算和关系运算:

运算符:+ ,-,++,—

这种形式只能用于指向数组中某个元素的指针,结果类型也是指针。
指针的算数运算都需要操作一段连续的内存空间,例如数组

指针运算:+,++

int value[5]
int *p;
(1) p = &value[0];//p指向value数组的第一个元素
P += 2; //p向后偏移两个int长度的位置,即指向了value数组的第三个元素

(2) for (p = &value[0]; p< &value[5];)
{
p++ =0; //这边先进行p = 0的操作,即把value[0]赋初值为0,再指针后移一位,循环初始化value这个数组
}

当p这个指针指向的地址大于value[5]的地址,循环结束,p <&value[5],这里经过了5此循环后,p就指向了value数组最后一个数组外面的那个地址,指针可能可以合法的获取这个值,但对它执行简介访问操作可能意外的原先存储于这个位置的变量,我们一般不知道这个变量是什么,因此,这种情况下,一般不允许对指向这个位置的指针进行间接操作,即*p = 10这种操作

指针运算: -,–

指针相减运算,只适用于数组的操作,即两个指针都指向同一个数组中的元素时,才允许一个指针减去另一个指针。

int value[5]
int p;
(1) p = &value[4];//p指向value数组的第一个元素
P -= 2; //p向前偏移两个int长度的位置,即指向了value数组的第三个元素
(2) for (p = &value[4]; p>= &value[0]; p–)
{
p =0; //这边先进行*p = 0的操作,即把value[4]赋初值为0,再指针减减,向前移动一位,循环初始化value这个数组
}

当p这个指针指向的地址小于value[0]的地址,循环结束,p > = &value[0],经过5次循环后,p指针指向了数组第一个元素之前,这里我们同样不能再对p这个指针进行间接操作。

总结:

1)未初始化的指针变量,不能进行解引用操作
2)初始化为NULL的指针,不能进行解引用操作
3)指针进行加减法操作后,指向了数组外面的内存地址后,不能对它们进行间接操作
4)指针的减法操作只能针对同一个数组的元素进行

Tianger Ge wechat
如果您喜欢这篇文章,欢迎扫一扫我的微信公众号!