Tips
- 學(xué)習(xí)算法最好的方法并不是編寫程序唯沮,而是手算
- 千萬不要圖快——如果沒有足夠的時(shí)間來實(shí)踐,那么學(xué)的快忿檩,忘的也快
- 手工模擬的方法重點(diǎn)在于:記錄每條語句執(zhí)行之后各個(gè)變量的值
- 黑盒測試:只考察解決問題的能力尉尾,而不關(guān)心采用了什么方法
- 偽代碼:在實(shí)際應(yīng)用中并不太拘泥于偽代碼的格式,主要目的是描述算法梗概燥透,避開細(xì)節(jié)沙咏,啟發(fā)思路
- 盡量縮短變量的定義范圍
- 變量在未賦值前是不確定的,特別的班套,它不一定等于 0
- Keep It Simple and Stupid 保持程序簡單
0. 管道機(jī)制
作用:把不同的程序串聯(lián)起來
例如:程序 aplusb 作用是讀入兩個(gè)整數(shù)a,b肢藐,返回 a+b 的值 程序 sqr 作用是讀入一個(gè)整數(shù) a,返回 a*a 的值
用管道機(jī)制表示為
echo 10 20 | ./aplusb | ./sqr
- 格式
echo 傳入?yún)?shù) | ./接收函數(shù) | ./接收函數(shù) …
1. 精確數(shù)值
const double pi = acos(-1.0); //精確取 π 值
//輸出所有形如aabb的完全平方數(shù)吱韭。注意:a 的范圍是1 ~ 9吆豹,但 b可以是 0
//方法一:
for(int a=0; a<=9; a++)
{
for(int b=0; b<=9; b++)
{
int n = a*1100+b*11;
int m = floor(sqrt(n)+0.5);
if(m*m == n) printf(“%d\n”, n);
}
}
//floor函數(shù)只取整數(shù)位,小數(shù)位舍棄
//floor(x+0.5)為了四舍五入 不過這樣小數(shù)部分0.5也會(huì)有誤差
//因此不能寫 if( sqrt(n) == floor(sqrt(n)) ) printf(“%d\n”,n);
//方法二:
for(int x=1; ;x++)
{
int n = x*x;
if (n < 1000) continue;
if (n > 9999) break;
int hi = n/100;
int lo = n%100;
if(hi/10 == hi%10 && lo/10 == lo%10) printf(“%d”,n);
}
2. 輸入輸出框架
每次輸入輸出用標(biāo)準(zhǔn)輸入「鍵盤輸入」輸出「顯示器輸出」太過于繁瑣 采用輸入輸出數(shù)據(jù)存放在文件中來避免這種繁瑣
//輸入一些整數(shù)理盆,求出它們的最小值痘煤、最大值和平均值(保留3位小數(shù))
//輸入保證這些數(shù)都是不超過1000的整數(shù)
//方法一:重定向
#define LOCAL //注意:這里的宏定義即便沒有賦值 也算定義了LOCAL
#include<stdio.h>
#define INF 1000000000
int main()
{
#ifdefin LOCAL
freopen("data.in","r",stdin);//從這里開始所有鍵盤的輸入改用文件
freopen("data.out","w",stdout);//從這里開始所有鍵盤的輸出改用文件
#endif
int x,n=0,min=INF,max=-INF,s=0;
while(scanf("%d",&x) == 1)
{
s += x;
if(x<min) min = x;
if(x>max) max = x;
//printf("x=%d, min=%d, max=%d\n", x, min, max);
n++;
}
printf("%d %d %.3f\n", min, max, (double)s/n);
return 0;
}
//方法二:fopen
#include<stdio.h>
#define INF 1000000000
int main()
{
FILE fin, fout;
fin = fopen("data.in","rb");//fopen方法較靈活
fout = fopen("data.out","wb");//fin = stdin 便能切換到標(biāo)準(zhǔn)輸入
int x, n=0, min = INF, max = -INF, s=0;
while(fscanf(fin, "%d", &x) == 1)
{
s += x;
if(x < min) min = x;
if(x > max) max = x;
n++;
}
fprintf(fout, "%d %d %.3f\n", min, max, (double)s/n);
fclose(fin);
fclose(fout);
return 0;
}
3. 細(xì)節(jié)注意
C語言中 數(shù)據(jù)有不同的類型,因此 關(guān)系運(yùn)算符 == 和 != 有嚴(yán)格的規(guī)定猿规,必須同時(shí)考慮 數(shù)據(jù)類型 和 數(shù)值大小
4. 關(guān)于 段
段:二進(jìn)制文件內(nèi) 的區(qū)域衷快,所有特定類型信息被保存在里面
4.1 在可執(zhí)行文件中
- 正文段:存儲(chǔ)指令
- 數(shù)據(jù)段:存儲(chǔ)全局變量「已初始化的」
- BSS段:存儲(chǔ)全局變量所需的空間「未初始化的」
4.2 在運(yùn)行時(shí)
- 堆棧段:程序動(dòng)態(tài)創(chuàng)建,保存函數(shù)調(diào)用關(guān)系 和 局部變量
- 因此棧溢出不一定是遞歸調(diào)用太多姨俩,也可能是局部變量太大