前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言指针与数组-学习二十三

C语言指针与数组-学习二十三

作者头像
XG.孤梦
发布2022-03-01 14:21:48
2590
发布2022-03-01 14:21:48
举报
文章被收录于专栏:日志随记日志随记

本文最后更新于2022年02月17日,已超过11天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!

指针变量作为函数参数

  • 函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。
  • 它的作用是将一个变量的地址传送到另一个函数中
  • 例如:void swap(int *a,int *b)
代码语言:javascript
复制
#include <stdio.h>

void main() {
    void swap(int *x, int *y);
    int a,b;
    int *a1 = &a;
    int    *b1 = b;

    printf("请输入a,b的值:\n");
    scanf_s("%d %d", &a, &b);

    if (a < b) {
        swap(a1, b1);
    }
    printf("max = %d, min=%d\n", a, b);
}

void swap(int *x, int *y) {
    int p;
    p = *x;
    *x = *y;
    *y = p;
}
  • 注意: 函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。
  • 如果想通过函数调用得到n个要改变的值
    • 1.在主调函数中设n个变量,用n个指针变量指向它们
    • 2.设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值
    • 3.在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的地址传给该函数的形参
    • 4.在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值
    • 5.主调函数中就可以使用这些改变了值的变量。
  • 例子

输入3个整数a,b,c,要求按由大到小的顺序将它们输出。用函数实现。

代码语言:javascript
复制
#include <stdio.h>

void main() {
    void exchange(int *x, int *y,int *z);
    int a,b,c;
    int *a1 = &a;
    int    *b1 = &b;
    int *c1 = &c;
    printf("请输入a,b,c的值:\n");
    scanf_s("%d %d %d", &a, &b, &c);
    exchange(a1,b1,c1);
    printf("%d, %d, %d\n", a,b,c);
}

void swap(int *x, int *y) {
    int p;
    p = *x;
    *x = *y;
    *y = p;
}

void exchange(int *x, int *y, int *z) {
    void swap(int *x, int *y);
    if (*x < *y) {
        swap(x, y);
    }
    if (*x < *z) {
        swap(x, z);
    }
    if (*y < *z) {
        swap(y, z);
    }
}

数组元素的指针

  • 一个变量有地址,一个数组包含若干元素,每个数组元素都有相应的地址。
  • 指针变量可以指向数组元素(把某元素的地址放到一个指针变量中)。
  • 数组元素的指针就是数组元素的地址

引用数组元素时指针的运算

  • 在指针指向数组元素时,允许以下运算:
    • 一加一个整数(用 + 或 +=),例如:p + 1
    • 一减一个整数(用 - 或 -=),例如:p - 1
    • 一两个指针相减,如 p1-p2 (只有p1和p2都指向同一数组中的元素时才有意义)
  • 如果指针变量p已指向数组中的一个元素
    • p+1指向同一数组中的下一个元素;
    • p-1指向同一数组中的上一个元素。
  • 如果p的初值为&a[0],则
    • p+i 和 a+i 就是数组元素a[i]的地址
    • 或者说,它们指向a数组序号为i的元素。
  • 例如
代码语言:javascript
复制
#include <stdio.h>

void main() {
    int a[5] = {1,2,3,4,5};
    int *a1 = &a[0]; // 或者 int *a1 = a
    printf("%d, %d\n", *a1, a1);
    a1 = a1 + 2;
    printf("%d, %d\n",*a1, a1);
}
  • 当p指向a数组首元素时,数组元素 a[i] 的地址表达式有以下四种:
    • &a[i]
    • a + i
    • p + i
    • &p[i]
  • 当p指向a数组首元素时,数组元素 a[i] 的值表达式有以下四种:
    • a[i]
    • *(a + i)
    • *(p + i)
    • p[i]
  • a 和 p 是有本质的区别:
    • a 是指针常量,其值不可变;
    • p 是指针变量,其值可变。
    • 所以,a++、a = p 等都是非法表达式;
    • 而 p++、p = a都是合法的表达式。
  • 如果 指针p1 和 p2 都指向同一数组
    • p2 - p1 用来计算 p2所指的元素 与 p1所指的元素 之间有多少个元素
    • 两个指针变量相减 的含义是 两个地址之差 除以 每个数组元素所占的字节数
  • 例子
代码语言:javascript
复制
#include <stdio.h>

void main() {
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p1 = &a[0];
    int *p2 = &a[6];
    printf("p1的地址:%d\n",p1);
    printf("p2的地址:%d\n",p2);
    printf("%d\n", p2 - p1);
    printf("%d\n",*p2 - *p1);  // int 为4个字节
}
  • *++p,等价于 *(++p),先使 p+1指向下一个组元素,再取 *p 作为此表达式的值。
  • *p++,等价于 *(p++),取 p 作为此 表达式的值,再使 p+1
  • (*p)++,先取 p 所指向的 元素值 作为 此表达式的值,再将 该元素值加1
  • ++(*p),将 p 所指向的 元素值加1 作为 此表达式的值
代码语言:javascript
复制
#include <stdio.h>

void main() {
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p = &a[0];
    printf("%d\n",*p);
    printf("%d\n",*++p);
    printf("%d\n",*p++);
    printf("%d\n",(*p)++);
    printf("%d\n",++(*p));
}

通过指针引用数组元素

  • 引用一个数组元素,可用下面两种方法:
    • 1.下标法,例如:a[i]
    • 2.指针法,例如:*(a+i)*(p+i) 其中a是数组名,p 是指向数组元素的指针变量,其初值 p = a
  • 例子

有一个整型数组a,有10个元素,要求输出数组中的全部元素。

代码语言:javascript
复制
#include <stdio.h>

void main() {
    int a[10] = {1,2,3,4,5,6,7,8,9,10};
    int *p;

    // 下标法
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");

    // 通过数组名计算数组元素地址
    for (int i = 0; i < 10; i++) {
        printf("%d ", *(a+i));
    }
    printf("\n");

    // 指针法
    for (p=a; p <a+10; p++) {
        printf("%d ", *p);
    }
    printf("\n");
}
  • 3种方法的比较:
    • 第(1)和第(2)种方法执行效率相同
      • C编译系统是将 a[i] 转换为 *(a+i)处理的,即先计算元素地址。
      • 因此用第(1)和第(2)种方法找数组元素费时较多
    • 第(3)种方法比第(1)、第(2)种方法快
      • 用指针变量直接指向元素,不必每次都重新计算地址。
      • 这种有规律地改变地址值 例如 p++ 能大大提高执行效率。
    • 用下标法比较直观,能直接知道是第几个元素。
    • 用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-02-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 指针变量作为函数参数
  • 数组元素的指针
    • 引用数组元素时指针的运算
      • 通过指针引用数组元素
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档