一道题目让你看出C语言的数组与指针的区别:

一道题目让你看出C语言的数组与指针的区别:,第1张

文章目录
    • 题目概述:
      • 输入格式:
      • 输出格式:
      • 输入输出样例:
    • C语言题解:
      • 错误的运行结果:
    • 错误问题的分析与定位:
      • C库的malloc函数讲解:
      • 函数原型:
      • 函数形参:
      • 函数的返回值:
      • 内存的释放:
      • 内存释放需要注意野指针:
    • Bug定位
      • 数组与指针的区别:
    • 解决Bug
    • 正确的此题题解代码

题目概述:
### 题目描述:

某医院进行一项研究,想知道某项疾病是否与年龄有关。因此对以往的诊断记录进行整理,统计 0-18 、 19-35 、 36-60、 61 及以上这四个年龄段的患者人数占总患者人数的比例

输入格式:

输入共 22 行。

第一行包含一个整数 NN(0n≤100),表示总患者人数。

第二行包含 NN 个整数,代表这 NN 个患者就诊时的年龄。

输出格式:

输出共 44 行。

第 11 行包含一个百分数,这个百分数保留小数点后 22 位,代表 0-180−18 岁这个年龄段的患者人数占总患者人数的比例。

第 22 行包含一个百分数,这个百分数保留小数点后 22 位,代表 19-3519−35 岁这个年龄段的患者人数占总患者人数的比例。

第 33 行包含一个百分数,这个百分数保留小数点后 22 位,代表 36-6036−60 岁这个年龄段的患者人数占总患者人数的比例。

第 44 行包含一个百分数,这个百分数保留小数点后 22 位,代表 6161 岁及以上这个年龄段的患者人数占总患者人数的比例。

输入输出样例:

C语言题解:

首先让我们先来看看如下的代码解题:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int main() {
    int N;
    scanf("%d", &N);
    int *People = (int *) malloc(sizeof(int) * N);
    int *num = (int *) malloc(sizeof(int) * 4);
    printf("%d\n", sizeof(num));
    memset(num, 0, sizeof(num));
    for (int i = 0; i < N; ++i) {
        scanf("%d", &People[i]);
        if (0 <= People[i] && People[i] <= 18) {
            num[0]++;
        } else if (19 <= People[i] && People[i] <= 35) {
            num[1]++;
        } else if (36 <= People[i] && People[i] <= 60) {
            num[2] += 1;
//            printf("%d\n", num[2]);
        } else if (People[i] >= 61) {
            num[3]++;
        }
    }
    for (int i = 0; i < 4; ++i) {
        printf("%.2lf%%\n", 100.0 * num[i] / N);
    }
    free(People);
    free(num);
    return 0;
}
错误的运行结果:

发现为啥我都开辟了内存,并相应对内存进行了清空 *** 作,可num变量的值还是感觉怎么还是这么奇奇怪怪呢?不要急,来听听我下回分解,嘻嘻

错误问题的分析与定位: C库的malloc函数讲解:

C语言编程环境使用本函数之前需要需要使用包含个头文件#includefont>

函数原型:

C库的malloc函数讲解:

  void *__cdecl malloc(size_t _Size);
函数形参:

是指定开辟到堆区内存的大小,这里你可以把它类比成数组,类似于

#define Num_Size 10
    int N[Num_Size];
函数的返回值:

函数在堆区内存开辟成功则返回指向被分配内存的指针,否则返回空指针。我们一般最好可以用程序看看是否开辟成功,代码如下:

  int N;
    scanf("%d", &N);
    int *People = (int *) malloc(sizeof(int) * N);
    if(!People) exit(1);

这段代码的意思是,开辟一个10个int大小的内存,开辟失败程序直接退出。

内存的释放:

内存的释放需要使用一个叫free的函数来释放我们在堆区开辟的内存。

函数原型:

  void __cdecl free(void *_Memory);

形参我们只需要传入需要释放内存的指向的指针即可。

内存释放需要注意野指针:

free()函数只是将内存的大小,释放归还的,**But!!**指向该内存的指针还是存在的!也就是传说中的野指针!避免野指针的方法就是,把指向该内存的指针指向NULL即可!font

int *People = (int *) malloc(sizeof(int) * N);
free(People);
People = NULL;

由于本人刷题,内存就用一次,就没考虑那么多

Bug定位 数组与指针的区别:

sizeof计算的是指针占用内存的大小,那我们来看看int占几个字节?

#include "stdio.h"


int main() {
    printf("%d", sizeof(int));
};

运行结果

int占4个Byte!

我们再来看如下程序:

#include 
int main()
{
    int *a = NULL;
    printf("%d\n", sizeof(a));
    return 0;
}

这程序打印结果是多少呢?

程序运行起来了:

结果是8!

没错sizeof计算的是指针占用内存的大小,在32位系统中输出是4,在64位系统中输出的是8。

那我接下来修改下程序

#include 

int main() {
    char a[] = "123456";
    char *b = "123456";
    printf("%d %d\n", sizeof(a), sizeof(b));
    return 0;
}

这个打印结果又是多少呢?

打印结果如下:

很容易发现 sizeof(a)打印出来的是数组元素的个数,sizeof(b)打印出来的是指针占用内存的大小

解决Bug

那好我们继续回到之前的题目,我们的memset(num, 0, sizeof(num));置0的内存大小是不为8个Byte,可是我们却开开辟了(sizeof(int) * 4) 16Byte的字节,是不是num[2],num[3]内存没有清空。

正确解决办法是:将memse代码替换如下:

  memset(num, 0, sizeof(int) * 4);
正确的此题题解代码
#include "stdio.h"
#include "stdlib.h"
#include "string.h"


int main() {
    int N;
    scanf("%d", &N);
    int *People = (int *) malloc(sizeof(int) * N);
    int *num = (int *) malloc(sizeof(int) * 4);
    printf("%d\n", sizeof(num));
    memset(num, 0, sizeof(int) * 4);
    for (int i = 0; i < N; ++i) {
        scanf("%d", &People[i]);
        if (0 <= People[i] && People[i] <= 18) {
            num[0]++;
        } else if (19 <= People[i] && People[i] <= 35) {
            num[1]++;
        } else if (36 <= People[i] && People[i] <= 60) {
            num[2] += 1;
        } else if (People[i] >= 61) {
            num[3]++;
        }
    }
    for (int i = 0; i < 4; ++i) {
        printf("%.2lf%%\n", 100.0 * num[i] / N);
    }
    free(People);
    free(num);
    return 0;
}


运行效果

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/872750.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存