关于Fsum.c代码学习的心得
阅读提示:
1 完整代码贴在最后面
2 本文章按照main函数的顺序依次解释代码
此代码可用于测试浮点数加法中结合律的可行性!
-
int main(int argc, char *argv[])
①我们通常说main函数不能带参数,实际上,main函数可以带参数,这个参数可以认为是 main函数的形式参数。C语言规定main函数的参数只能有两个, 习惯上这两个参数写为argc和argv。
②argc参数表示了命令行中参数的个数(注意:文件名本身也算一个参数)argc的值是在输入命令行时由系统按实际参数的个数自动赋予的。
③argv参数是字符串指针数组,其各元素值为命令行中各字符串(参数均按字符串处理)的首地址。 指针数组的长度即为参数个数。数组元素初值由系统自动赋予。 -
char prefix[BUFSIZE]// char next[BUFSIZE]
定义两个字符数组用于存放用户输入的数据 -
for (i = 1; i < argc; i++)//float x = atof(argv[i]);
①i从1开始取值,因为不带参数时argc=1,而且第一个参数argv[0]储存文件名,argv[1]才是用户输入的第一个参数
sum += x;
将输入的参数依次相加;
②atof()
是C 语言标准库中的一个字符串处理函数,功能是把字符串转换成浮点数,
所使用的头文件为<stdlib.h> 返回值: 返回转换后的浮点型数 -
sprintf(prefix, "%.4g", x);
①格式化数字字符串sprintf 最常见的应用之一莫过于把整数打印到字符串中,sprintf 是个变参函数,定义如下:
sprintf函数原型:int sprintf( char *buffer, const char *format ,[argument] … );
而它的精华,显然就在第二个参数:格式化字符串上。
② 通俗的说sprintfa的作用就是将[arguement]
中的值按const char *format
的格式写入char *buffer
中;
即将x
的值按%.4g
的格式写入prefix数组
中; -
对for循环里面if/else语句的解释
if (i == 1) {
sprintf(prefix, "%.4g", x);
} else {
sprintf(next, " + %.4g", x);
strcat(prefix, next);
printf("%s = %.4g\n", prefix, sum);
}
① i等于1时,将第一个输入的参数argv[1]放到prefix数组中
② i>1时,将argv[2]、argv[3]等依次放入next数组中
③用字符串连接函数strcat依次连接prefix中与next中的字符串,并将新的字符串存放到prefix中,即让各字符串以加法形式相接
④%g
用来输出实数,它根据数值的大小,自动选f格式或e格式(选择输出时占宽度较小的一种)且不输出无意义的0。
即%g是根据结果自动选择科学记数法还是一般的小数记数法
⑤ .4
表示输出的数字小数部分精度为4。
⑥printf("%s = %.4g\n", prefix, sum);
打印新连接的字符串及求和之后的值。
例如:输入1,2,3,4。
依次输出:1+2=3;1+2+3=6;1+2+3+4=10
至此代码解释部分结束
从上图中我们可以知道:浮点数加法是不满足结合律的。
完整FSUM.C代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFSIZE 256
int main(int argc, char *argv[]) {
char prefix[BUFSIZE];
char next[BUFSIZE];
int i;
float sum = 0.0;
for (i = 1; i < argc; i++) {
float x = atof(argv[i]);
sum += x;
if (i == 1) {
sprintf(prefix, "%.4g", x);
} else {
sprintf(next, " + %.4g", x);
strcat(prefix, next);
printf("%s = %.4g\n", prefix, sum);
}
}
return 0;
}