天天看点

C语言的灵魂之指针

  指针在C语言中非常的重要,也比较的难。你对指针的掌握程度也决定了你对C语言的掌握程度。

  在学习C语言的时候因当搞清楚取值运算符和取地址运算符各自的含义。我们这里就通过取值运算符和取地址运算符展开讲指针。

  在讲指针之前会先介绍取值运算符与取址运算符的用处。这个对于理解指针非常的重要。

C语言的灵魂之指针

    • 一、取值运算符 *
    • 二、取地址运算符 &
    • 三、指针
    • 四、野指针
      • 1.野指针的规避
    • 五、其他

一、取值运算符 *

  * 除了有乘号运算的意思外还有取值运算符的意思。在指针中比较常见,表示的含义是取出一个地址存放的值。

例如现在在0x005这个地址存了一个值,值是多少呢?9。变量既可存放地址,也可以直接存放值。如果存放地址那么这个变量就叫做指针变量1。

C语言的灵魂之指针

  如果现在有指针变量pa存放了地址0x005如果我们在输出的时候直接写printf(""%d",pa);那么此时不会得到9。例如下面这个程序。

#include <stdio.h>
int main()
{
	int a=9;
	int *pa;
	pa=&a;//此时pa存放了a的地址,地址为62fe14 
	printf("pa=%d\n",pa);
	printf("pa=%x",pa);//通过十六进制输出验证地址是否为62fe14 
	return 0;
}
           

【运行结果】

C语言的灵魂之指针

  这是为什么呢?那么又要如何才能得到9呢?不能得到9是因为我们直接读取了变量的内容。而此时指针变量内存放的是一个地址。所以就会直接输出地址。如果我们在输出的时候在前面加上取值运算符 * 就可以直接输出9了。我们改了之后就是这样

#include <stdio.h>
int main()
{
	int a=9;
	int *pa;
	pa=&a;//此时pa存放了a的地址,地址为62fe14 
	printf("pa=%d\n",*pa);
	printf("pa=%d\n",pa);//此时pa作为参照
	return 0;
}
           

【运行结果】

C语言的灵魂之指针

  可见,我们不加 * 的输出结果仍然为地址的十进制形式。加了 *的就已经变成 9 了。

二、取地址运算符 &

  我们知道在计算机中所有的数据都是存储在内存地址中的。那么如果我们现在定义了整形变量 a 存放的值是 10086 那么我们想要知道这个 10086 是存在哪里的应该怎么办呢?此时就可以通过对变量 a 进行取地址操作。还有就是不知道大家是否还记得我们在写 scanf 的时候会在变量前面加上 & 。因为我们输入的数据只能存放在地址中所以要加上 & 。下面的示例可以同时体现出取值运算符和取地址运算符,可参考理解。

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

【运行结果】

C语言的灵魂之指针

三、指针

  前面介绍了取值运算符和取地址运算符,现在介绍指针。在C语言中指针不仅可以对数据本身进行操作,也可以对存储数据的变量地址进行操作。在前面我们说我们在使用 scanf 函数的时候会在变量前加上取地址运算符,那么是否可以不加呢? 可以,指针就可以办到。请见下例:

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

【运行结果】

C语言的灵魂之指针

  通过上面的示例可以看出我们在定义指针的代码是 int *pa 那么为啥是用 int 而不是 char 和 float 呢?因为我们在定义指针的时候指针类型应该和指针要指向的变量的类型保持一致。在C语言中还需注意的是指针变量也是属于C语言中的一种变量,占用的内存大小为8个字节2。另外一个需要注意的是C语言中指针变量名代表

四、野指针

  所谓野指针即为对所定义的指针不指定其应当指向的地址也就是未初始化,这是就会指向一个随机地址。注意!!!指向随机地址是非常危险的如果指向了一个正在使用的地址,再进行解引用那么可能导致程序崩溃,数据损坏。因此我们在进行指针编程的时候应当尽量避免出现野指针。

下面是野指针的错误示例

#include <stdio.h>
int main()
{
	int *pa;
	return 0;
}
           

1.野指针的规避

  如果在程序中需要暂时不对指针进行指定地址可以通过赋NULL的方法进行说明。上面的程序如果使用下面的方法来定义就不是野指针了。

#include <stdio.h>
int main()
{
	int *pa=NULL;
	return 0;
}
           

五、其他

  在编写C语言的指针的时候可以使用下面的两种写法,这两种写法在运行时是没有任何差别的。

int *p;
int* p;
           

如果仍有疑问或者存怀疑,可以通过下面的程序来验证结论。

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

【运行结果】

C语言的灵魂之指针

  理解了取值运算符,取址运算符与指针之间的区别和关系之后应该能够理解下面的第二行的等式。

C语言的灵魂之指针

  因为文章篇幅的原因关于指向指针的指针等更多其余关于指针的应用暂未在此做介绍,如果阅读完有疑问或好的建议与意见可在下方留言。

  1. 指针变量就是用来存放内存地址的变量。 ↩︎
  2. 关于C语言指针变量的内存大小在C语言中各类型变量在程序中占用内存大小中做了详细介绍及验证。 ↩︎

继续阅读