創作不易,友友們給個三連吧
一、C語?的基本概念與發展歷史
1.1 人和計算機進行交流的語言
? ? ? ? 通常,我們使用英語、中文等語言來進行兩個人之間的交流。這意味著當我們想要和他人進行交流時,我們需要一種語言來表達自己的感受。同樣的,當我們想要和計算機進行交流時,我們也需要一種語言,可以通過該語言向計算機提供信息,傳達指令,我們稱該語言為計算機語言。?
? ? ? ?然而C語言只不過是眾多語言中的一種,像C++/Java/Go/Python都是計算機語?。
1.2 C語言的輝煌和歷史
C 語?最初是作為 Unix 系統的開發?具?發明的。
類似的操作系統還有:windows、linux、macos(蘋果)……
?1.3“C生萬物,編程之本”
C語言的四大領域:
游戲:目前很多游戲客戶端都是基于C++開發的,除了一些網頁游戲可能不是,所以如果想從事游戲開發行業學好C++是沒錯的。
服務器端開發:很多互聯網公司的后臺服務器程序都是基于C++開發的,而且大部分是linux,unix等類似操作系統。如果你想從事這樣的工作,需要熟悉linux操作系統及其在上面的開發,熟悉數據庫開發,精通網絡編程。
數字圖像處理:現在市面上有很多VC++圖像處理的書籍,可見在這個領域的應用軟件開發也是占了很大比重,需要深入學習數字圖像處理和模式識別等課程。
虛擬現實仿真:這個也是發展很快的計算機領域,目前各種數字地球,數字城市,虛擬地理環境什么的,出現了這方面的大量應用
? ? ? ? C語言出現時間較早,其他語言基本都是在C語言之后出現,或者在C語言的基礎上進行創造,比如Java,C++是兩門很有代表性的語言。
? ? ? ? 并且 學習了之后,語言的通用性還是存在的,所以在學習其他的語言的時候,學習起來就相對會簡單一點。
? ? ? ? TIOBE網站上可以查到每年編程語言的使用排名,其中c語言常見保持前3,
網址:https://www.tiobe.com/tiobe-index/
二、編譯器的選擇和使用方法
2.1 編譯和鏈接
? ? ? ? C語?是??編譯型計算機語?,C語言源代碼都是文本文件,文本文件本身無法執行,必須通過編譯器翻譯和鏈接器的鏈接,生成二進制的可執行文件,可執行文件才能執行。(計算機識別的是二進制指令)?C語?代碼是放在 .c 為后綴的?件中的,要得到最終運?的可執?程序,中間要經過編譯和鏈接2個過程。
? ? ? ??個工程?般都會有多個源文件組成,如下圖所示,演示了源程序經過編譯器和鏈接器處理的過程。
.c→.obj→.exe
??個工程?般都會有多個源文件組成,如下圖所示,演示了源程序經過編譯器和鏈接器處理的過程。
1. 每個源文件(.c)單獨經過編譯器處理?成對應的目標?件(.obj為后綴的?件)
2. 多個?標?件和庫文件經過鏈接器處理?成對應的可執行程序(.exe?件)
?2.2 編譯器對比和選擇
? ? ? ? ?C語?是??編譯型的計算機語?,需要依賴編譯器將計算機語?轉換成機器能夠執?的機器指令。
? ? ? ? ?那我們常?的C語?編譯器都有哪些呢? ?如:msvc、clang、gcc 就是?些常?的編譯器,當然也有?些集成開發環境如:VS2022、 XCode、CodeBlocks、DevC++、Clion等。
集成開發環境(IDE):?于提供程序開發環境的應?程序,?般包括代碼編輯器、 編譯器 、 調試器 和 圖形??界? 等?具。 集成了代碼編寫功能、分析功能、編譯功能、調試功能等?體化的開發軟件服務套。
?
? VS2022 集成了MSVC(安裝報包較??些,安裝簡單,?需多余配置,使?起來?常?便)
? XCode 集成了clang(蘋果電腦上的開發?具)
? CodeBlocks 集成了gcc(這個?具?較?眾,需要配置環境,不太推薦)
? DevC++ 集成了gcc(?巧,但是?具過于簡單,對于代碼?格的養成不好,?些競賽使?)
? Clion 是默認使?CMake,編譯器是可以配置的(?具是收費,所以暫時推薦?家使?)
? VSCode 具有強大的插件系統,可安裝各種插件,來搭建c/c++的開發環境(不推薦新手使用)
新手推薦使用VS2022社區版本,免費并且使用方便。
?2.3 VS的優缺點和下載方法
優點:
? VS2022 是?個主流的集成開發環境,企業中使?較為普遍
? VS2022 包含了:編輯器+編譯器+調試器,功能強?
? 直接安裝即可使?,基本不?額外配置環境,上?容易
? 默認界?是中?的,初學者友好
缺點:
? 功能豐富,安裝包?,占?空間多。
下載方法:https://visualstudio.microsoft.com/zh-hans/downloads/
安裝教程:https://www.bilibili.com/video/BV11R4y1s7jz/
2.4 VS項目和源文件、頭文件介紹
在項?中就可以添加源?件和頭?件。
C語?把 .c 為后綴的?件稱為源?件,把 .h 為后綴的?件稱為頭?件。
2.5 在VS上創建新項目
2.5.1 寫代碼的前的步驟
1、創建項目(代碼是在項目中管理的)
2、創建.c文件
3、寫C語言代碼,邀嚴格按照C語言的語法來寫!!
?
?
2.5.2 項目名稱
1、項目名稱最好有自己的實際意義
2、項目名稱最好不要使用后中文
3、不要使用特殊字符
2.5.3 項目存儲路徑?
1、代碼的位置邀自己找一個熟悉的路徑維護起來
2、這個代碼的路徑不要包括空格、特殊字符、中文字符
三、main函數
每個 C 語?程序不管有多少?代碼,都是從 main 函數開始執?的, main 函數是程序的??, main 函數也被叫做:主函數。 main 前?的 int 表? main 函數執?結束的時候返回?個整型類 型的值。所以在 main 函數的最后寫 return 0; 正好前后呼應。
? main函數是程序的入口
? main函數有且僅有?個
? 即使?個項?中有多個.c?件,但是只能有?個main函數(因為程序的入口只能有?個)
? main函數可以出現在任意位置,若在主函數中調用的哪些函數,則必須在main函數之前對所調用的函數進行聲明,或者包含其被調用函數的頭文件
? 一般約定返回0,在c語言中正常在返回0,異常會返回非0
int main()
{
printf("hello C\n");
return 0;
}
在VS2022上運?代碼的快捷鍵: Ctrl+f5?
四、關鍵字介紹
? ? ? C語?中有?批保留的名字的符號,?如: int 、 if 、 return ,這些符號被稱為保留字或者關鍵 字。
? ? ? ? 關鍵字都有特殊的意義,是保留給C語言使用的
? ? ? ? 程序員自己在創建標識符的時候是不能和關鍵字重復的
? ? ? ? 關鍵字也是不能自己創建的。 C語言的32個關鍵字如下:
注:在C99標準中加?了 inline 、 restrict 、 _Bool 、 _Comploex 、 _Imaginary 等關鍵字。 ?些關鍵字?家可以去了解?下,不過使?最多的還是上?的32個關鍵字。
注:https://zh.cppreference.com/w/c/keyword(C語?關鍵字的全部介紹)
注: difine不是關鍵字,他是編譯器實現的用來定義宏的預處理指令,不是c語言中的內容。
五、字符和ASCII編碼
? ? ? ? ?在鍵盤上可以敲出各種字符,如:a,q,@,#等,這些符號都被稱為字符,C語?中字符是?單引號 括起來的,如:'a','b','@'。單個字符的打印可以使用%c來指定格式。
? ? ? ? 我們知道在計算機中所有的數據都是以二進制的形式存儲的,那這些字符在內存中分別以什么樣的?進制存儲的呢?如果我們每個???給這些字符中的每個字符編?個?進制序列,這就叫做編碼,為了?便?家相互通信,不造成混亂,后來美國國家標準學會(ANSI)出臺了?個標準 ASCII 編碼,C語言中的字符就遵循了ASCII 編碼的?式。
參考:https://zh.cppreference.com/w/cpp/language/ascii
? ? ? 我們不需要記住所有的ASCII碼表中的數字,使?時查看就可以,不過我們最好能掌握?組特殊的數據:
?? 字符A~Z的ASCII碼值從65~90
? 字符a~z的ASCII碼值從97~122
? 對應的大小寫字符(a和A)的ASCII碼值的差值是32
? 數字字符0~9的ASCII碼值從48~57 ? 換? \n 的ASCII值是:10
? 在這些字符中ASCII碼值從0~31 這32個字符是不可打印字符,無法打印在屏幕上觀察
? 字符其實也屬于整型家族
比如:可打印字符展示(32-127)
#include <stdio.h>
int main()
{int i = 0;for (i = 32; i <= 127; i++){printf("%c ", i);if (i % 16 == 15)printf("\n");}return 0;
}
? ! " # $ % & ' ( ) * + , - . /
0 1 2 3 4 5 6 7 8 9 : ; < = > ?
@ A B C D E F G H I J K L M N O
P Q R S T U V W X Y Z [ \ ] ^ _
` a b c d e f g h i j k l m n o
p q r s t u v w x y z { | } ~
六、字符串和\0
使用雙引號括起來的一串字符就被稱為字符串,如:“abcdef”,就是一個字符串。
字符串的打印格式可以使用 %s 來指定,也可以直接打印如下:
#include <stdio.h>
int main()
{printf("%s\n", "hello C");printf("hello c");return 0;
}
? ? ? ? C語?字符串中?個特殊的知識,就是在字符串的末尾隱藏放著?個 \0 字符,這個 \0 字符是字符串 的結束標志。
? ? ? 為了觀察這一現象,我們要在調試中找到監視功能,它在VS2022里面的路徑是:【調試】->【窗口】->【監視】,但當我們打開此路徑,我們并沒有找到監視的功能。
原因是:監視必須是代碼在調試的條件下進行,所以按下ctrl+F10,開始調試程序,此時再來到剛才的路徑,就能找到監視的窗口了。
左邊出現箭頭即為進入調試階段
? ? ? 在進入調試狀態后,比如想要監視某一個變量,添加本代碼變量于監視窗口中添加完待監視項后,按f10 代碼會一步一步運行,待監視項便也隨著代碼運行進行改變。
? ? ? ?我們可以發現對于字符串"abcdef",我們實際上看到了6個字符:a,b,c,d,e,f,但是實際上在末尾還隱藏?個 \0 的 轉義字符, \0 是字符串的結束標志。所以我們在使?庫函數 printf() 打印字符串或者 strlen() 計算字符串?度的時候,遇到 \0 的時候就?動停?了。
監視窗口的優點:
1.便于理解代碼,對代碼工作原理運行順序的理解都很有幫助
2.可以方便地在大型工作表中檢查、審核或確認公式計算及其結果。. 使用“監視窗口”,無需反復滾動或定位到工作表的不同部分。
注:C語?中也可以把?個字符串放在?個字符數組中,我們在這里利用下?的代碼驗證?下 \0 的功能。
#include<stdio.h>
int main()
{char arr1[] = { 'a', 'b', 'c' };//arr1數組中存放3個字符char arr2[] = "abc"; //arr2數組中存放字符串printf("%s\n", arr1);//不含有/0,所以沒有停止的標志,會一直輸出下去,會出現一些隨機值printf("%s\n", arr2);//含有/0,所以會輸出到停止return 0;
}
abc燙燙燙燙燙燙燙燙燙燙燙燙燙燙蘟bc
abc
? ? ? ?我們可以看到, arr1 字符數組在打印的時候,打印了 a 、 b 、 c 后還打印了?些隨機值,這就是 因為 arr1 在末尾的地?沒有 \0 字符作為結束標志,在打印的時候沒有停?。
? ? ? ?但是 arr2 的打印就是完全正常的,就是因為 arr2 數組是使?字符串常量初始化的,數組中有 \0 作為技術標志,打印可以正常停?。
?如果我們在arr1數組中單獨放?個 '\0' 字符呢?
#include<stdio.h>
int main()
{char arr1[] = { 'a', 'b', 'c' ,'\0'};//arr1數組中存放3個字符char arr2[] = "abc"; //arr2數組中存放字符串printf("%s\n", arr1);printf("%s\n", arr2);return 0;
}
abc
abc
? ? ? 則我們可以發現打印的結果是?樣的了,都是打印到 \0 的時候就停?了,由此可以說明\0的作用以及重要性。
七、轉義字符
也許在前?的代碼中你看到 \n , \0 很納悶時啥。其實在字符中有?組特殊的字符是轉義字符,轉義 字符顧名思義:轉變原來的意思的字符。
C語?中像這樣的轉義字符,具體如下:
? \? :在書寫連續多個問號時使?,防?他們被解析成三字?詞,在新的編譯器上沒法驗證了。
? \' :?于表?字符常量'(想打印單引號時用\將'轉換成字符)
? \" :?于表??個字符串內部的雙引號(想打印雙引號時用\將'轉換成字符)
? \\ :?于表??個反斜杠,防?它被解釋為?個轉義序列符。(相當于\\=1個\)
? \a :警報,這會使得終端發出警報聲或出現閃爍,或者兩者同時發?。
? \b :退格鍵,光標回退?個字符,但不刪除字符。(覆蓋前面那個字符)
? \f :換?符,光標移到下??。在現代系統上,這已經反映不出來了,?為改成類似于 \v 。
? \n :換?符。
? \r :回?符,光標移到同??的開頭。
? \t :制表符,光標移到下?個?平制表位,通常是下?個8的倍數。(讓輸出的內容更美觀和可讀)
? \v :垂直分隔符,光標移到下?個垂直制表位,通常是下??的同?列。
下?2種轉義字符可以理解為:字符的8進制或者16進制表?形式
? \ddd :d d d表?1~3個?進制的數字。 如: \130 表示字符X(字符八進制的表示形式)
? \xdd :d d表?2個?六進制數字。 如: \x30 表示字符0(字符十六進制的表示形式)
? \0 :null 字符,代表沒有內容, \0 就是 \ddd 這類轉義字符的?種,?于字符串的結束標志,其 ASCII碼值是0.
注: 關于轉義字符我們首先要了解,然后要能在字符串中識別出來。(求字符串長度時,轉義字符只占一個字節)
題型:求復雜字符串的長度
int main()
{printf("%zd\n", strlen("c:\test\130\test.c"));
}
13? ? ? ?因為\t和\130都只算1個字符?
轉義字符參考:https://zh.cppreference.com/w/c/language/escape
八、語句和語句分類
8.1空語句
? ?空語句是最簡單的,?個分號就是?條語句,是空語句。
#include <stdio.h>
int main()
{;//空語句return 0;
}
? ? ? ? 空語句?般出現的地?是:這?需要?條語句,但是這個語句不需要做任何事,就可以寫?個空語句。
8.2表達式語句
? ? ? ?表達式語句就是在表達式的后邊加上分號。如下所?:
#include <stdio.h>
int main()
{int a = 20;int b = 0;b = a + 5; //表達式語句return 0;
}
8.3函數調用語句
函數調?的時候,也會加上分號,就是函數調?語句。
#include <stdio.h>
int Add(int x, int y)
{return x+y;
}int main()
{printf("hehe\n");//函數調?語句int ret = Add(2, 3);//函數調?語句 return 0;
}
8.4復合語句
復合語句其實就是前?講過的代碼塊,成對括號中的代碼就構成?個代碼塊,也被稱為復合語句。
#include <stdio.h>
void print(int arr[], int sz) //函數的?括號中的代碼也構成復合語句
{int i = 0;for(i=0; i<sz; i++){printf("%d ", arr[i]);}
}
int main()
{int i = 0;int arr[10] = {0};for(i=0; i<10; i++) //for循環的循環體的?括號中的就是復合語句{arr[i] = 10-i;printf("%d\n", arr[i]);}return 0;
}
8.5控制語句
? ? ? ? 控制語句?于控制程序的執?流程,以實現程序的各種結構?式(C語??持三種結構:順序結構、選擇結構、循環結構),它們由特定的語句定義符組成,C語?有九種控制語句。
可分成以下三類:
1. 條件判斷語句也叫分?語句:if語句、switch語句;
2. 循環執?語句:do while語句、while語句、for語句;
3. 轉向語句:break語句、goto語句、continue語句、return語句。
九、注釋
注釋是對代碼的說明,編譯器會忽略注釋,也就是說,注釋對實際代碼沒有影響。
注釋是給程序員??,或者其他程序員看的。
好的注釋可以幫我們更好的理解代碼,但是也不要過度注釋,不要寫沒必要的注釋。
當然不寫注釋可能會讓后期閱讀代碼的?抓狂。 寫注釋?定程度上反應了程序作者的素質,建議?家寫必要的注釋,在未來找?作的時候,寫代碼時 留下必要的注釋也會給?試官留下更好的印象。
第?種?法是將注釋放在 /*...*/ 之間,內部可以分?。
注:這種注釋?定不能忘記寫結束符號 */ ,否則很容易導致錯誤。
注:/* */ 的這個注釋不?持嵌套注釋, /* 開始注釋后,遇到第?個 */ 就認為注釋結束了。
第?種方法是將注釋放在雙斜杠 // 后?,從雙斜杠到?尾都屬于注釋。這種注釋只能是單?,可以 放在??,也可以放在??語句的結尾。這是 C99 標準新增的語法。
注:不管是哪?種注釋,都不能放在雙引號??。 雙引號??的注釋符號,會成為字符串的?部分,解釋為普通符號,失去注釋作?。
注:編譯時,注釋會被替換成?個空格,所以(min/*? ? 這?是注釋? ?*/Value) 會變成 min Value ,而不是 minValue 。
十、數據類型
C語?提供了豐富的數據類型來描述?活中的各種數據。
使?整型類型來描述整數,使?字符類型來描述字符,使?浮點型類型來描述?數。
? ? ? ? 所謂“類型”,就是相似的數據所擁有的共同特征,編譯器只有知道了數據的類型,才知道怎么操作 數據。
10.1 字符型
char
[signed] char
unsigned char
10.2 整型
//短整型
short [int]
[signed] short [int]
unsigned short [int]
//整型
int
[signed] int
unsigned int
//?整型
long [int]
[signed] long [int]
unsigned long [int]
//更?的整型
//C99中引?
long long [int]
[signed] long long [int]
unsigned long long [int]
10.3 浮點型
float
double
long double
10.4 布爾類型
C 語?原來并沒有為布爾值單獨設置?個類型,?是使?整數 0 表?假,?零值表?真。
在 C99 中也引?了 布爾類型 ,是專門表示真假的。
_Bool
布爾類型的使?需要包含頭?件<stdbool.h>?
布爾類型變量的取值是:true或者false
10.5 自定義類型?
C語言:自定義類型——結構體-CSDN博客
C語言:自定義類型——聯合和枚舉-CSDN博客
10.6 數據類型的長度
10.7?signed 和 unsigned?
C 語?使? signed 和 unsigned 關鍵字修飾字符型和整型類型的。
signed 關鍵字,表??個類型帶有正負號,包含負值;
unsigned 關鍵字,表?該類型不帶有正負號,只能表?零和正整數。
整數變量聲明為 unsigned 的好處是,同樣?度的內存能夠表?的最?整數值,增?了?倍。
C 語言規定 char 類型默認是否帶有正負號,由當前系統決定。
所以 char 不等同于 signed char ,它有可能是 signed char ,也有可能是 unsigned char?
這?點與 int 不同, int 就是等同于 signed int 。
十一、變量
類型是?來創建變量的。C語?中把經常變化的值稱為變量,不變的值稱為常量。
data_type name;| || |
數據類型 變量名
11.1 變量初始化
變量在創建的時候就給?個初始值,就叫初始化。
int age = 18;
char ch = 'w';
double weight = 48.0;
unsigned int height = 100;
11.2?變量的分類
? 全局變量:在?括號外部定義的變量就是全局變量
全局變量的使?范圍更?,整個?程中想使?,都是有辦法使?的。
? 局部變量:在?括號內部定義的變量就是局部變量
局部變量的使?范圍是?較局限,只能在??所在的局部范圍內使?的。
int global = 2023;//全局變量
int main()
{int local = 2018;//局部變量printf("%d\n", local);printf("%d\n", global);return 0;
}
注意:局部變量和全局變量同名的時候,局部變量優先使?。?
11.3 變量的命名規則和規范
1.一個變量名稱可以由數字、字母、下劃線、美元符號($) 組成
2.嚴格區分大小寫
3.不能由數字開頭,不要使用中文漢字命名
4.不能是保留字或者關鍵字
5.不要出現空格
十二、printf詳細介紹
12.1 基本用法
printf() 的作?是將參數?本輸出到屏幕。它名字??的 f 代表 format (格式化),表?可以 定制輸出?本的格式。頭文件<stdio.h>
int main(void)
{printf("Hello World");return 0;
}
Hello World?
? ? ?printf() 不會在自動在行尾添加換行符,運?結束后,光標就停留在輸出結束的地?,不會?動換行。 為了讓光標移到下?行的開頭,可以在輸出文本的結尾,添加?個換行符 \n 。?
12.2 占位符列舉
? %a :?六進制浮點數,字?輸出為?寫。
? %A :?六進制浮點數,字?輸出為?寫。
? %c :字符。 ? %d :?進制整數。
? %e :使?科學計數法的浮點數,指數部分的 e 為?寫。
? %E :使?科學計數法的浮點數,指數部分的 E 為?寫。
? %i :整數,基本等同于 %d 。
? %f :?數(包含 float 類型和 double 類型)。
? %g :6個有效數字的浮點數。整數部分?旦超過6位,就會?動轉為科學計數法,指數部分的 e 為?寫。
? %G :等同于 %g ,唯?的區別是指數部分的 E 為?寫。
? %hd :?進制 short int 類型。
? %ho :?進制 short int 類型。
? %hx :?六進制 short int 類型。
? %hu :unsigned short int 類型。
? %ld :?進制 long int 類型。
? %lo :?進制 long int 類型。
? %lx :?六進制 long int 類型。
? %lu :unsigned long int 類型。
? %lld :?進制 long long int 類型。
? %llo :?進制 long long int 類型。
? %llx :?六進制 long long int 類型。
? %llu :unsigned long long int 類型。
? %Le :科學計數法表?的 long double 類型浮點數。
? %Lf :long double 類型浮點數。
? %n :已輸出的字符串數量。該占位符本?不輸出,只將值存儲在指定變量之中。
? %o :?進制整數。
? %p :指針。
? %s :字符串。
? %u :?符號整數(unsigned int)。
? %x :?六進制整數。
? %zd : size_t 類型。
? %% :輸出?個百分號。
12.3 占位符的使用
printf() 可以在輸出?本中指定占位符。 所謂 “占位符”,就是這個位置可以?其他值代?。
常?的占位符除了 %d ,還有 %s 表?代?的是字符串。
輸出文本里面可以使用多個占位符!!!
int main()
{printf("%s says it is %d o'clock\n", "lisi", 21);return 0;
}
lisi says it is 21 o'clock 。?
? ? ? printf() 參數與占位符是??對應關系,如果有 n 個占位符, printf() 的參數就應該有 n + 1 個。如果參數個數少于對應的占位符, printf() 可能會輸出內存中的任意值。?
12.4 輸出格式
printf() 允許限定占位符的最?寬度。
12.4.1 限定寬度
int main()
{printf("%5d\n", 123); // 輸出為 " 123"return 0;
}
輸出結果:“? 123”?
上??例中, %5d 表?這個占位符的寬度?少為5位。如果不滿5位,對應的值的前?會添加空格。 輸出的值默認是右對?,即輸出內容前?會有空格;如果希望改成左對?,在輸出內容后?添加空格,可以在占位符的 % 的后?插??個 - 號。?
int main()
{printf("%-5d\n", 123); // 輸出為 "123 "return 0;
}
?輸出結果:“123? ”?
對于小數,這個限定符會限制所有數字的最小顯示寬度。?
int main()
{printf("%12f\n", 123.45);return 0;
}
"? 123.450000"?
上??例中, %12f 表?輸出的浮點數最少要占據12位。由于小數的默認顯示精度是?數點后6位, 所以 123.45 輸出結果的頭部會添加2個空格。?
12.4.2 總是顯示正負號
默認情況下, printf() 不對正數顯? + 號,只對負數顯? - 號。如果想讓正數也輸出 + 號,可 以在占位符的 % 后?加?個 + 。
int main()
{printf("%+d\n", 12); // 輸出 +12printf("%+d\n", -12); // 輸出 -12return 0;
}
+12
-12?
上??例中, %+d 可以確保輸出的數值,總是帶有正負號。?
12.4.3 限定小數位數
輸出小數時,有時希望限定?數的位數。舉例來說,希望?數點后?只保留兩位,占位符可以寫 成 %.2f 。
int main()
{printf("Number is %.2f\n", 0.5);return 0;
}
Number is? 0.50
這種寫法可以與限定寬度占位符,結合使?。?
int main()
{printf("%6.2f\n", 0.5);return 0;
}
"? ?0.50"?
最?寬度和?數位數這兩個限定值,都可以? * 代替,通過 printf() 的參數傳?。?
int main()
{printf("%*.*f\n", 6, 2, 0.5);return 0;
}
// 等同于printf("%6.2f\n", 0.5);
"? ?0.50"? ? ? ? ? ? ? ? ? ? ? ? ? 上述代碼等同于printf("%6.2f\n", 0.5);
12.4.4 輸出部分字符串
%s 占位符?來輸出字符串,默認是全部輸出。如果只想輸出開頭的部分,可以? %.[m]s 指定輸出 的?度,其中 [m] 代表?個數字,表?所要輸出的?度。
int main()
{printf("%.5s\n", "hello world");return 0;
}
?hello? ? ? ? ? ? ? ? ? 占位符 %.5s 表?只輸出字符串“hello world”的前5個字符,即“hello”。
12.5 printf的返回值?
printf的返回值返回的是字符串中字符的數量(和strlen的返回值差不多,但是strlen的返回值是size_t,而printf的返回值是int)
int main()
{int a=printf("hello world\n");printf("%d\n", a);return 0;
}
hello world
12?
十三、scanf詳細介紹
13.1 基本用法
scanf() 函數?于讀取用戶的鍵盤輸?。
程序運?到這個語句時,會停下來,等待??從鍵盤輸?。
??輸?數據、按下回?鍵后, scanf() 就會處理??的輸?,將其存?變量。
它的原型定義也在頭?件 stdio.h ,?scanf() 的語法跟 printf() 類似。?
scanf("%d", &i);
? ? ? ? 它的其余參數就是存放??輸?的變量,格式字符串??有多少個占位符,就有多少個變量。 上??例中, scanf() 的第?個參數 %d ,表???輸?的應該是?個整數。 %d 就是?個占位 符, % 是占位符的標志, d 表?整數。第?個參數 &i 表?,將??從鍵盤輸?的整數存?變量 i 。
? ? ? ? 變量前?必須加上 & 運算符(指針變量除外),因為 scanf() 傳遞的不是值,?是地址, 即將變量 i 的地址指向??輸?的值。 如果這?的變量是指針變量(?如字符串變量),那就不?加 & 運算符。
? ? ?scanf() 處理數值占位符時,會?動過濾空?字符,包括空格、制表符、換?符等。
? ? ?所以,??輸?的數據之間,有?個或多個空格不影響 scanf() 解讀數據。另外,??使?回? 鍵,將輸?分成??,也不影響解讀。?
scanf() 處理??輸?的原理是,??的輸?先放?緩存,等到按下回?鍵后,按照占位符對緩存 進?解讀。 解讀用戶輸?時,會從上?次解讀遺留的第?個字符開始,直到讀完緩存,或者遇到第?個不符合條件的字符為?。?
int main()
{int x;float y;// ??輸? " -13.45e12# 0"scanf("%d", &x);printf("%d\n", x);scanf("%f", &y);printf("%f\n", y);return 0;
}
輸入: -13.45e12# 0
輸出:-13
? ? ? ? ? 449999994880.000000
? ? ? ? 在上??例中, scanf() 讀取??輸?時, %d 占位符會忽略起?的空格,從 - 處開始獲取數據,讀 取到 -13 停下來,因為后?的 . 不屬于整數的有效字符。這就是說,占位符 %d 會讀到 -13 。 第?次調? scanf() 時,就會從上?次停?解讀的地?,繼續往下讀取。這?次讀取的?字符 是 . ,由于對應的占位符是 %f ,會讀取到 .45e12 (表示0.45*10^12),這是采?科學計數法的浮點數格式。后?的 # 不屬于浮點數的有效字符,所以會停在這?。?
13.2 scanf的返回值?
scanf() 的返回值是?個整數,表?成功讀取的變量個數。 如果沒有讀取任何項,或者匹配失敗,則返回 0 。如果在成功讀取任何數據之前,發?了讀取錯誤或 者遇到讀取到?件結尾,則返回常量 EOF。
13.3 占位符的使用?
scanf() 常?的占位符如下,與 printf() 的占位符基本?致。
? %c :字符。
? %d :整數。
? %f : float 類型浮點數。
? %lf : double 類型浮點數。
? %Lf : long double 類型浮點數。 ? %s :字符串。
? %[] :在?括號中指定?組匹配的字符(?如 %[0-9] ),遇到不在集合之中的字符,匹配將會停?。
13.3.1 %c
1、上?所有占位符之中,除了 %c 以外,都會?動忽略起首的空白字符。 %c 不忽略空?字符,總是返回當前第?個字符,無論該字符是否為空格。
2、如果要強制跳過字符前的空?字符,可以寫成 scanf(" %c", &ch) ,即 %c 前加上?個空格,表?跳過零個或多個空?字符。?
13.3.2 %s
1、占位符 %s ,它其實不能簡單地等同于字符串。它的規則是,從當前第?個?空? 字符開始讀起,直到遇到空?字符(即空格、換?符、制表符等)為?。
2、 因為 %s 不會包含空?字符,所以?法?來讀取多個單詞,除?多個 %s ?起使?。這也意味著, scanf( ) 不適合讀取可能包含空格的字符串,?如書名或歌曲名。另外, scanf( ) 遇到 %s 占位符,會在字符串變量末尾存儲?個空字符 \0 。?
3、 scanf() 將字符串讀?字符數組時,不會檢測字符串是否超過了數組?度。所以,儲存字符串時, 很可能會超過數組的邊界,導致預想不到的結果。為了防?這種情況,使? %s 占位符時,應該指定讀?字符串的最??度,即寫成 %[m]s ,其中的 [m] 是?個整數,表?讀取字符串的最大場度,后?的字符將被丟棄。
int main()
{char name[11];scanf("%10s", name);return 0;
}
上面實例中, name 是?個?度為11的字符數組, scanf() 的占位符 %10s 表?最多讀取??輸? 的10個字符,后?的字符將被丟棄,這樣就不會有數組溢出的?險了。