指针知识(二) 指针用途举例

指针

本文目录

五、指针的用途举例

1.例子1

前面我们通过指针变量p间接访问了变量a,在有些人看来,觉得指针变量好傻B,直接用变量名a访问变量a不就好了么,干嘛搞这么麻烦。别着急,接下来举个例子,让大家看看指针还能做什么事情。

现在有个要求:写一个函数swap,接收2个整型参数,功能是互换两个实参的值。

1> 如果没学过指针,你可能会这样写

复制代码
 1 void swap(char v1, char v2) {
 2     printf("更换前:v1=%d, v2=%d\n", v1, v2);
 3     
 4     // 定义一个中间变量
 5     char temp;
 6     
 7     // 交换v1和v2的值
 8     temp = v1;
 9     v1 = v2;
10     v2 = temp;
11     
12     printf("更换后:v1=%d, v2=%d\n", v1, v2);
13 }
14 
15 int main()
16 {
17     char a = 10, b = 9;
18     printf("更换前:a=%d, b=%d\n", a, b);
19     
20     swap(a, b);
21     
22     printf("更换后:a=%d, b=%d", a, b);
23     return 0;
24 }
复制代码

输出结果:,虽然v1和v2的值被交换了,但是变量a和b的值根本就没有换过来。因为基本数据类型作为函数实参时,只是纯粹地将值传递给形参,形参的改变并不影响实参。

我们可以简要分析一下这个过程:

* 在第20行中,将变量a、b的值分别传递给了swap函数的两个形参v1、v2

* 在第8行中,将v1的值赋值给了temp

* 在第9行中,将v2的值赋值给了v1

* 在第10行中,将temp的值赋值给了v2

就这样,v1和v2的值被交换了,但是a和b的值一直都没有改变

 

2> 如果学了指针,就应该这样写

复制代码
 1 void swap(char *v1, char *v2) {
 2     // 中间变量
 3     char temp;
 4     
 5     // 取出v1指向的变量的值
 6     temp = *v1;
 7     
 8     // 取出v2指向的变量的值,然后赋值给v1指向的变量
 9     *v1 = *v2;
10     
11     // 赋值给v2指向的变量
12     *v2 = temp;
13 }
14 
15 int main()
16 {
17     char a = 10, b = 9;
18     printf("更换前:a=%d, b=%d\n", a, b);
19     
20     swap(&a, &b);
21     
22     printf("更换后:a=%d, b=%d", a, b);
23     return 0;
24 }
复制代码

先看看输出结果:,变量a和b的值终于换过来了。

解释一下:

(在16位编译器环境下,一个指针变量占用2个字节)

* 先注意第20行,传递是变量的地址。因此swap函数的形参v1指向了变量a,v2指向了变量b

* 第6行代码是取出v1指向的变量的值,也就是变量a的值:10,然后赋值给变量temp

* 第9行代码是取出v2指向的变量(变量b)的值,然后赋值给v1指向的变量(变量a)

* 第12行代码是将temp变量的值赋值给v2指向的变量(变量b)

相信你已经感受到指针的强大了,如果没有指针,在一个函数的内部根本改变不了外部的实参

 

2.例子2

接下来再举一个指针的实用例子。默认情况下,一个函数只能有一个返回值,有了指针,我们可以实现函数有"多返回值"。

现在有个要求:写一个函数sumAndMinus,可以同时计算2个整型的和与差,函数执行完毕后,返回和与差(注意了,这里要返回2个值)

复制代码
// 计算2个整型的和与差
int sumAndMinus(int v1, int v2, int *minus) {
    // 计算差,并赋值给指针指向的变量
    *minus = v1 - v2;
    
    // 计算和,并返回和
    return v1 + v2;
}

int main()
{
    // 定义2个int型变量
    int a = 6, b = 2;

    // 定义2个变量来分别接收和与差
    int sum, minus;

    // 调用函数
    sum = sumAndMinus(a, b, &minus);   //传入的是一个指针变量,这里就是使用&minus代表指针
    
    // 打印和
    printf("%d+%d=%d\n", a, b, sum);
    
    // 打印差
    printf("%d-%d=%d\n", a, b, minus);
    return 0;
}
复制代码

输出结果:,和与差都由同一个函数计算并返回出来。和是函数的直接返回值,差是通过函数的第3个指针参数间接返回。

因此有了指针,我们可以让函数有"无限个"返回值。

 

六、关于指针的疑问

刚学完指针,都可能有一大堆的疑惑,这里我列出几个常见的疑惑吧。

1.一个指针变量占用多少个字节的内存空间?占用的空间是否会跟随所指向变量的类型而改变?

在同一种编译器环境下,一个指针变量所占用的内存空间是固定的。比如,在16位编译器环境下,任何一个指针变量都只占用2个字节,并不会随所指向变量的类型而改变。

 

2.既然每个指针变量所占用的内存空间是一样的,而且存储的都是地址,为何指针变量还要分类型?而且只能指向一种类型的变量?比如指向int类型的指针、指向char类型的指针。

其实,我觉得这个问题跟"数组为什么要分类型"是一样的。

* 看下面的代码,利用指针p读取变量c的值

复制代码
1 int i = 2;
2 char c = 1;
3 
4 // 定义一个指向char类型的指针
5 char *p = &c;
6 
7 // 取出
8 printf("%d", *p);
复制代码

这个输出结果应该难不倒大家:,是可以成功读取的。

* 如果我改一下第5行的代码,用一个本应该指向int类型变量的指针p,指向char类型的变量c

int *p = &c;

我们再来看一下输出:c的原值是1,现在取出来却是513,怎么回事呢?这个要根据内存来分析

根据变量的定义顺序,这些变量在内存中大致如下图排布:

其中,指针变量p和int类型变量i各占2个字节,char类型的c占一个字节,p指向c,因此p值就是c的地址    字节 : 位 = 8 : 1

1> 最初的时候,我们用char *p指向变量c。当利用*p来获取变量c的值时,由于指针p知道变量c是char类型的,所以会从ffc3这个地址开始读取1个字节的数据:0000 0001,转为10进制就是1

2> 后来,我们用int *p指向变量c。当利用*p获取变量c的值时,由于指针p认为变量c是int类型的,所以会从ffc3这个地址开始读取2个字节的数据:0000 0010 0000 0001,转为10进制就是513

可见,给指针分类是多么重要的一件事,而且一种指针最好只指向一种类型的变量,那是最安全的。


资料来源:http://www.cnblogs.com/mjios/archive/2013/03/16/2963645.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值