C语言基础之指针


大家都知道,一个完整的程序是由数据+算法所组成的,我们的教程到目前为止,只是涉及到了关于c语言的一些基础知识。而要想更深入的了解C语言就必须进一步了解算法和数据的处理,所以学习数据结构就是我们学习程序的必经之路了。这一章的指针就对我们学习数据结构有非常大的作用,弄清楚它的原理和基础运用,对我们的数据结构的学习具有非常大的作用。


一、内存,地址和内容

而想学好指针就必须先弄明白它的原理,所以我们就需要先弄明白内存,地址和内容之间的关系才能明白指针到底是什么,它在我们的C语言的运行中担任什么样的角色。

电脑的内存(尤其是指主存)是由许多“内存地址”所组成的,每个内存地址都有一个“物理地址”。而内容就是在这个内存里所存放的东西。如图

名字标识abc
地址标识101102103
内容-13.143241

在图中,名字标识就是你申请这个变量时所设定的名字,如

int a=1;

这时,整型变量a的名字标识为字母“a“,地址标识为计算机内部储存这个变量的地址内容就是你输入的数字”1“。所以每当我们需要运用字母”a“中存放的数据时,我们就可以直接”告诉“电脑我们需要**”a“或者”a”的地址**,电脑就可以直接访问存放这个数据的具体地址,从它的“内容”中取出我们想要的数据了。
如果你还不明白,我们可以那生活中的每个人的住址做比较。我们每个人的房子就像内存一样,而房子所在的地方就是我们所说的地址,而名字标识地址标识就像“xx的家”和“xx市xx街区xx号”一样的区别。至于内容就是这些房子里你所放置的东西。这么说,你明白了内存,地址和内容之间的关系了吗?

二、指针和指针变量

说完内存,地址和内容之间的关系,我们再来介绍下今天的主角——指针吧。
指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。
说白了,就是一个像路标一样的东西。它的作用就是给电脑指路,让电脑知道从哪个地址的内存中读取数据

(1)指针变量的定义

定义指针变量:

int *pt1;

这样,我们就成功申请了一个名为“pt1”的指针了。而“pt1”前面的“*”,我们把它称为“寻地址符”。与它相反的“&”,我们称作“取地址符”。现在明白我们在使用scanf函数的时候,除了输入变量名称外,还要在它前面加一个“&”是为什么了把?其实就是在把你输入的数据存入到它的“地址”所在的地方

(2)指针变量的运用

最简单的运用就是使用一个指针指向一个地址,例如:

int a=5;
int *pt1=&a;
printf("%d,%d",*pt1,pt1);

此时,程序的输出结果为

5,7339588

由输出结果不难看出,变量a的值为5,在这台电脑中存放的地址为7339588。此时pt1的值就是变量a的地址,而在pt1前加一个“去地址符”,输出的就是变量a的值。就好比加了"*"输出的就是路标所指向地址里存放的值了,而不加,输出的就是这个路标上存放的地址了

三、指针数组

看完了指针的简单介绍,我们再来把指针和我们前面学的数组结合起来。
指针数组定义的一般形式为:

类型名 *数组名[数组长度];

知道了怎么定义,那么怎么使用嘞?
它其实跟我们平时使用的数组是差不多的,不过指针数组有一个特别方便的地方,就是我们在储存一个字符串的时候,使用普通的数组,如果是一堆字符串嘞?那就要使用二维数组了。而使用一维的指针数组就能轻易的解决了。
我们都知道,字符串输出时,时以“/0”作为结束字符的,所以我们输出一串字符时,只需要知道它的第一个字符的地址,就可以将这个字符串输出了,而第一个字符的地址,我们可以用指针储存。所以有n个字符串时,我们就可以用n个指针来储存了。直接看题
例:
输入任意一个值,若小于5,则输出“oh is too small”;若等于5,则输出“yes you are right”;若大于5,则输出“oh is too big”。要求:必须使用数组。
解析:
这题我们可以使用二维数组输出,也可以使用指针数组输出。既然题目是一堆字符串,当然是使用简洁点的指针数组啦。
解:

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */

int main() {
    char *a[3]={"oh is too small","yes you are righ","oh is too big"};
    int b;
    scanf("%d",&b);
    if(b<5)
    printf("%s",a[0]);
    else if(b=5)
    printf("%s",a[1]);
    else
    printf("%s",a[2]);
	return 0;
}

输出结果:

4
oh is too small

四、指针与函数

联系完指针与数组的关系,我们再看看它和函数有啥骚操作,是不是感觉它们之间是不是好像用不到一起去?错!它们之间一结合后骚操作多的去了。我们这里就简单的介绍下最简单的,更加深入的话,我们会在数据结构中接触到的。
我直接拿题讲吧!
例:
输入两个值a,b,输出时交换值。要求:使用函数。
解析
我们都知道,函数里的值与主函数无关,除非使用宏定义,函数结束后,在函数内申请的变量会自动清零,且只能一次返回一个值。所以我们这里可以使用指针来写它。
解:

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
void fun(int *a,int *b){/*函数的参数是指针,既在此函数内运算时,主函数的值也会变化*/
	int c;
	c=*a;
	*a=*b;
	*b=c;
} 
int main() {
    int a,b;
    scanf("%d %d",&a,&b);
    fun(&a,&b);/*由于调用的函数的参数时指针,所以这里传入的就应该是a,b的地址*/
    printf("a=%d,b=%d",a,b);
	return 0;
}

程序结果:

3 2
a=2,b=3

从这里我们可以看出它的一个很直接的用法:可以在函数里面修改主函数的值。它是通过像主函数传递地址而不是传递数值来实现的。这里你可能还是没想明白,我举个例子:我们把黑板看成主函数,我在黑板上写了“a=3”和“b=2”,我们把调用函数看成请同学做题。我们普通的调用函数是直接把a,b的值复制粘贴给函数,就相当于我让同学把题目抄了下去,在他抄的纸上面交换a,b的值。他在纸上交换好了后,并不能改变我在黑板上的结果。而这一题中,我把a,b的地址给了函数,就相当于我让同学上来做题。这样,他写完后,我黑板上的题也随之改变了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值