零、代碼
#include <stdio.h>
#define MAXLINE 1000 // 輸入行的最大長度
int max; // 儲存目前為止最長行的長度
char line[MAXLINE]; // 儲存目前的輸入行
char longest[MAXLINE]; // 儲存最長的行
int get_line(void);
void copy_longest_line(void);
int main()
{
int cur_len; // 目前行的長度
extern int max;
extern char longest[];
max = 0;
while ((cur_len = get_line()) > 0)
{
printf("The current line's length is : %d\n", cur_len);
if (cur_len > max)
{
// 如果目前行的長度大于上次儲存的最大長度,則最大長度要更新為目前長度
// 并且要把目前行的内容放到longest數組中,此時longest數組原先的内容會被覆寫掉
max = cur_len;
copy_longest_line();
}
}
if(max > 0)
{
printf("\nThe max length of the input lines is : %d\n", max);
printf("The longest line is : %s\n", longest);
}
return 0;
}
// 将目前輸入行的内容儲存到line數組中
int get_line(void)
{
int c=0, i=0;
extern char line[];
/**
* 繼續循環需要三個條件:
* (1) i小于999,因為數組的最大長度為1000(即0~999),line[999]要放換行符'\n',是以輸入字元隻能放在line[0]~line[998]
* (2) 輸入的字元不為檔案結束符,Windows的檔案結束符為ctrl+z,mac/linux/unix的檔案結束符為ctrl+d
* (3) 輸入的字元不為換行符'\n',因為一旦換符,那就是新的一行了
*/
for (; i < MAXLINE-1 && (c= getchar()) != EOF && c != '\n'; ++i)
{
line[i] = c;
}
if (c == '\n')
{
line[i] = c;
++i;
}
// 換行符的下一個字元是行結束符'\0','\0'不算在行長度内
line[i] = '\0';
return i;
}
void copy_longest_line(void)
{
int i = 0;
extern char line[], longest[];
// 先把line[i]指派給longest[i],再判斷longest[i]是不是行結束符'\0'
while ((longest[i] = line [i]) != '\0')
{
++i;
}
}
一、運作結果
輸入
a
abc
ab
ctrl + z
二、分析
1 定義數組char c[10],可存放十個字元,從c[0]~c[9]。注意計算機是從0開始計數而不是從1開始計數,是以最後一個元素是c[9]而不是c[10]。
2 字元與數字是一一對應的。具體而言,就是每個字元都對應着一個ascii編碼。
比如:
a對應97,b對應98,其它小寫字母以此類推;
A對應65,B對應66,其它大寫字母以此類推;
字元‘1’對應49,字元‘2’對應50,其它數字以此類推;
回車符‘\r’對應13,換行符‘\n’對應10;
行結束符‘\0’對應0。
是以,整型數組既可以用來存放整型元素,也可以用來存放字元元素;
同理,字元數組既可以用來存放字元元素,也可以用來存放整型元素。
3 在C語言中,字元數組是以’\0’作為行結束符的,并且行結束符不算在字元數組的長度内。
例子:輸入abc并換行,這在長度為10的字元數組c[10]中是這麼放的
a | b | c | \n | \0 | 空 | 空 | 空 | 空 | 空 |
這裡c[0] = ‘a’, c[1] = ‘b’, c[2] = ‘c’, c[3]= ‘\n’, c[4] = ‘\0’, c[5]~c[9]都為空。
其長度為4,行結束符’\0’不算在長度内。
4 get_line函數中有個句子
for (; i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
等價于
for (i = 0; i < MAXLINE-1 && (c=getchar()) != EOF && c != '\n'; ++i)
因為i = 0;上面已經出現過,是以這裡不寫也可以。
5 本程式的執行過程
(0)最開始max=0;
(1)第一次輸入a并且換行,get_line()函數的執行順序為
i = 0時; 輸入‘a’,循環的三個條件都滿足,先執行line[0] = ‘a’;
再執行i++,i的值變為1
i = 1時; 輸入換行符’\n‘ ,循環條件有一個不滿足,結束循環
繼續執行if(c == ‘\n’),這個條件是成立的,是以line[1] = ‘\n’,i++,i的值變為2
繼續執行line[2] = ‘\0’
繼續執行return 2。傳回的2就是目前行的長度。
此時main()函數中cur_len=2,max=0, cur_max > max成立,執行max = cur_len,即max由原先的0更新為 2。再執行copy_longest_line()函數。
copy_longest_line()函數中,
longest[0] = line[0] = ‘a’
longest[1] = line[1] = ‘\n’
longest[2] = line[2] = ‘\0’循環結束
(2)第二次輸入abc并換行,get_line()函數的執行順序為
while語句中,
i = 0時,line[0] = ‘a’,i++,i的值變為1;
i = 1時,line[1] = ‘b’,i++,i的值變為2;
i = 2時,line[2] = ‘c’,i++,i的值變為3;
i = 3時,line[3] = ‘\n’,循環結束;
if語句中
line[3] = ‘\n’, i++, i的值變為4
line[4] = ‘\0’;
return 4;
main()函數中,
cur_len的值為get_line()的傳回值4,上次得到的max值為2,cur_len>max,max=cur_len=4,即max的值由原先的2更新為4,并執行copy_longest_line()函數。
copy_longest_line()函數中,
longest[0] = line[0] = ‘a’;
longest[1] = line[1] = ‘b’;
longest[2] = line[2] = ‘c’;
longest[3] = line[3] = ‘\n’;
longest[4] = line[4] = ‘\0’;
循環結束。
(3)第3次輸入ab并換行,執行get_line()函數,
line[0] = ‘a’;
line[1] = ‘b’;
line[2] = ‘\n’;
line[3] = ‘\0’;
return 3;
因為cur_len=3, max=4, cur_len>max不成立,是以max仍為上次得到的4不作改變,并且copy_longest_line()函數不被執行。
6 本程式中,全局變量max,line[1000], longest[1000]的定義和使用都在同一個檔案中,并且是先定義後使用,是以實際上所有的extern語句都可以去掉。
但是若全局變量的定義在一個檔案内(比如test1.c),使用在另一個檔案内(比如test2.c),那麼extern語句不能省。
代碼:
#include <stdio.h>
#define MAXLINE 1000 // 輸入行的最大長度
int max; // 儲存目前為止最長行的長度
char line[MAXLINE]; // 儲存目前的輸入行
char longest[MAXLINE]; // 儲存最長的行
int get_line(void);
void copy_longest_line(void);
int main()
{
int cur_len; // 目前行的長度
max = 0;
while ((cur_len = get_line()) > 0)
{
printf("The current line's length is : %d\n", cur_len);
if (cur_len > max)
{
// 如果目前行的長度大于上次儲存的最大長度,則最大長度要更新為目前長度
// 并且要把目前行的内容放到longest數組中,此時longest數組原先的内容會被覆寫掉
max = cur_len;
copy_longest_line();
}
}
if(max > 0)
{
printf("\nThe max length of the input lines is : %d\n", max);
printf("The longest line is : %s\n", longest);
}
return 0;
}
// 将目前輸入行的内容儲存到line數組中
int get_line(void)
{
int c=0, i=0;
/**
* 繼續循環需要三個條件:
* (1) i小于999,因為數組的最大長度為1000(即0~999),line[999]要放換行符'\n',是以輸入字元隻能放在line[0]~line[998]
* (2) 輸入的字元不為檔案結束符,Windows的檔案結束符為ctrl+z,mac/linux/unix的檔案結束符為ctrl+d
* (3) 輸入的字元不為換行符'\n',因為一旦換符,那就是新的一行了
*/
for (; i < MAXLINE-1 && (c= getchar()) != EOF && c != '\n'; ++i)
{
line[i] = c;
}
if (c == '\n')
{
line[i] = c;
++i;
}
// 換行符的下一個字元是行結束符'\0','\0'不算在行長度内
line[i] = '\0';
return i;
}
void copy_longest_line(void)
{
int i = 0;
// 先把line[i]指派給longest[i],再判斷longest[i]是不是行結束符'\0'
while ((longest[i] = line [i]) != '\0')
{
++i;
}
}