【 C 】动态内存分配实用案例(一)之读取、排序和打印一列整形值

举报
李锐博恩 发表于 2021/07/15 08:34:19 2021/07/15
【摘要】 什么时候用动态内存分配呢?下面这个案例给出了一个比较实用且精彩地使用动态内存的场合,并且教你如何合理地使用动态内存分配? 动态内存分配一个常见的用途就是为那些长度在运行时才知的数组分配内存空间。 下面这个程序读取一列整数,并按升序排列它们,最后打印这个列表(由于这个程序的重点不是排序,所以排序函数并未给出,而是用一个调用代表了下!) 本程序来自于《C与指针》! //...

什么时候用动态内存分配呢?下面这个案例给出了一个比较实用且精彩地使用动态内存的场合,并且教你如何合理地使用动态内存分配?

动态内存分配一个常见的用途就是为那些长度在运行时才知的数组分配内存空间。

下面这个程序读取一列整数,并按升序排列它们,最后打印这个列表(由于这个程序的重点不是排序,所以排序函数并未给出,而是用一个调用代表了下!)

本程序来自于《C与指针》!



  
  1. //读取、排序和打印一列整形值
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. //该函数有'qsort'调用,用于比较整形值
  5. int compare_integers( void const *a, void const *b )
  6. {
  7. register int const *pa = a;
  8. register int const *pb = b;
  9. return *pa > *pb ? 1 : ( *pa < *pb ? -1 : 0 );
  10. }
  11. int main()
  12. {
  13. int *array;
  14. int n_values;
  15. int i;
  16. //观察共有多少个值,这个时候确定有多少个需要比较的整形值
  17. printf("How many values are there? ");
  18. if( scanf( "%d", &n_values ) != 1 || n_values < 0 ) //如果按照规定输入的话,scanf函数返回1,如果返回值不为1,则输入出错。
  19. {
  20. printf( "Illegal number of values.\n" );
  21. exit( EXIT_FAILURE );
  22. }
  23. //分配内存,用于存储这些值
  24. for( i = 0; i < n_values; i ++ )
  25. {
  26. printf( "? ");
  27. if( scanf( "%d", array + i ) != 1 )
  28. {
  29. printf( "Error reading value #%d\n", i )
  30. free( array );
  31. exit( EXIT_FAILURE );
  32. }
  33. }
  34. //对这些值进行排序
  35. qsort( array, n_values, sizeof( int ), compare_integers );
  36. //打印这些值
  37. for( i = 0; i < n_values; i ++ )
  38. {
  39. printf( "%d\n", *( array + i ) );
  40. }
  41. //释放内存并退出
  42. free( array );
  43. return EXIT_SUCCESS;
  44. }

说点题外话,《C与指针》这本书的可贵之处在于它的代码很整洁规范,不像某大学谭什么编写的教材,代码简直就是给出了一个反面教材来当正面教材!

合理的使用空格会让程序更具有可读性!上面的程序把空格的使用体现的淋漓尽致!

每次运行这个程序的时候,你都必须确定输入的整型值的个数,每次运行的时候,输入的整型值个数可能不一样,所以,用动态内存分配(也就是这个例子)就很合适了。

用于保存这个列表的内存是动态分配的,这样当你编写程序时就不必猜测用户可能希望对多少个值进行排序。可以排序的值的数量仅受分配给这个程序的动态内存数量的限制。但是,当程序对一个小型的列表进行排序时,它实际分配的内存就是实际需要的内存,因此不会造成浪费。

上面那个程序该添加的不该添加的注释我都基本加了,我认为这个程序是非常好的,从我这个菜鸟以前读过的书中,就没有注意到程序如此严谨地判断数字输入是否合法,不合法如何?动态内存分配失败又该如何?读取数值不合法如何?程序严谨地体现了这些问题,值得学习!


关于scanf函数返回值的问题,我这里搜索了一个比较精彩的说法:

1. scanf 函数是有返回值的,它的返回值可以分成三种情况
  1) 正整数,表示正确输入参数的个数。例如执行 scanf("%d %d", &a, &b);
      如果用户输入"3 4",可以正确输入,返回2(正确输入了两个变量);
      如果用户输入"3,4",可以正确输入a,无法输入b,返回1(正确输入了一个变量)。
  2) 0,表示用户的输入不匹配,无法正确输入任何值。如上例,用户如果输入",3 4",返回0。
  3) EOF,这是在stdio.h里面定义的常量(通常值为-1),表示输入流已经结束。在Windows下,用户按下CTRL+Z(会看到一个^Z字符)再按下回车(可能需要重复2次),就表示输入结束;Linux/Unix下使用CTRL+D表示输入结束。

所以可以使用下面的代码来处理输入:
while (scanf("%s %c %c", str, &oldchar, &newchar) == 3) /* 或!= EOF , 但前者更好 */
{
    ; //处理
}

2. 为什么前面 scanf 的格式串里面,%s和%c中间需要空格呢?
  那是因为如果没空格的话。。。oldchar输入的就是空格了= =.

3. 顺便说一下,printf的返回值是输出的字符数,例如,printf("1234")的返回值是4,而printf("1234\n")的返回值是5。

来自于:https://www.douban.com/note/220299804/


最后一个问题就是程序中的exit函数:

函数的参数声明如下:

#define    EXIT_SUCCESS    0
#define    EXIT_FAILURE    1

函数名: exit()

所在头文件:stdlib.h(如果是”VC6.0“的话头文件为:windows.h)

功 能: 关闭所有文件,终止正在执行的进程。

exit(0)表示正常退出,

exit(x)(x不为0)都表示异常退出,这个x是返回给操作系统(包括UNIX,Linux,和MS DOS)的,以供其他程序使用。

stdlib.h: void exit(int status);//参 数status,程序退出的返回值

来自于:百度百科

 

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/82629255

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。