1. 程式人生 > >我這個萌新在HDOJ上的被A+B problem虐記錄

我這個萌新在HDOJ上的被A+B problem虐記錄

在六天前,也就是10月21日,我受某位學長慫恿去了HDOJ看看,結果被虐的不要不要的。我當時連while語句都不知道誒,英語也不好,連題幹都看不懂,

題是這樣的

Problem Description Calculate A + B. Input Each line will contain two integers A and B. Process to end of file. Output For each case, output A + B in one line. Sample Input 1 1 Sample Output 2

第一遍是我還真的以為是簡單的算一遍A+B呢,當然沒有通過啦。有位同級大佬告訴我不是算一次就行的,還要接著算。直到今天(27日)才看到開頭有一個EACH,好吧,真實人生一大悲哀。

可以AC的程式碼是這樣的

#include<stdio.h>
int main()
{
	int a,b;
	while(scanf("%d%d",&a,&b)!=EOF)
	{
		printf("%d\n",a+b);
		}
	return 0; 
}

那麼scanf後為什麼非要加一個!=EOF呢?

《C Primer Plus中文第六版》220頁提到,C的輸入函式內建了檔案結尾檢測器。 檢測檔案結尾的一種方法是:在檔案末尾放一個特殊的字元標記檔案結尾,例如內嵌的Ctrl+Z字元。 另一種方法是:儲存檔案大小的資訊。如果檔案有3000位元組,讀到3000位元組時便達到檔案末尾。 讀取到檔案末尾時,getchar()和scanf()會返回一個特殊值EOF(end of file縮寫),EOF定義在stdio.h中:#define EOF (-1)

所以,while(scanf("%d%d",&a,&b)!=EOF)加上!=EOF的作用就是,讀取到檔案末尾時可以跳出迴圈。如果不加,無法跳出while(),系統判定超時。

接下來是一些題外話?

之前總有一種執念,以為scanf的返回值為-1或0時自動跳出while(),現在想想真是腦袋被門夾了,捂臉捂臉~

scanf()返回型別為int,返回值為成功讀取的項數 讀取失敗時返回值為0 檢測到檔案末尾或硬體問題時返回值為-1

使用%d轉換說明讀取時,scanf()每次讀取一個字元,跳過所有空白符,直至遇到第一個非空白字元才開始讀取,如果找到一個數字或符號(+/-),便開始讀取儲存字元,直至遇到非數字字元。 如果第一個非空白符不是數字,scanf()停在那裡,把字元放入輸入中,不會把值賦給指定變數。在下一次讀取時,首先讀取到的還是該字元,scanf()始終無法越過該字元,且此時scanf()返回值為0,上面的程式碼就是死迴圈……

我是用下面這個程式碼研究返回值的

#include<stdio.h>
#include<stdlib.h>
int main(void)
{
	int a;
	int b;
	int c;
	printf("請輸入三個整數\n");
	int x=scanf("%d%d%d",&a,&b,&c);
	
	printf("a=%d\nb=%d\nc=%d\n返回值=%d\n",a,b,c,x);
	system("pause");
	
	return 0;
}

別問我為什麼不用上面AC的程式碼修改,我不會TAT,求大佬教我啊

經過以上研究,程式碼改成下面這樣也可以AC了,反正題幹一組兩個整數,順便解決了輸入非數字會造成死迴圈的問題……

#include<stdio.h>
int main()
{
	int a,b;
	while(scanf("%d%d",&a,&b)==2)
	{
		printf("%d\n",a+b);
	}
	return 0; 
}

其他人的AC程式碼還有寫成這樣的 就是把 while(scanf("%d %d",&a,&b)!=EOF) 改成 while(~scanf("%d %d",&a,&b))

“~”意為取一個數的二進位制反碼。 while裡不加判斷條件預設為語句不等於0…… 那麼就是說取反後不等於0就進行迴圈

當scanf()讀到檔案結束,返回值為-1。 按教材寫的“負數取反:原碼的符號位不變,其他位按位取反”。 (-1)10原碼(10000001)2取反後為八位二進位制數 (11111110)2?並沒有看出來這個是0

於是機智的我又寫了一段程式

#include<stdio.h>
int main(void)
{
	int A=-1;
	int B=999; 
	B=~A; 
	printf("%d",B);
	
	return 0;
}

輸出結果為0……我先去哭一會……

0 的機器罵(原碼):0|0000000000000000000000000000000 -1的機器碼(補碼):1|1111111111111111111111111111111 怎麼又蹦出來個補碼?1和0字元寬度不一樣,沒對齊強迫症忍耐一下……

來自於百度知道,沒找到-1取反,先拿這個將就吧。和我們教材上寫的根本不一樣,教材說符號位不變……

所以while(~scanf("%d %d",&a,&b))與while(scanf("%d %d",&a,&b)!=EOF)等價 都是在scanf()返回值為-1時跳出迴圈

//…………………………分割線…………………………

累啊~~~問題還有很多(還是緩衝區不懂),取反不會,先在這裡記著吧,不寫下來怕忘了