谈谈C语言的指针

C/C++
279
0
0
2022-11-14

C语言的指针是啥?

举个栗子:新学期到了,小明正式开启了自己的大学生活,他的课表显示,今天上午十点,在教一204教室有一节计算机专业课。小明迫不及待的来到教一,但他不知道教一204教室是哪间教室。这个时候,他在教一门口看见了一个指路牌,上面就写着教一204教室的具体位置,于是他直奔教一204教室开始上课。

上述栗子中提到的 指路牌 顾名思义,就类似于C语言的指针。

指针的专业术语: 指针是一种编程语言对象,它是存储位于计算机内存中的另一个值的内存地址。 参考资料:《C++ Primer Plus》

我们在编写C语言代码时,当写下一个 int a; 计算机就会帮我们在内存中给这个a分配一个内存,当我们对a赋值6时,计算机就会满世界的在内存中寻找这个a的地址,功夫不负有心人,终于找到了a的地址,于是计算机就把6放到了对应的内存里存储数据。试想,这样效率是不是很低?为了一个简单的赋值工作,计算机就需要在内存条里满世界的找a的地址。丹尼斯·里奇就想,这样执行效率太低了,于是就发明了指针。有了指针,我们只需再写下一个 int *p = a; 计算机就会帮我们做一件事,将a的内存地址值告诉p,此时,*p就是a,我们只需对*p赋值6,于是计算机就直奔到a的内存地址存储数据。

举个栗子:

用指针实现a和b值的交换,源代码如下:

#include <stdio.h>
int main() {
    int a = 10, b = 5;
    int *pa = &a, *pb = &b, *pt;
    pt = pa;
    pa = pb;
    pb = pt;
    printf("a=%d\nb=%d\n", *pa, *pb);
    return 0;
}

我们知道,int类型的函数只能return回来一个参数,假设我们现在要return三个参数或多个参数,该怎么办?有人会想声明几个全局变量,强行让函数返回多个值。这里我补充一下:当我们的代码量比较小时,使用全局变量不会造成很大的影响,反之,代码量、函数名和变量名比较多时,就要格外小心了。下面我来引用一位大佬的总结:

①全局变量是所有的函数外部定义的变量,它的作用域是整个程序,也就是所有的源文件,包括.c和.h文件,和函数的模块化编程相违背,不利于程序的修改、调试和移植。编写函数时,最好用传参返回值来和外部交换数据,不要用全局变量。但有时候又不得不使用全局变量,定义了太多的全局变量,会破坏程序的结构性。 ②全局变量是在程序开始运行之前的初始化阶段就诞生,到整个程序结束退出的时候才死亡,始终占用数据段上的空间,一定程度上造成了内存浪费。 ③在面向对象的程序设计中,全局变量的初始化顺序不能确定,因编译器不同而不同,在面向对象的领域就变成了构造对象的顺序不确定,会造成无法预估的灾难性后果 参考链接:https://blog.csdn.net/wangpan0330/article/details/89065486

最佳的方案还是用函数指针,将函数中返回的参数直接存储在内存中,这样就实现了函数传递多个参数。

举个栗子:

现有十位同学的成绩,请你用指针函数编写一个程序,求他们的最高分,最低分,平均分。源代码如下:

#include <cstdio>
void student(int *pa, int len, int *pmax, int *pmin, int *pave);
int main() {
    int a[] = {99, 60, 75, 85, 55, 42, 22, 33, 55, 96};
    int len = sizeof(a) / sizeof(a[0]);
    int max = 0, min = 0, ave = 0;
    int *pmax = &max, *pmin = &min, *pave = &ave;
    student(a, len, pmax, pmin, pave);
    printf("max = %d\nmin = %d\nave = %d\n", *pmax, *pmin, *pave);
    return 0;
}
void student(int *pa, int len, int *pmax, int *pmin, int *pave) {
    for (int i = 0; i < len - 1; ++i) {
        for (int j = 0; j < len - 1 - i; ++j) {
            if (*(pa + j) > *(pa + j + 1)) {
                int t = *(pa + j);
                *(pa + j) = *(pa + j + 1);
                *(pa + j + 1) = t;
            }
        }
    }
    for (int k = 0; k < len; ++k) {
        *pave += *(pa + k);
    }
    *pave /= len;
    *pmax = *(pa + len - 1);
    *pmin = *pa;
}