经过前面漫长的c语言学习,终于进入了C语言中最核心,最重要的部分啦!其实对于前面的知识,自己都有所了解,必境C语言也是一直在学(只是没学通而已(∩_∩)),但是通过写博文的方式,我发现最好的一个地方就是它能够让你很踏实地去学习,摒弃浮燥,因为你写出来的东西都是自己亲自验证过的,强制让自己把所学的东西全部动手实践出来,写博文的另外一个很大的劣势,那就是比较费时间,如果你不写博文,可能对于我之前c语言的基础知识的学习可能一两周就学完了,而如果加上写博文,时间就得翻倍了,但是:我觉得这些小时间的"浪费"是非常值得的,因为你会学得扎实!所以,我会一直坚持下去的,好了,话不多说,正式进入非常期待,也非常容易犯迷糊的C语言“指针”之旅啦!
什么是指针:



下面通过代码来初探下指针:

看结果:

从输出的地址来看,这两个变量都是在栈上分配的,ec和e8刚好差一个整数的大小,说明这两个地址是连续的,且linux中栈地址增长是从高地址往低地址
如果在两个变量声明之间再加入一个变量呢?


7c、78、74刚好是四个字节连续的。
上面演示的指针是指向一个栈区,实际上,指针可以指向内存的任何区域(堆区、数据段.......):

运行结果:

&和*运算符:



值传递【比较经典的问题,也比较简单】:
#include <stdio.h> //值传递,最终不会影响原值 void swap(int x, int y) { int tmp = x; x = y; y = tmp; } int main(void) { int a = 100; int b = 200; printf("before swap: a=%d b=%d ", a, b); swap(a, b); printf("after swap: a=%d b=%d ", a, b); return 0; }
输出结果:
指针与函数参数:【比较经典的问题,也比较简单】
#include <stdio.h> //指针传递,形参的改变最终会影响实参 void swap(int* px, int* py) { int tmp = *px; *px = *py; *py = tmp; } int main(void) { int a = 100; int b = 200; printf("before swap: a=%d b=%d ", a, b); swap(&a, &b); printf("after swap: a=%d b=%d ", a, b); return 0; }
输出:
空指针:
空指针NULL,是一个特殊的指针,表示不指向任何东西。NULL实际上是用(void*)0表示的。



int* p = NULL;
*p //这种操作是不允许的。
通用指针【上面已经接触到了】:
在这之前,需理解一下指针类型:


指针算术运算:
我们来想一个问题:
对于变量,有不同的类型,是因为不同数据类型的空间大小是不一样的,是为了内存的分配,如:
short a;//占2个字节 int b;//占4个字节 double c;//占8个字节
但是:对于不同类型的指针变量,它们占用的空间都是相同的:
short* a;//占四个字节 int* b;//占四个字节 double* c;//占四个字节
那为什么不用一个指针类型来含盖所有不同类型的指针呢?原因就是为了:指针算术运算
所以,从上图来看,指针的加法支算,并非简单的地址+1,而是根据不同的数据类型,来偏移一个数据类型,这也就是为什么指针需要指定类型的原因。
好了,指针的初步了解就到这,之后会慢慢深入,下回见!