c语言编程有关指针应用的疑惑

指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,在同一CPU构架下,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。那么如何运用指针来解决主次函数的编写呢。
比如以下实例:⑴ 编写函数fun,其返回值类型为整型,有1个整型参数n,核心功能须使用指针完成操作。
  fun的功能为:假设有n个人围成一圈,顺序排号,并从第1个人开始报数(1~7),
  凡是报到7的人退出圈子,后面的人从1开始重新报数。函数返回最后留在圈里的人的编号。
⑵ 编写主函数,其功能为:
  首先,提示用户输入1个10到100以内的整数,并存放到变量n中。
  然后,判断用户输入的数值是否满足要求,不满足则输出错误信息并终止运行。
  接着,以n作为参数,调用函数fun,将结果存放到变量result中。
  最后,输出result的值并辅以中文说明。

指针描述了数据在内存中的位置,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。


#include <stdio.h>

int fun(int *n) {
    int i, j, m;
    int a[100];
    for (i = 0; i < *n; i++) {
        a[i] = i + 1;
    }
    i = -1;  // 因为起始位置是 0,所以初始化为 -1
    m = 0;  // 记录退出圈子的人数
    while (m < *n - 1) {  // 只有一个人留下来时结束循环
        for (j = 1; j <= 7; j++) {
            i++;
            if (i == *n) {
                i = 0;  // 回到第一个人
            }
            while (a[i] == 0) {  // 如果该人已退出圈子则跳过
                i++;
                if (i == *n) {
                    i = 0;
                }
            }
        }
        a[i] = 0;  // 标记退出圈子
        m++;
    }
    for (i = 0; i < *n; i++) {  // 找到最后留下的人的编号
        if (a[i] != 0) {
            return a[i];
        }
    }
}

int main() {
    int n, result;
    printf("请输入一个10到100以内的整数:");
    scanf("%d", &n);
    if (n < 10 || n > 100) {  // 判断输入是否合法
        printf("输入错误,请重新输入\n");
        return 1;
    }
    result = fun(&n);  // 传递指向n的指针
    printf("最后留在圈里的人的编号为:%d\n", result);
    return 0;
}

通过在 fun 函数中使用指针 *n 来获取主函数中输入的值。&n 表示取 n 的地址,这个地址就是 *n 指向的内存单元,通过传递 &n,可以在 fun 函数中修改 n 的值。

通过使用指针,可以在主函数和子函数之间传递大数据,避免了传递数组和结构体时产生的数据拷贝,提高了程序的执行效率。同时,指针还可以用于动态分配内存,提高程序的灵活性和可扩展性。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7616007
  • 除此之外, 这篇博客: C语言实现八大排序算法详解及其性能之间的中的 名字已经暴露了他的算法,就是往里面插入数据,就拿我们生活中的例子来说,打扑克牌。我们往手里码牌的时候,是一张一张的码,先码一张,抓手心,不需要修改位置,因为只有一张牌,一定是有序的。再接一张,和手里的牌对比大小,调整位置,选择放在它的左边或者右边。然后接着码,又接到一张牌,拿到先和右边的牌比,比右边还大就放到最右边,如果比右边这张小呢,在和左边这张比。同样,我们这里也是这样的,首先我们默认第一个元素,一定是有序,OK吧。然后第二个,元素比较,大,放到左边,小放到右边。然后第三个元素,直到第N个,比它前一个大,继续往前找位置,直到找到对应位置了,就是有序数列了。(当然每次找位置都是在一个有序的序列中找,所以完全可以用二分查找找位置,数据大的话,二分明显快于我们一张一张比) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
  • 算法思想

  • 以下回答由chatgpt基于相关博客总结生成:
    #include <stdio.h>
    
    /**
     * 函数名称:fun
     * 函数功能:计算最后留在圈里的人的编号
     * 参数说明:
     *     n:圈中人数
     * 返回值:最后留在圈里的人的编号
     */
    int fun(int n) {
        int *a = (int*)malloc(n * sizeof(int)); // 动态分配内存存放圈中人数
        int remaining = n; // 剩余未退出圈子的人数
        int count = 0; // 报数
        int i = 0; // 数组下标
    
        // 初始化圈中人数及每个人的编号
        for (i = 0; i < n; i++) {
            a[i] = i + 1;
        }
    
        // 模拟报数并退出圈子
        while (remaining > 1) {
            for (i = 0; i < n; i++) {
                if (a[i] != -1) { // 如果这个人还在圈里
                    count++;
                    if (count == 7) { // 报到7的人退出圈子
                        count = 0;
                        a[i] = -1; // 标记退出圈子的人
                        remaining--;
                        if (remaining == 1) { // 仅剩一人时退出循环
                            break; 
                        }
                    }
                }
            }
        }
    
        // 查找仍在圈里的人的编号
        for (i = 0; i < n; i++) {
            if (a[i] != -1) {
                break;
            }
        }
    
        free(a); // 释放动态分配的内存
    
        return a[i];
    }
    
    /**
     * 主函数
     */
    int main() {
        int n, result;
        printf("请输入一个10到100以内的整数:");
        scanf("%d", &n);
    
        if (n < 10 || n > 100) { // 判断输入是否合法
            printf("输入不合法。\n");
            return 0;
        }
    
        result = fun(n);
        printf("最后留在圈里的人的编号是%d。\n", result);
    
        return 0;
    }