【学习目标】
01掌握for循环的使用方法(OK)
02掌握while循环的使用方法(OK)
03学会使用计数器和累加器(OK)
04学会使用输出中间结果的方法调试(OK)
05学会用计时函数测试程序效率(不熟悉)
06学会用重定向的方法读写文件(基本不会)
07学会用fopen的方式读写文件(基本不会)
08了解算法竞赛对文件读写方式和命名的严格性(嗯)
09记住变量在赋值之前的值是不确定的(OK)
10学会使用条件编译指示构架本地运行环境(不会)
P18
注意浮点数的运算(包括返回浮点数的函数)可能有误差!
编写一个程序判断输出的数(n<10^9)是不是完全平方数,是输出yes,否则输出no;
#include <stdio.h> #include <math.h> int main(void) { int n; double r; scanf("%d", &n); r = sqrt(n);//or r = sqrt((double)n); printf(floor(r+0.5) == r ? "yes\n" : "no\n"); return 0; }
#include <stdio.h> #define N 100 int main(void) { int i; for (i = 0; i != N; i++) { if (i == 5) continue; if (i == 10) break; } printf("%d\n",i); return 0; }
可见循环出口一旦执行,i++肯定不会再执行;而继续循环(中途就继续或者正常继续),i++肯定会执行。
05学会用计时函数测试程序效率
#include <stdio.h> #include <time.h> int main(void) { int n, i, j; clock_t star, end; scanf("%d", &n); star = clock(); for (i = 0; i != n; i++) for (j = 0; j != n; j++) ; end = clock(); printf("%lf\n", (double)(end-star) / CLOCKS_PER_SEC); //notice! is CLOCKS including 'S' return 0; }这样写可以避免把等待输入的时间也算上,注意常量CLOCKS_PER_SEC带'S'。
linux中重定向输入是echo 12321 | ./program_name
06学会用重定向的方法读写文件
学会这个主要是可以把输入输出放在一个文本,省的在终端输入或粘贴测试数据,特别是输入一些矩阵时。
下面默认输入文件名是test.in,输出文件名是test.out
下面写一个程序,输入一个n*n的矩阵(n<=100),输出矩阵的转置矩阵;
比如,
输入:
3
1 2 3
1 2 3
1 2 3
输出:
1 1 1
2 2 2
3 3 3
(注意:每一行最后一个元素后面没有空格)
【普通版本】
#include <stdio.h> #define N 110 int a[N][N]; int main(void) { int i, j, n; scanf("%d", &n); for (i = 0; i != n; i++) for (j = 0; j != n; j++) { scanf("%d", &a[i][j]); } for (j = 0; j != n; j++) for (i = 0; i != n; i++) { printf(i == n-1 ? "%d\n" : "%d ", a[i][j]); } return 0; }
【重定向版本】
#include <stdio.h> #define N 110 int a[N][N]; int main(void) { int i, j, n; freopen("test.in", "r", stdin); freopen("test.out", "w", stdout); scanf("%d", &n); for (i = 0; i != n; i++) for (j = 0; j != n; j++) { scanf("%d", &a[i][j]); } for (j = 0; j != n; j++) for (i = 0; i != n; i++) { printf(i == n-1 ? "%d\n" : "%d ", a[i][j]); } return 0; }可以看到重定向版本就多了两行代码!就是读取test.in的内容作为标准输入流(stdin),把标准输出流(stdout)的内容写入到test.out。
【fopen版】
#include <stdio.h> #define N 110 int a[N][N]; int main(void) { int i, j, n; FILE *fin, *fout;//file pointer indicated file name; fin = fopen("test.in", "r"); fout = fopen("test.out", "w"); fscanf(fin, "%d", &n); for (i = 0; i != n; i++) for (j = 0; j != n; j++) { fscanf(fin, "%d", &a[i][j]); } for (j = 0; j != n; j++) for (i = 0; i != n; i++) { fprintf(fout, i == n-1 ? "%d\n" : "%d ", a[i][j]); } fclose(fin); fclose(fout); return 0; }其实这个版本也很容易理解,首先打开文件,fin是文件的指针,并且可以读文件,然后scanf()改为fscanf(),即从文件中读取,参数也相应加了一个,并在最开始部分指定文件的地址(指针);写入的原理以此类推。
感觉重定向相当好用哦!
书中介绍本地用重定向,提交则删除“重定向”语句,感觉不是太实用,但不妨一学。
10学会使用条件编译指示构架本地运行环境
#include <stdio.h> #define N 110 int a[N][N]; int main(void) { int i, j, n; #ifdef LOCAL freopen("test.in", "r", stdin); freopen("test.out", "w", stdout); #endif scanf("%d", &n); for (i = 0; i != n; i++) for (j = 0; j != n; j++) { scanf("%d", &a[i][j]); } for (j = 0; j != n; j++) for (i = 0; i != n; i++) { printf(i == n-1 ? "%d\n" : "%d ", a[i][j]); } return 0; }上述程序文件名为test.c
那么我们通过编译命令:(注意是:-DLOCAL)
gcc -g -Wall -DLOCAL test.c -o test就会执行重定向那两句代码了,反之去掉-DLOCAL就不会执行