我们可以任意选择其中的一个盒子存放东西,例如我们要在第一个盒子中放入10个乒乓球,所以我们可以找到编号为1的盒子,然后把10个乒乓球放进里面。
计算机的内存跟上面的例子很相似,因为内存也有编号,也可以往里面放东西,所以本质上跟上面的例子没有什么区别的。我们看看内存的真实结构吧:
在上面的图中,我们看到的图片左边的一些16进制数值就是内存的编号,我们称他为内存地址。而白色框框里面的数据就是保存在内存中的实际数据,我们一般使用的就是这些数据。
好了,已经大概了解过计算机的内存结构了,下面我们来说说什么是指针吧。
定义:指针是一种数据类型,与其它的数据类型不同的是指针是一种“用来存放内存的地址”的变量。
从上面的定义上可以看出,指针是变量,而且是有类型的变量,但他保存的是内存的地址。这样说来,指针也是很容易理解的。的确,指针就是这么容易。不过要灵活运用指针才能发挥出C语言的最大优势。
首先我们来看看怎么声明一个指针吧,声明指针的方法很简单,如下:
指针类型 *指针名;
例子:
int*iptr; //声明一个int类型的指针
char*cptr; //声明一个char类型的指针
unsigned long *ulptr; //声明一个unsigned long类型的指针
嗯,声明一个指针就是这么简单,就是"指针的类型" + "*" + "指针变量名"。跟声明一个普通的变量差不多,只是要多加一个"*"好而已。
那么我们声明了一个指针之后要怎么使用他呢?
嗯,前面我们已经说过,指针是保持着变量的地址,所以我们声明一个指针之后一般要把一个变量的地址赋值给他,那怎么把一个变量的地址赋值给一个指针呢,如下:
1.int *iptr;
2.int ivar;
3.iptr = &ivar;
第三行就是把ivar的地址赋给了iptr了,我们可以使用"&"操作符来取得一个变量的地址,所以第三行就是取得ivar的地址之后赋值给iptr了。
好了,现在iptr保存了ivar的地址了,不过这样有什么用呢?
嗯,继续看回我们一开始举的盒子的例子,我们知道了盒子的编号之后就可以往盒子放东西,同理我们知道内存的地址也可以往内存中存放数据,这就是指针的主要作用。看看下图:
我们看到iptr保存了ivar的地址,就像iptr指向了ivar一样,所以我们才会称这样的东西就指针。
既然iptr指向了ivar的地址,那么怎么向这个地址的内存存放数据呢?可以使用如下的方法:
*iptr= 10;
这样我们就向iptr指向的内存存放了10这个数据了。不信?我们可以打印一下ivar的值就清楚了,代码如下:
#include
intmain() {
int *iptr;
int ivar;
*iptr = 10;
return 0;
}
结果:
ivar:10
从结果看来,ivar的值的确被修改了。通过在指针变量前面加星号“*”,就可以访问到指针指向的内存单元。
例如我们要向iptr指向的内存存放数据可以使用:
*iptr= 10;
获取iptr指向的内存的数据可以使用:
itmpvar = *iptr;
说到这里,其实已经把指针的知识都讲完了,不过指针还有一些技巧,这个下次再讲了。
最后我们探讨一下怎样通过函数交换两个变量的数据吧。
如,我们有两个整型变量ivar1和ivar2,他们的值分别是10和12,要求我们写一个函数把这两个变量的值交换:
intivar1 = 10;
intivar2 = 12;
voidswap(…) {
}
要怎么写swap函数呢?看看下面的方法可不可以:
voidswap(int var1, int var2) {
int tmp = ivar1;
ivar1 = ivar2;
ivar2 = tmp;
}
intmain() {
int ivar1 = 10;
intivar2 = 12;
swap(ivar1, ivar2);
printf("ivar1: %d, ivar2: %dn", ivar1, ivar2);
return 0;
}
编译运行之后,我们会发现这两个变量的值并没有交换到。原因是,函数传递参数的时候是传值的,就是说的会copy一份新的数据作为参数,更直白的说就是传递给函数的变量跟原来要传递的变量是不一样的,他们只是值相等而已。就像上面的传递给函数的var1参数跟ivar1变量是不一样的,var1复制了ivar1的值。所以上面的函数只是交换了var1和var2两个参数的值,而没有交换ivar1和ivar2的值。
嗯,那有什么办法可以交换ivar1和ivar2的值呢?这个时候就可以用到我们刚刚学到的指针来做了,因为我们知道指针是保存的是变量的地址,所以我们可以通过传递ivar1和ivar2的地址给函数,然后函数通过访问这两个地址来实现值的替换,代码如下:
voidswap(int *var1, int *var2) {
int tmp = *ivar1;
*ivar1 = *ivar2;
*ivar2 = tmp;
}
intmain() {
int ivar1 = 10;
intivar2 = 12;
swap(&ivar1, &ivar2);
printf("ivar1: %d, ivar2: %dn", ivar1, ivar2);
return 0;
}
这次编译运行之后,我们发现ivar1和ivar2的值已经交换了。这样就实现了通过函数把两个变量的值交换了。
还有什么不明白的话可以慢慢体会一下,如果还有什么问题可以留言。我会认真回答大家的问题的,下次讲讲指针,数值和函数的关系吧。