導航:首頁 > 源碼編譯 > 使用printf進行編譯的實驗步驟

使用printf進行編譯的實驗步驟

發布時間:2022-10-03 08:47:31

❶ C++中printf() 使用方法

C++中printf() 使用

printf()函數是格式化輸出函數, 一般用於向標准輸出設備按規定格式輸出 信息。在編寫程序時經常會用到此函數。printf()函數的調用格式為:

printf("<格式化字元串>", <參量表>);

其中格式化字元串包括兩部分內容: 一部分是正常字元, 這些字元將按原 樣輸出; 另一部分是格式化規定字元, 以"%"開始, 後跟一個或幾個規定字元, 用來確定輸出內容格式。

參量表是需要輸出的一系列參數, 其個數必須與格式化字元串所說明的輸出 參數個數一樣多, 各參數之間用","分開, 且順序一一對應, 否則將會出現意想不到的錯誤。

❷ 怎麼在51里使用printf重定義

您的意思使用 printf 輸出對吧

使用printf實現串口發送的重定義步驟:
1、首先要配置好串口的功能,以我們的第四個實驗myUART_LED為例,這個工程的串口
發送已經能夠實現,我們需要用printf("error,theinputnumbermustbetween1~4. ");代替Main函數中的語句:
while(TxCounter<TxBufferSize){USART_SendData(USART1,TxBuffer[TxCounter++]);//從串口1發送數據while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){}
//等待一個發送完一個數據
}
2、在main.c文件的開頭增加語句:#include"stdio.h",這樣我們的程序就可以使用標準的
輸入輸出函數了
3、在main.c中添加函數://重定義printf到串口//intfputc(intch,FILE*f){
USART_SendData(USART1,ch);
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){}
returnch;}
4、修改u8TxBuffer[]={"error,theinputnumbermustbetween1~4. "};
charTxBuffer[]={"error,theinputnumbermustbetween1~4. "};
(這關繫到printf函數參數類型匹配的問題,如果不修改會出現一個警告)然後將Main函數中的語句:
while(TxCounter<TxBufferSize){USART_SendData(USART1,TxBuffer[TxCounter++]);//從串口1發送數據while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET){}
//等待一個發送完一個數據
}改為:
printf(TxBuffer);5、編譯下載運行
說明:
fputc屬於輸出函數,在C語言中,包含在文件stdio.h中,為ANSI標準的函數。在步
驟3中,我們修改此函數輸出設備為串口。
經重定義後,main函數就可以使用printf實現串口發送了。(大家暫且理解printf會調用
到fputc函數)。
與fputc對應的intfgetc(FILE*f);為輸入函數,如果想用fgetc實現串口接收功能請按照上面例子重定義。

❸ c語言中printf的用法

c語言中printf的用法的用法你知道嗎?下面我就跟你們詳細介紹下c語言中printf的用法的用法,希望對你們有用。

c語言中printf的用法的用法如下:

Printf和Scan函數的使用方法

一 printf()函數是格式化輸出函數, 一般用於向標准輸出設備按規定格式輸出

信息。在編寫程序時經常會用到此函數。printf()函數的調用格式為:

printf("<格式化字元串>", <參量表>);

其中格式化字元串包括兩部分內容: 一部分是正常字元, 這些字元將按原

樣輸出; 另一部分是格式化規定字元, 以"%"開始, 後跟一個或幾個規定字元,

用來確定輸出內容格式。

參量表是需要輸出的一系列參數, 其個數必須與格式化字元串所說明的輸出

參數個數一樣多, 各參數之間用","分開, 且順序一一對應, 否則將會出現意想

不到的錯誤。

格式化字元串的格式是:

%[標志][輸出最小寬度][.精度][長度]格式字元

1. 標志:標志字元為-、+、#、空格四種,其意義下表所示:

標志 意義

- 結果左對齊,右邊填空格

+ 輸出符號(正號或負號)

空格 輸出值為正時冠以空格,為負時冠以負號

# 對c,s,d,u類無影響;對o類,在輸出時加前綴o;對x類,在輸出時加前綴0x;對e,g,f 類當結果有小數 時才給出小數點(??????)

例1:

#i nclude

main()

{

int a=100;

float b=123.255;

printf("a=%d ",a);

printf("a=d ",a);

printf("a=%-10d ",a);

printf("a=%+d ",a);

printf("a=% d ",a);

printf("a=%#o ",a);

printf("a=%#x ",a);

printf("b=%#f ",b);

}

運行結果

a=100

a= 100

a=100

a=+100

a= 100

a=0144

a=0x64

b=123.254997 (?????)

2.輸出最小寬度:用十進制整數來表示輸出的最少位數。(至少要輸出這么多位!)

若實際位數多於定義的寬度:則按實際位數輸出。

若實際位數少於定義的寬度:則右對齊,左邊留空。

有負號,左對齊,右邊留空

表示寬度的數字以0開始,則右對齊,左邊留空。

例2 #i nclude

main()

{

int a=3456;

printf("a== ",a); //若實際位數多於定義的寬度:則按實際位數輸出

printf("a=d ",a); //若實際位數少於定義的寬度:則右對齊,左邊留空

printf("a=%-10d ",a); //若實際位數少於定義的寬度:有負號,左對齊,右邊留空

printf("a=0d ",a); //若實際位數少於定義的寬度:表示寬度的數字以0開始,則右對齊,左邊留空

printf("a=%-010d ",a); //左對齊,0無意義。

}

運行結果:

a=3456

a= 3456

a=3456

a=0000003456

a=3456

3.精度:精度格式符以“.”開頭,後跟十進制整數。意義是:

如果輸出數字,則表示小數的位數;若實際位數大於所定義的精度數,則四捨五入。若不足則補0;

如果輸出的是字元,則表示輸出字元的個數;若實際位數大於所定義的精度數,則截去超過的部分。

例3:

#i nclude

main()

{

printf("%.3f ",12.3456);

printf("%.9f ",12.3456);

printf("%.3s ","abcdefg");

printf("%.9s ","abcdefg");

}

運行結果:

12.346 //四捨五入到小數點後三位

12.345600000 //不足補0

abc

abcdefg

4.長度:長度格式符為h,l兩種,h表示按短整型量輸出,l表示按長整型量輸出?????

5.Turbo C2.0提供的格式字元如下:

━━━━━━━━━━━━━━━━━━━━━━━━━━

符號 作用

──────────────────────────

%c 單個字元

%d 十進制有符號整數

%e 以“科學記數法”的形式輸出十進制的浮點數 如2.451e+02

%f 輸出十進制浮點數,不帶域寬時,保留6位小數

%g 選用e或f格式中較短的一個輸出十進制浮點數,不輸出無效零

%0 無輸出無符號八進制整數

%p 指針的值

%s 輸出字元串

%u 輸出無符號十進制整數

%x, %X 輸出無符號十六進制整數 (不輸出前綴Ox)

━━━━━━━━━━━━━━━━━━━━━━━━━━

2. 一些特殊規定字元

━━━━━━━━━━━━━━━━━━━━━━━━━━

字元 作用

──────────────────────────

換行

f 清屏並換頁

回車

Tab符

xhh 表示一個ASCII碼用16進表示,

其中hh是1到2個16進制數

━━━━━━━━━━━━━━━━━━━━━━━━━━

使用這些轉義字元時不需要加上%,可單獨使用!

由本節所學的printf()函數, 並結合上一節學習的數據類型, 編制下面的程

序, 以加深對Turbo C2.0數據類型的了解。

例1

#i nclude

#i nclude

int main()

{

char c, s[20], *p;

int a=1234, *i;

float f=3.141592653589;

double x=0.12345678987654321;

p="How do you do";

strcpy(s, "Hello, Comrade");

*i=12;

c='x41';

printf("a=%d ", a);

printf("a=m ", a);

printf("a=d ", a);

printf("a=- ", a);

printf("*i=M ", *i);

printf("*i=%-4d ", *i);

printf("i=%p ", i);

printf("f=%f ", f);

printf("f=6.4f ", f);

printf("x=%lf ", x);

printf("x=.16lf ", x);

printf("c=%c ", c);

printf("c=%x ", c);

printf("s[]=%s ", s);

printf("s[]=%6.9s ", s);

printf("s=%p ", s);

printf("*p=%s ", p);

printf("p=%p ", p);

getch();

retunr 0;

}

其他需要注意的一些問題:

1.如果用浮點數表示字元或整型量的輸出格式, 小數點後的數字代表最大寬度,

小數點前的數字代表最小寬度。

例如: %6.9s 表示顯示一個長度不小於6且不大於9的字元串。若大於9, 則第9個字元以後的內容將被刪除。

2.使用printf函數時還要注意一個問題,那就是輸出表列中的求值順序。不同的編譯系統不一定相同,可以從左到右,也可從右到左。Turbo C是按從右到左進行的。請看下面兩個例子:

例1

main(){

int i=8;

printf("%d %d %d %d %d %d ",++i,--i,i++,i--,-i++,-i--);

}

運行結果

8

7

7

8

-7

-8

例2

main(){

int i=8;

printf("%d ",++i);

printf("%d ",--i);

printf("%d ",i++);

printf("%d ",i--);

printf("%d ",-i++);

printf("%d ",-i--);

}

運行結果:

9

8

8

9

-8

-9

這兩個程序的區別是用一個printf語句和多個printf 語句輸出。但從結果可以看出是不同的。為什麼結果會不同呢?就是因為printf函數對輸出表中各量求值的順序是自右至左進行的。在第一例中,先對最後一項“-i--”求值,結果為-8,然後i自減1後為7。 再對“-i++”項求值得-7,然後i自增1後為8。再對“i--”項求值得8,然後i再自減1後為7。再求“i++”項得7,然後i再自增1後為8。 再求“--i”項,i先自減1後輸出,輸出值為7。 最後才求輸出表列中的第一項“++i”,此時i自增1後輸出8。

但是必須注意,求值順序雖是自右至左,但是輸出順序還是從左至右,因此得到的結果是上述輸出結果。

補充:最近在調試程序時發現一段代碼如下:

printf(sFormat,"%%0?",THE_NUMBER_LEN);

輸出數組後發現sFormat = d;其中宏THE_NUMBER_LEN定義的為4,發現如果需要通過在printf轉化的數組中出現%,那麼就使用%%來代替,且後面的所有字元都會直接放入sFormat數組中一直遇到新的%。只有碰到“%+特定字元”,才會把右邊對應的變數放入進來。

例如: printf(sFormat,"ABC%%d%d%%s?bc",THE_NUMBER_LEN,6);輸出為ABC?%s6abc;

還有就是發現如果是修改成%0?,輸出的字元串就變成 ?,這樣我猜想就是在printf函數時,碰到第一個%0後知道再遇見下一個%前,如果中間沒有特定字元d,s,e,f等,通通變成空格,而我在%中間增加兩個的非特殊字元後,發現?前面的空格急劇增加,原因就不清楚。故兩%之間不能增加其他非特殊字元。

二 Scan函數

scanf()函數是格式化輸入函數, 它從標准輸入設備(鍵盤) 讀取輸入的信息。

其調用格式為:

scanf("<格式化字元串>", <地址表>);

格式化字元串包括以下三類不同的字元;

1. 格式化說明符: 格式化說明符與printf()函數中的格式說明符基本相同。

2. 空白字元: 空白字元會使scanf()函數在讀操作中略去輸入中的一個或多

個空白字元。

3. 非空白字元: 一個非空白字元會使scanf()函數在讀入時剔除掉與這個非

空白字元相同的字元。

注意:(1)地址表是需要讀入的所有變數的地址, 而不是變數本身:

----如果是一般的變數,通常要在變數名前加上"&";但輸出時是用變數名

----如果是數組,用數組名就代表了該數組的首地址;輸出時也是用數組名

----如果是指針,直接用指針名本身,不要加上“*”;輸出時也用該指針即可。

例1:

各個變數的地址之間同","分開。

main()

{

int i;

char *p, str[20];

scanf("%d", &i);

scanf("%s", p);

scanf("%s", str);

printf("i=%d ",i);

printf("%s ", p);

printf("%s ", str);

}

(2)scanf函數中是否包含空白/非空白字元導致輸入格式的不同

如:scanf("%d,%d",&i,&j); scanf中有,所以輸入的格式應該是5,6==>i=5,j=6

scanf("%d%d",&i,&j); 可以用空格或回車來分隔兩個輸入 如 5 6==>i=5,j=6

scanf("%d %d",&i,&j); 同上

(3) 實際使用scanf()函數時存在一個問題, 下面舉例進行說明:

當使用多個scanf()函數連續給多個字元變數輸入時, 例如:

main()

{

char c1, c2;

scanf("%c", &c1);

scanf("%c", &c2);

printf("c1 is %c, c2 is %c", c21, c2);

}

運行該程序, 輸入一個字元A後回車 (要完成輸入必須回車), 在執行scanf

("%c", &c1)時, 給變數c1賦值"A", 但回車符仍然留在緩沖區內, 執行輸入語句

scanf("%c", &c2)時, 變數c2輸出的是一空行, 如果輸入AB後回車, 那麼輸出結

果為: c1 is A, c2 is B。

要解決以上問題, 可以在輸入函數前加入清除函數fflush()( 這個函數的使

用方法將在本節最後講述)。修改以上程序變成:

#i nclude

main()

{

char c1, c2;

scanf("%c", &c1);

fflush(stdin);

scanf("%c", &c2);

printf("c1 is %c, c2 is %c", c1, c2);

}

在輸入字元數據時,若格式控制串中無非格式字元,則認為所有輸入的字元均為有效字元。

例如:scanf("%c%c%c",&a,&b,&c);

輸入為:d e f

則把'd'賦予a, ' ' 賦予b,'e'賦予c。

只有當輸入為: def

時,才能把'd'賦於a,'e'賦予b,'f'賦予c。

如果在格式控制中加入空格作為間隔,

如:scanf ("%c %c %c",&a,&b,&c);

則輸入時各數據之間可加空格。

例4

main(){

char a,b;

printf("input character a,b ");

scanf("%c%c",&a,&b);

printf("%c%c ",a,b);

}

由於scanf函數"%c%c"中沒有空格,輸入M N,結果輸出只有M。而輸入改為MN時則可輸出MN兩字元。

(4)格式字元串的一般形式為:

%

[輸入數據寬度][長度]類型

其中有方括弧[]的項為任選項。各項的意義如下:

1)類型:表示輸入數據的類型,其格式符和意義如下表所示。

格式 字元意義

d 輸入十進制整數

o 輸入八進制整數

x 輸入十六進制整數

u 輸入無符號十進制整數

f或e 輸入實型數(用小數形式或指數形式)

c 輸入單個字元

s 輸入字元串

2)“*”符:用以表示該輸入項,讀入後不賦予相應的變數,即跳過該輸入值。

如:scanf("%d %*d %d",&a,&b);

當輸入為:1 2 3時,把1賦予a,2被跳過,3賦予b。

3)寬度:用十進制整數指定輸入的寬度(即字元數)。

例如:

scanf("]",&a);

輸入:12345678

只把12345賦予變數a,其餘部分被截去。

又如:scanf("MM",&a,&b);

輸入:12345678

將把1234賦予a,而把5678賦予b。

例:

main()

{

int a,b;

scanf("MM",&a,&b);

printf("a=%d,b=%d",a,b);

}

輸入 12345 67890

運行結果 a=1234,b=5

4) 長度:長度格式符為l和h,l表示輸入長整型數據(如%ld) 和雙精度浮點數(如%lf)。h表示輸入短整型數據。

使用scanf函數還必須注意以下幾點:

1)scanf函數中沒有精度控制,如:scanf("%5.2f",&a);是非法的。不能企圖用此語句輸入小數為2位的實數。

2)在輸入多個數值數據時,若格式控制串中沒有非格式字元作輸入數據之間的間隔則可用空格,TAB或回車作間隔。C編譯在碰到空格,TAB,回車或非法數據(如對“%d”輸入“12A”時,A即為非法數據)時即認為該數據結束。

❹ 各位百度大神們,在keil uv3環境下編譯lpc2000系列程序,應該如何使用printf()函數

我來給你解答吧。
看你的printf語句的終端是指向哪裡了,可能是串口也可能只是你keil里邊的一個虛擬終端。
這倆差不多,keil的虛擬終端也是模擬的串口的
首先需要包含stdio.h
然後需要顯示實現一個函數,重新定義一個fput函數,該函數是ANSI標準的,在這個函數里邊的實現的是發送一個字元到串口。然後以此函數為基礎的printf就可以用了。詳細的步驟,請查查「標准輸出函數的重定義」。

❺ c程序的運行環境和運行一個c程序的方法實驗報告書

實驗目的 (1)了解所用的計算機系統的基礎操作方法,學會獨立使用該系統。 (2)了解在該系統上如何編輯、編譯、連接和運行一個C程序。 (3)通過運行簡單的C程序,初步了解C源程序的特點。 二、實驗內容 1.檢查所用的計算機系統是否已安裝了C編譯系統並確定它所在的子目錄。如果是在Windows操作系統下使用Turbo C編譯器,可以按以下步驟進行操作: ①單擊Windows桌面上的「開始」按鈕,在菜單中單擊「查找(F)」,在其右面的下拉菜單中單擊「文件或文件夾(F)」。屏幕上出現「查找」窗口。 ②在「名稱」框中輸入文件名「tc.exe」,單擊「開始查找」按鈕,系統即自動在指定的范圍內尋找所需要文件,如果找到,就會顯示出文件路徑(例如:C:\lib\tc或c:\tc)。 ③注意:在「搜索」框中應說明搜索范圍,如使「搜索」欄中的內容為「C:\」,表示從根目錄開始尋找,即搜索整個C盤。 2.建立用戶自己的子目錄 ①利用「Windows資源管理器」在磁碟(如D盤)上建立自已的文件夾。 ②利用DOS命令md在磁碟上建立自己的子目錄。 3.進入TC工作環境 第一種方法; ①單擊桌面上的「開始」按鈕,從菜單中選擇「程序」,單擊它然後在其下拉菜單中選擇「MS-DOS」,屏幕上出現MS-DOS窗口。 ②用DOS命令cd,使當前目錄改變為tc.exe所在的子目錄(例如:C:\lib\tc)。 ③在tc的子目錄下輸入tc,按回車鍵進入tc的工作環境。 第二種方法: 用滑鼠雙擊「我的電腦」圖標,進入C盤根目錄,在C盤根目錄下找到tc.exe文件所在的文件夾(如C盤下的lib文件夾下的tc文件夾),在文件夾中找到tc.exe文件,雙擊滑鼠進入TC的工作環境。 4.熟悉Turbo C集成環境 ①了解和熟悉編輯(Edit)窗口和信息(Message)窗口的作用。試一下能否向信息窗口輸入程序。按功能鍵F5,觀察它有什麼作用,再按一次F5,再觀察它有什麼作用。按F6,觀察它有什麼作用;再按一次F6,再觀察它有什麼作用。(參見第一部分的1.1節) ②按功能鍵F10,並按回車鍵,觀察「File」菜單,了解它們的作用和方法。用鍵盤上的「→」鍵,分別選中Edit、Run、Compile、Project、Options、Debug、Break/watch,觀察它們的菜單,大致上了解它們的作用,以後用到時再深入了解。 ③選擇File菜單中的New並按回車鍵,在編輯窗口中隨意輸入幾行字元,觀察窗口頂部左端line和col後面數字的變化。 5.編輯並運行一個簡單的程序 ①再選擇File菜單中的New並按回車鍵,使編輯窗口變成空白。 ②輸入下面的程序 main( ) { printf("* * * * *\n"); printf(" Hello.\n"); printf("* * * * *\n"); } ③按功能鍵F9進行編譯和連接,觀察屏幕上顯示的編譯信息。如果出現「出錯信息」,則應找出原因並改正之,再進行編譯。 ④如果編譯無錯誤,按Ctrl和F9鍵使程序運行,按Alt和F5鍵,切換到用戶屏,觀察運行結果。 ⑤按任一鍵回到TC窗口,將程序命令為ex1.c保存在自已的子目錄下。(參見第一部分1.2節的內容) 6.編輯並運行另一個C程序 ①再選擇File→New,使編輯窗口變成空白。 ②輸入以下程序 main( ) { int a,b,sum; a=150;b=200; sum=a+b; printf("sum is %d\n",sum); } ③按F9進行編譯,仔細分析編譯信息窗口和Message窗口,可能顯示有多個錯誤,逐個修改,直到不出現錯誤。 ④運行程序,分析運行結果。 ⑤將程序命名為ex2.c,保存到自己所建的子目錄下。 7.編輯並運行一個需要在運行時輸入數據的程序 ①清空編輯窗口,輸入下面的程序。 main( ) { int a,b, max; scanf("%d%d",&a,&b); if(a>b) max=a; else max=b; printf("%d",max); } ②編輯並運行,注意按Ctrl和F9運行後,先從鍵盤輸入整數2和5,然後按回車鍵,再按Alt和F5鍵,觀察運行結果。 ③將程序中的第3行改為: int a;b;max; 再進行編譯,觀察其結果。 ④將程序第5、6兩行合並為一行,即 if(a>b) max=a ; else max=b ; 進行編譯和運行,分析結果。 將程序命名為ex3.c保存在用戶自己的子目錄下。

麻煩採納,謝謝!

❻ c語言里怎麼使用printf

printf()函數是格式化輸出函數,調用格式為: printf("<格式化字元串>", <參量表>)。

scanf()函數是格式化輸出函數,調用格式為:scanf("<格式化字元串>", <參量表>)。

格式輸出,它是c語言中產生格式化輸出的函數(在 stdio.h 中定義)。用於向終端(顯示器、控制台等)輸出字元。格式控制由要輸出的文字和數據格式說明組成。要輸出的的文字除了可以使用字母、數字、空格和一些數字元號以外,還可以使用一些轉義字元表示特殊的含義。

(6)使用printf進行編譯的實驗步驟擴展閱讀

C語言是一門通用計算機編程語言,廣泛應用於底層開發。C語言的設計目標是提供一種能以簡易的方式編譯、處理低級存儲器、產生少量的機器碼以及不需要任何運行環境支持便能運行的編程語言。

盡管C語言提供了許多低級處理的功能,但仍然保持著良好跨平台的特性,以一個標准規格寫出的C語言程序可在許多電腦平台上進行編譯,甚至包含一些嵌入式處理器(單片機或稱MCU)以及超級電腦等作業平台。

二十世紀八十年代,為了避免各開發廠商用的C語言語法產生差異,由美國國家標准局為C語言制定了一套完整的美國國家標准語法,稱為ANSI C,作為C語言最初的標准。

目前2011年12月8日,國際標准化組織(ISO)和國際電工委員會(IEC)發布的C11標準是C語言的第三個官方標准,也是C語言的最新標准,該標准更好的支持了漢字函數名和漢字標識符,一定程度上實現了漢字編程。

C語言是一門面向過程的計算機編程語言,與C++,Java等面向對象的編程語言有所不同。

其編譯器主要有Clang、GCC、WIN-TC、SUBLIME、MSVC、Turbo C等。

參考資料網路-c語言

❼ printf函數的實現方式

其實printf和getchar()類似,它們都是一個」外殼「,真正實現功能的不是它本身,而是通過調用別的函數。
getchar() is equivalent to getc(stdin).
printf有一家子print函數

printf, fprintf, sprintf, snprintf, vprintf, vfprintf, vsprintf, vsnprintf - formatted output conversion
它們的聲明在不同的header file裡面

#include <stdio.h>

int printf(const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sprintf(char *str, const char *format, ...);
int snprintf(char *str, size_t size, const char *format, ...);

#include <stdarg.h>

int vprintf(const char *format, va_list ap);
int vfprintf(FILE *stream, const char *format, va_list ap);
int vsprintf(char *str, const char *format, va_list ap);
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
snprintf(), vsnprintf():
這兩個函數是C99新加的,編譯的時候 注意 -std=c99

實現之前還是「復習」一下printf比較好,就當是鋪墊
有意思的是printf的declaration。
int printf(const char *format, ...);
返回值是int,第一個參數是const字元串指針,第二個參數是個...
先看看返回值int有哪些情況
Return value
Upon successful return, these functions return the number of characters printed (excluding the null byte used to end output to strings).

嗯哼。。。返回的是成功列印的字元的個數,這里不包括NULL
demo:
#include<stdio.h>

int main()
{
int counter = 0;

counter = printf("hello world! %d\n",10);

printf("counter is %d\n",counter);

return 0;
}
jasonleaster@ubuntu:~$ ./a.out
hello world! 10
counter is 16

接著,第一個參數是一個指針,指向const字元串
Format of the format string
The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of
zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications,
each of which results in fetching zero or more subsequent arguments. Each conversion specification is introced by the character %,
and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an optional minimum field width,
an optional precision and an optional length modifier.

很少人會用下面這種用法
printf("%*d",10,5);
我第一次遇到的時候,可以說是「驚愕」,究竟會列印什麼東西。折騰了好久,最後搞定了。總結在這里
http://blog.csdn.net/cinmyheart/article/details/10116359

Format of the format string

The format string is a character string, beginning and ending in its initial shift state, if any. The format string is composed of zero or more directives: ordinary characters (not %), which are copied unchanged to the output stream; and conversion specifications, each of which results in fetching zero or more subsequent arguments. Each conversion specification is introced by the character %, and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an optional minimum field width, an optional precision and an optional length modifier.
The arguments must correspond properly (after type promotion) with the conversion specifier. By default, the arguments are used in the order given, where each '*' and each conversion specifier asks for the next argument (and it is an error if insufficiently many arguments are given). One can also specify explicitly which argument is taken, at each place where an argument is required, by writing "%m$" instead of '%' and "*m$" instead of '*', where the decimal integer m denotes the position in the argument list of the
desired argument, indexed starting from 1. Thus,
printf("%*d", width, num);
and
printf("%2$*1$d", width, num);
are equivalent. The second style allows repeated references to the same argument. The C99 standard does not include the style using '$', which comes from the Single UNIX Specification. If the style using '$' is used, it must be used throughout for all conversions taking an argument and all width and precision arguments, but it may be mixed with "%%" formats which do not consume an argument.
There may be no gaps in the numbers of arguments specified using '$'; for example, if arguments 1 and 3 are specified, argument 2
must also be specified somewhere in the format string.

第三個參數 ...
嗯,這傢伙有點屌,叫做變長參數。把這個搞定,C總會有點長進的
這個stdarg.h 我在現在的GCC和現在的linux 3.0版本的內核裡面找了好久,都木有,估計是封裝到被的地方了。。。。
__builtin_va_start(v,l) 線索就死在這個地方。。。之後就找不到__builtin_va_start的定義了

還是看早起內核的實現吧
0.12內核裡面的stdarg.h
#ifndef _STDARG_H
#define _STDARG_H

typedef char *va_list;

/* Amount of space required in an argument list for an arg of type TYPE.
TYPE may alternatively be an expression whose type is used. */

#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))

#ifndef __sparc__
#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#else
#define va_start(AP, LASTARG) \
(__builtin_saveregs (), \
AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))
#endif

void va_end (va_list); /* Defined in gnulib */
#define va_end(AP)

#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))

#endif /* _STDARG_H */

va_list 是一個指向字元串的指針
分析上面的宏定義#define __va_rounded_size(TYPE) \
(((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int))
這個用來得到TYPE元素類型的位元組大小,若不足4位元組(例如short 和char),那麼認為這個元素的大小為4位元組,簡單的說就是檢測元素的大小,不足4位元組的當作4位元組看待。。。#define va_start(AP, LASTARG) \
(AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG)))

AP一般都是va_list,LASTARG則是 指向參數變長函數的格式化字元串的指針.
va_start的作用就很明顯了。取得變長參數列表的第一個參數的地址。
va_end 則是把指針va_list 置0 (通過google知道的,這個va_end真沒找到定義,代碼裡面就一句#define 我無能為力啊。。。)
不過知道用va_start 和va_end 就OK啦
下面先來個變長參數的demo
/*****************************************************************************
code writer : EOF
code date : 2014.04.26
e-mail:[email protected]
code purpose:
just a demo for varible parameter function.

usage: va_sum(a number,anohter number...,0);
va_sum(1,2,3,4,5,0); return 15

******************************************************************************/

#include <stdarg.h>
#include <stdio.h>

int va_sum(int* a,...);

int main()
{
int number = 1;

int foo = 0;

foo = va_sum(&number,2,3,4,5,0);

return 0;
}

int va_sum(int* a,...)
{
int counter = 0;
int element = 0;

va_list arg;

va_start(arg,a);

while((element = va_arg(arg,int)) != 0)
{
counter += element;
}

va_end(arg);

return counter;
}

#define va_arg(AP, TYPE) \
(AP += __va_rounded_size (TYPE), \
*((TYPE *) (AP - __va_rounded_size (TYPE))))

❽ c語言printf用法

這個相當於
printf((const char *)'001');
你隨意指定了一個指針,然後恰好那個地方有數據,但是沒有'\0『,所以就輸出了一堆亂七八糟。
實際上也有可能會崩潰,還有可能什麼都不輸出。
C語言不檢查參數類型,你無論寫什麼都當做const char * fmt。這是C語言的優點之一,也是缺陷之一。不過目前大部分編譯器會發出警告,早期的編譯器可能不會。

你可以這樣考慮:
printf("%X\n",'001');
'001'實際上就是一個數,不同編譯器略有不同。

gcc 4上面的結果是303031
printf('001');
相當於printf((const char *)0x303031);

閱讀全文

與使用printf進行編譯的實驗步驟相關的資料

熱點內容
小天才app怎麼升級v242 瀏覽:544
簡單手工解壓玩具製作大全 瀏覽:926
免費編程電子書 瀏覽:869
想玩游戲什麼app最合適 瀏覽:560
安卓手機如何用airportspro 瀏覽:448
怎麼清理idea編譯緩存 瀏覽:951
鏡頭app怎麼推廣 瀏覽:437
什麼app隨便看電視劇 瀏覽:307
2021程序員薪酬 瀏覽:708
糖豆廣場怎麼下載app 瀏覽:213
qtvs2019選哪個編譯器 瀏覽:124
壓縮空氣管能焊嗎 瀏覽:284
linux中yum命令 瀏覽:397
在職演算法工程師 瀏覽:706
電碼加密函數方法有幾種 瀏覽:802
後綴是pdf 瀏覽:720
pr導出壓縮 瀏覽:32
命令語氣 瀏覽:245
脊柱解剖pdf 瀏覽:714
plc入門編程題目及答案 瀏覽:383