C基础系列教程7——指针1

该系列文章内容可能来源我本人或者zhrmoe(他的主页:http://zhrmoe.iflab.org/)的编写。文章如果有错误欢迎批评指正,谢谢!转载请注明来自本站,另外,本系列教程中的代码建议初学者自己手打一遍,不要直接复制(由于某些奇怪的原因可能会导致你复制的代码出现错误!相信自己的双手吧=-=
如果你觉得进度太快,可以等你熟悉了前面的内容后再继续往下看

     接下来主要是指针和结构体的使用,以及堆内存的分配。这些内容非常非常非常重要,将会在数据结构中大量使用,如果这些不懂,写数据结构的代码会比较困难。

首先是指针的使用,请思考,如何写一个函数,实现两个参数内容的交换?
比如我传入a = 1, b = 2,要求用函数交换这两个内容,你可能会写出这样的代码

void swap1(int a, int b) {

    
int t = a;

    a = b;

    b = t;

}

最初的想法一定是这样的,你肯定会想,直接把两个变量交换一下不就结了- –
你可以使用这段代码来测试这个函数

#include <stdio.h>

void swap1(int a, int b) {

    
int t = a;

    printf(
"In swap1:\n");

    printf(
"a = %d, b = %d\n", a, b);

    a = b;

    b = t;

    printf(
"a = %d, b = %d\n", a, b);

    printf(
"swap1 end\n");

}

int main() {

    
int a = 1;

    
int b = 2;

    printf(
"Before swap1\n");

    printf(
"a = %d, b = %d\n", a, b);

    swap1(a, b);

    printf(
"a = %d, b = %d\n", a, b);

    system(
"pause");

    
return 0;

}


        你会发现运行结果是这样的
当swap1之中结束之前,两个变量的值还是被交换的,但是当回到主函数中的时候,两个变量的值又回到了交换前的状态。
原因是这样的,函数的参数在主程序时候传入的那个a,和函数中的a,在这个例子中名字都是a,但实际上确实两个不同的变量,当传入一个参数给函数时候,电脑会把传入的参数变量原封不动的复制一遍,当函数执行完毕后,复制出来的那份变量会被电脑销毁。所以当你在swap1中交换两个变量的时候,实际操作的是复制出来的那份a和b,原来的那份a和b根本就没被交换,所以才会出现函数执行之后回到交换之前的状态。

那么怎么解决这个问题呢?
变量实际上是存在内存中的,你可以想象成一个巨大的表格,每个单元格有自己的地址,如图所示,左侧的0xXXXXXXXX是个16进制的数字,就是这个单元格的地址,可以理解为这个格子的编号。执行完int a = 1;之后,电脑就会分配4个单元格(4个字节)当作变量a,并且把内容改为00000001(从下往上看,栈内存分配是从高到低分配,不懂也没关系,不要在意这些细节)
想一下,函数参数的传递既然都是值传递(也就是刚才说的原封不动的复制一份以前的内容放到一个新的地方),那么可不可以把单元格的地址传给函数,在函数内部更改指定地址的内容呢?答案是可以的,这样就引出了指针,我们把储存内存地址的变量叫做指针,如下图,储存了上图中变量a的地址。接下来介绍指针的基本语法
在C语言中, 我们使用*来声明一个指针变量(也可以称作地址变量),使用&符号取一个变量的地址(这下知道为什么scanf的时候不能忘记&符号了吧),使用*来取出指针所指向地址中的内容(也就是取值),示例代码如下

#include<stdio.h>

int main() {

    
int a = 5;

    
int* pa = &a;

    printf(
"&a = %p\n", &a);

    printf(
"a = %d\n", a);

    printf(
"&pa = %p\n", &pa);

    printf(
"pa = %p\n", pa);

    printf(
"*pa = %d\n", *pa);

    system(
"pause");

    
return 0;

}


需要注意的是,要注意区分两次星号的意义,第一个星号是声明一个整数类型的指针(四个字节,储存的是地址),第二个星号的意思是,先取出pa中的地址,再取出这个地址中的内容,是个间接的访问。(补充一点,在printf中%p用来显示内存地址,%d就不用说了吧)
你可以多次运行这段代码观察结果的规律,内存状态如下图所示。需要注意的是,你的运行结果和我图中结果一样的几率很小,但是规律肯定是一样的,因为每次运行电脑分配的内存都不一样。后两张是内存的状态,注意观察规律。

    

下一次介绍指针的应用之一,当作参数传递给函数,这样就可以解决开始提出的问题。。。
转载请注明出处,谢谢!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

24 + = 29