CSAPP基本版实验学习日志:关于sq代码的阅读以及在ubantu上的运行

sq(计算平方值)代码内容:

#include <stdio.h>
#include <stdlib.h>

int sq(int x) {
    return x*x;
}

int main(int argc, char *argv[]) {
    int i;
    for (i = 1; i < argc; i++) {
	int x = atoi(argv[i]);
	int sx = sq(x);
	printf("sq(%d) = %d\n", x, sx);
    }
    return 0;
}

下面我将分别解释:

#include <stdio.h>
#include <stdlib.h>

#include<stdio.h>是编译预处理命令,即在程序编译之前要处理的内容,<>中以以“.h ”作为结尾的文件称为头文件,如stdio.h,stdlib.h,string.h均为头文件。
stdio 即 “standard input & output"(标准输入输出)在开头加上#include <stdio.h>即可实现c语言中的 输入函数printf、输出函数scanf等函数。
同理,在开头加上#include <stdlib.h>即可实现c语言中的exitmallocfree等函数。
同样的,在开头加上#include <string.h>即可实现关于字符数组的函数,例如连接字符串函数strcat,复制字符串函数strcpy,比较字符串(区分大小写)函数strcmp等。
类似头文件还有math.h(包括各种常用的三角函数、双曲线函数、指数和对数函数等)等。

	return x*x;
}

返回x乘x的值,即x的平方。return 用于实现函数值的返回,将x*x返回到主函数。关于return

int main(int argc, char *argv[]) {

程序的主函数,有main()函数的程序才能运行,即函数必须被main()直接或间接调用才能发挥作用,主函数的返回值类型为int(整型)。其中,main函数可以带参数,这个参数可以认为是main函数的形式参数。C语言规定main函数的参数只能有两个,习惯上这两个参数写为argc和argv。可参考关于main函数参数int main(int argc,char* argv[])详解
C语言还规定argc(第一个形参)必须是整型变量,argv(第二个形参)必须是指向字符串的指针数组。
argc是命令行总的参数个数,argv[]是argc个参数,其中第0个参数argv[0]指向程序运行的全路径名,以后的参数为命令行后面跟的用户输入的参数。
通过阅读后续代码,可以发现它利用了这些参数间关系。

	int i;

定义一个整型变量(int),整型变量,在内存中占4个字节,最长能到32位二进制位,其取值为基本整常数,在该定义中,变量名为i。

	for (i = 1; i < argc; i++) {

for循环语句用来实现当型循环,括号中的表达式1的作用是初始化循环控制变量,即为循环控制变量赋初值;表达式2的作用是给出循环重复执行的判断条件,这个条件也用于决定什么时候结束循环;表达式3的作用是给循环控制变量增值,即定义循环控制变量在每次循环结束后按什么方式变化。
除了for语句,while和do-while语句也是循环语句。关于for语句:C语言for语句用法详解
在此循环中,让i赋初值1,当i < argc时进行循环,每一次循环后i+1,则i >= argc时结束循环,argc由用户输入参数个数决定,也就是在用户不输入其他参数情况下,循环不进行。

		int x = atoi(argv[i]);

定义一个整型变量,其变量名为x。atoi函数用来将字符串转换成整数(int),它的头文件为#include <stdlib.h>。atoi函数会扫描参数 str 字符串,跳过前面的空白字符(例如空格,tab缩进等,可以通过 isspace() 函数来检测),直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(’\0’)才结束转换,并将结果返回。更多可参考:C语言atoi()函数
在这里则是将argv数组的第二个元素,即用户输入的第一个参数做为函数的参数,并将转换来的整型数赋给x。

		int sx = sq(x);

定义一个整型变量sx,令sx赋值为函数sq以x为参数的返回函数,即x的平方。

		printf("sq(%d) = %d\n", x, sx);
    }

printf函数是一个标准库函数,它的函数原型在头文件stdio.h中。printf函数调用的一般形式为:printf(“格式控制字符串”, 输出表列)。printf是将一个格式化的字符串输出到屏幕。更多可参考:C语言格式输出函数printf()详解
这里是打印出sq(x的值) = sx的值。并换行。

	return 0;
}

主函数返回0表程序结束。
以下为该代码在ubantu上运行结果:

@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 12
sq(12) = 144
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 65535
sq(65535) = -131071
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 40000
sq(40000) = 1600000000
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 50000
sq(50000) = -1794967296
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 400000
sq(400000) = 1086210048
@ubuntu:/mnt/hgfs/share/csapp_code$ ./a.out 500000
sq(500000) = 891896832

综上,该程序的功能为计算用户所输变量的平方值。可以看到,当输入的值足够大时,所算出来的值发生了错误。这是由于int只能算到二进制的32位。在机器中的计算是按二进制计算,在经过转换在屏幕上看到十进制数。因此输入参数过大时,所得结果超过机器的位数,就会发生高位溢出。由于定义为有符号类型,所以甚至会出现x的平方等于负数的现象。(C语言中二进制数的第一位表符号位,0表示正,1表示负)。因此要求我们在做编程用到运算时要充分考虑数的范围问题,并采取恰当解决方案。
博客参考:《深入理解计算机系统》第二章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值