C语言指针与数组-学习二十三
C语言指针与数组-学习二十三
2022-02-17 / 0评论 / 297阅读 / 0点赞
-- XG.孤梦

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

XG.孤梦
2022-02-17 / 0 评论 / 297 阅读 / 正在检测是否收录...

指针变量作为函数参数

  • 函数的参数不仅可以是整型、浮点型、字符型等数据,还可以是指针类型。
  • 它的作用是将一个变量的地址传送到另一个函数中
  • 例如:void swap(int *a,int *b)
#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;
}

36311-krn7qehijjd.png

  • 注意:
    函数的调用可以(而且只可以)得到一个返回值(即函数值),而使用指针变量作参数,可以得到多个变化了的值。如果不用指针变量是难以做到这一点的。
  • 如果想通过函数调用得到n个要改变的值

    • 1.在主调函数中设n个变量,用n个指针变量指向它们
    • 2.设计一个函数,有n个指针形参。在这个函数中改变这n个形参的值
    • 3.在主调函数中调用这个函数,在调用时将这n个指针变量作实参,将它们的地址传给该函数的形参
    • 4.在执行该函数的过程中,通过形参指针变量,改变它们所指向的n个变量的值
    • 5.主调函数中就可以使用这些改变了值的变量。
  • 例子
输入3个整数a,b,c,要求按由大到小的顺序将它们输出。用函数实现。
#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);
    }
}

29454-0720rcvbi90q.png


数组元素的指针

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

1.png


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

  • 在指针指向数组元素时,允许以下运算:

    • 一加一个整数(用 + 或 +=),例如:p + 1
    • 一减一个整数(用 - 或 -=),例如:p - 1
    • 一两个指针相减,如 p1-p2 (只有p1和p2都指向同一数组中的元素时才有意义)
  • 如果指针变量p已指向数组中的一个元素

    • p+1指向同一数组中的下一个元素;
    • p-1指向同一数组中的上一个元素。
  • 如果p的初值为&a[0],则

    • p+i 和 a+i 就是数组元素a[i]的地址
    • 或者说,它们指向a数组序号为i的元素。
  • 例如
#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);
}

53332-ju2jz9gij2s.png

  • 当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所指的元素 之间有多少个元素
    • 两个指针变量相减 的含义是 两个地址之差 除以 每个数组元素所占的字节数
  • 例子
#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个字节
}

44445-102th4toxkej.png

  • *++p,等价于 *(++p),先使 p+1指向下一个数组元素,再取 *p 作为此表达式的值。
  • *p++,等价于 *(p++),取 p 作为此 表达式的值,再使 p+1
  • (*p)++,先取 p 所指向的 元素值 作为 此表达式的值,再将 该元素值加1
  • ++(*p),将 p 所指向的 元素值加1 作为 此表达式的值
#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));
}

32523-kndlkc16em.png


通过指针引用数组元素

  • 引用一个数组元素,可用下面两种方法:

    • 1.下标法,例如:a[i]
    • 2.指针法,例如:*(a+i)*(p+i)
      其中a是数组名,p 是指向数组元素的指针变量,其初值 p = a
  • 例子
有一个整型数组a,有10个元素,要求输出数组中的全部元素。
#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");
}

64509-bqhkkrqoc98.png

  • 3种方法的比较:

    • 第(1)和第(2)种方法执行效率相同
    • C编译系统是将 a[i] 转换为 *(a+i)处理的,即先计算元素地址。
    • 因此用第(1)和第(2)种方法找数组元素费时较多

      • 第(3)种方法比第(1)、第(2)种方法快
    • 用指针变量直接指向元素,不必每次都重新计算地址。
    • 这种有规律地改变地址值 例如 p++ 能大大提高执行效率。

      • 用下标法比较直观,能直接知道是第几个元素。
      • 用地址法或指针变量的方法不直观,难以很快地判断出当前处理的是哪一个元素。

0

评论

博主关闭了所有页面的评论