當前位置:網站首頁>C語言學習

C語言學習

2022-07-23 04:11:32Programmer_Xuyih

C語言簡介

BCPL -> new B -> C語言 -> UNIX -> Minix -> Linux -> gcc
C語言誕生於1970-1973年,在肯·湯普遜丹尼斯·裏奇的編寫下完成,歸屬於美國貝爾實驗室
C語言之父:丹尼斯·裏奇(也有稱 肯·湯普遜丹尼斯·裏奇同為C語言之父)

C語言優點:

1.C語言專門用於編寫操作系統而發明的編程語言,所以天生適合硬件編程
2.以運行速度快而著稱,
3.非常適合實現數據結構和算法

C語言缺點:

1.由於出現的時間過早,有很多缺陷,也存在著很多的陷阱
我們的前輩給總結了一些避免陷阱的經驗教訓   
(《C陷阱與缺陷》《C和指針》《C專家編程》)-> (C語言三劍客)
2.C語言的語法很自由,但是也意味著危險

自由源於自律

C語法標准

C89語法標准		默認是gcc編譯器的語法標准
C99語法標准		可以認為是對C語言的擴展和增强
    		Ubuntu 16.04 默認C99  
    		-std=gnu99  指定為C99語法標准
C11語法標准		全新的昇級

一、第一個C語言程序

1、vim xxx.c    創建.c源文件
2、編寫代碼,並保存退出
3、gcc xxx.c    編譯.c源文件,成功會得到a.out可執行文件
4、./a.out  運行可執行文件
    注意:可以合並3、4步驟
        gcc xxx.c && ./a.out

#include <stdio.h>
程序員所編寫的代碼不是標准C代碼,需要一段程序把它翻譯成標准C代碼,負責翻譯的程序叫做預處理器翻譯的過程叫做預處理需要被翻譯的代碼叫做預處理指令以#開頭的代碼叫做預處理指令
#include 功能是導入頭文件
#include <xxx.h>
<> 從系統指定路徑查找頭文件並導入
#include "xxx.h"
"" 先從當前的工作路徑查找頭文件,如果找不到再從系統指定路徑查找並導入
stdio.h
頭文件:以.h結尾,裏面存放的是輔助性的代碼,絕大數都是函數的說明

int main()
{
    printf("Hello World!\n");   
    return 0;
}

main函數:入口函數
C語言以函數為單比特來管理代碼,一個函數就是一段具有某一項功能的代碼段
main函數是程序的執行入口,必須有且只能有一個
int 是一種數據類型,它錶示main函數的執行結果是一個整數
return 功能有兩個:

1、結束函數的執行
2、返回一個結果給函數的調用者

main函數的調用者是操作系統,它的返回值是給了操作系統的,它的值能反映出程序是如何結束的,一般有三類:

正數    出現异常    (別人的錯誤)
0       一切正常
負數    出現錯誤    (自己的錯誤)

printf/scanf 是標准庫中的函數,負責輸出數據、輸入數據
printf("想要輸入的內容");

轉義字符:

鍵盤上一些無法直接打印顯示的符,用一些特殊的字符組合來錶示,這種特殊的字符組合成為轉義字符,\n 就是其中之一

\r  	回到行首
\t  	制錶符,相當於Tab,用於輸出格式對齊
\b  	退格鍵
\a  	鈴響
\\  	錶示一個\
%%  	錶示一個%

C語言中以分號作為一行代碼的結束,使用大括號{}劃分區域

二、編譯器

負責把人能看得懂的記錄著代碼的文件,翻譯成計算機能看得懂的二進制文件,由預處理器編譯器鏈接器組成
gcc是由GNU社區為了編譯Linux內核代碼而開發的一款免費的編譯器
gcc常用的編譯參數:

-E          只顯示預處理的結果到終端
-std=gun99  設置C99語法標准
-c          只編譯不鏈接
-o          指定編譯結果的名字 -oname / -o name
-S     		生成匯編代碼(機器語言)
-I          指定頭文件的加載路徑    -I 加載路徑     -I優先級最高
-Wall       盡可能多地產生警告
-Werror     把警告當錯誤處理
-l          指定要加載的代碼庫  -lm 使用數學庫

三、C代碼變成可執行文件的詳細過程

1、預處理   把源文件翻譯成預處理文件
    gcc -E code.c           顯示預處理結果到終端
    gcc -E code.c -o code.i 生成以.i結尾的預處理文件
2、編譯     把預處理的文件翻譯成匯編文件
    gcc -S code.i           生成以.s結尾的匯編文件
3、匯編     把匯編文件翻譯成二進制的目標文件
    gcc -c code.s           生成以.o結尾的目標文件
4、鏈接     把若幹個目標文件合並成一個可執行文件
    gcc a.o b.o c.o ...     默認生成a.out的可執行文件              

四、C語言的文件類型

.c      源文件
.h      頭文件  
.h.gch  頭文件的編譯結果文件,它會被優先使用
.i      預處理文件
.s      匯編文件
.o      目標文件
.a      靜態庫文件
.so     共享庫文件

五、存儲空間的單比特

Bit     比特(最小)  存儲一個二進制比特,只能存儲0或者1,計算機中存儲數據的最小單比特
Byte    字節        存儲八個二進制比特,計算機存儲器描述存儲容量的基本單比特
KB      1024字節    
MB      1024KB
GB      1024MB
TB      1024GB
PB      1024TB

六、數據類型

為什麼要對數據進行分類?

1、現實生活中的數據本身就自帶類別屬性
2、對數據進行分類可以節約存儲空間、提高運行速度

C語言中數據分類為兩大類:自建(程序員自己設計的類型:結構、聯合、類)和內建(C語言自帶的類型)
==注意:==運算符 sizeof 可以計算類型、變量的字節數

整型:

signed      有符號  
     11010111    最高比特錶示符號比特    0為正,1為負
     signed char             1個字節                                                 -128~127
     signed short            2個字節                                                 -32768~32767
     signed int              4個字節                                                 ±20億
     signed long             4/8個字節   操作系統32比特為4個字節,操作系統64比特為8個字節   ±20億/±9開頭的19比特整數
     signed long long        8個字節                                                 ±9開頭的19比特整數
unsigned    無符號  從0開始,最小是0
     11010101    最高比特是數據比特
      unsigned char           1個字節                                                 0~255
      unsigned short          2個字節                                                 0~65535
      unsigned int            4個字節                                                 0~40億
      unsigned long           4/8個字節   操作系統32比特為4個字節,操作系統64比特為8個字節    0~40億/0~1開頭的20比特整數
      unsigned long long      8個字節                                                 0~1開頭的20比特整數
注意:signed不加就代錶了加
由於定義無符號整型時比較麻煩,C標准庫把這些類型重定義成一些新的簡單的類型名:
                需要導入頭文件<stdint.h>
            uint8_t uint16_t uint32_t uint64_t  無符號整型
            int8_t  int16_t  int32_t  int64_t   有符號整型

浮點型: 有小數部分的類型

float       單精度浮點型    4個字節
double      雙精度浮點型    8個字節
long double                12個字節/16個字節
注意:小數點後六比特有效
注意:采用一定的算法對真實的浮點型數據到二進制數據進行轉換,這個過程比存儲、讀取整型要慢得多,編程時盡量使用整型數據

判斷double是否與0相等?

double num
if(num < 0.000001 && num > -0.000001)

模擬型:

字符型:char
字符就是符號或圖案,在內存中存儲的依然是整數,需要顯示出字符時,會根據ASCII錶中對應的關系顯示出對應的字符或圖案
'\0'    0       特殊字符 空字符
'0'     48      (單引號中只能放一個字符)
'A'     65
'a'     97

布爾型:bool

先有的C語言後有的bool,所以C語言中不可能有真正的布爾類型,在頭文件stdbool.h中對布爾類型進行了模擬
添加頭文件<stdbool.h>後才可使用 bool true false

類型轉換

只有相同類型的數據才能運算,如果類型不相同的數據需要先轉換後才能再進行計算。

自動類型轉換:

轉換規則:以不丟失數據為基礎,可以適當地犧牲一些空間

1、字節少的向字節多的轉   (優先級最高)
2、有符號的向無符號的轉
3、整型會向浮點型轉
注意:char short 如果與不同類型的數據運算時,會先提昇為int類型後參與運算

强制類型轉換:

(新類型名)數據;
這種方式有可能會丟失數據,慎重使用

七、變量與常量

什麼是變量:程序運行期間數值可以發生變化的叫做變量,相當於一個存儲數據的盒子
定義:類型名 變量名;
int num;
取名規則:

1、由字母、數字、下劃線_組成
2、不能以數字開頭
3、不能與C語言32個關鍵字重名(要求能默寫)
4、見名知意 (功能、類型、作用範圍...)
        int sum_s_i;

使用:

賦值:       變量名 = 10;
            num = 10;
參與運算:   2+(變量名*10);
           2+(num*10);   
注意:C語言中變量的初始值是隨機的,為了安全起見,一般在定義時初始化為0

變量的輸出與輸入:

int printf(const char *format, ...);
功能:輸出數據

format:"雙引號包含的提示信息+占比特符"
...(可變長參數):變量名列錶
返回值:輸出字符個數

類型占比特符:C語言中通過類型占比特符來傳遞變量的類型
signed      char  short  int    long    long long
            %hhd  %hd    %d     %ld     %lld
unsigned    char  short  int    long    long long
			%hhu  %hu    %u     %lu     %llu
float       %f
double      %lf
long double %LF
字符型 char  %c

`int scanf(const char *format, …);``
功能:輸入數據

format:"雙引號包含的占比特符"
...:    變量地址的列錶
返回值: 成功輸入的變量的個數

注意:scanf需要提供變量的地址    
        &變量名 == 變量地址

什麼是常量:程序運行期間數值不能改變的叫做常量

100     默認int類型
100l    long
100ll   long long
100u    unsigned int
100lu   unsigned long
100llu  unsigned long long
3.14    默認double
3.14f   float
3.14l   long double

八、格式化輸入輸出

%nd     顯示n個字符寬度,不够則在左邊補充空格,右對齊
%-nd    顯示n個字符寬度,不够則在右邊補充空格,左對齊
%0nd    顯示n個字符寬度,不够則在左邊補充0,右對齊
%n.mf   顯示n個字符寬度(小數點也算一比特),不够則在左邊補充空格,m錶示小數點後幾比特(多餘則四舍五入,不够補0),右對齊
%g      不顯示小數點後多餘的0

九、運算符

自變運算符: ++/--   使變量的值自動加1或者减1
    前自變: ++num/--num 立即生效
    後自變: num++/num-- 下一行語句才有效
注意:不要在一行代碼中多次使用自變運算符

算術運算符: + - * / %
    整數/整數   結果還是整數,沒有小數點,只保留整數部分
      10/3    ->  3
      10%3    ->  1
	 / % 除數不能為0,否則就會浮點數例外、(核心已轉儲),這是個運行報錯,一旦產生則程序立即停止   ->  計算機中只有加法器,無法完成該操作

關系運算符:  >  <  >=  <=  ==  !=
    比較結果 0(不成立)或1(成立),比較結果可以繼續參與後續的運算
    int n = -100;
    if(10 < n <100)   從左開始運算  ->  結果永遠為真,與數學的運算規則不同
注意: == 建議常量放左邊

邏輯運算符:   &&  ||  !
    先把運算對象轉換成邏輯值,0轉換為假,非0轉換為真
    A && B  一假即假
    A || B  一真即真
    !A      求反
    && ||   短路特性:
當左邊部分的結果值可以確定整個錶達式的結果時,右邊部分就不執行計算

三目運算符:運算對象有三個部分
    A ? B : C   判斷A的值如果為真,則執行B的內容,否則執行C

賦值運算符:
    a = 10;
    a += 10;    a=a+10;
    a -= 10;
    a *= 10;
    a /= 10;
    a %= 10;

比特運算符:   &   |   ~   ^   <<  >>

十、分支語句

if(錶達式)  //單分支
{
    //錶達式為真(非0),則執行此處代碼
}

if(錶達式)  //雙分支
{
    //錶達式為真(非0),則執行此處代碼
}
else
{
    //錶達式為假(0),則執行此處代碼
}

if(錶達式1)  //多分支
{
    //錶達式1為真(非0),則執行此處代碼
}
else if(錶達式2)
{
    //錶達式2為真(非0),則執行此處代碼
}
else if(錶達式3)
{
    //錶達式3為真(非0),則執行此處代碼
}
else
{
    //如果以上所有錶達式都為假,則最後執行此處代碼
}



switch開關分支語句
switch(n) // n可以是數值、錶達式,錶達式的運算結果必須是整數
{
    case val:   // 如果val == n,則打開執行開關
                // val必須是常量
        ...
        break;  // 關閉執行開關,結束switch
        // 如果每個case後都加break,形成了分支結構
        // switch中不能使用continue配合
        // case a ... b:可以錶示[a,b],但是只有GNU編譯器才支持該語法,不建議使用
    case val1:
        ...
    default:
        // 如果所有的case都沒有打開,則最後打開default,並且放在任何比特置都可以最後打開
}

十一、for循環語句:

循環就是一種讓代碼反複執行的一種方法,直到達到你想要的效果
for循環是一種非常靈活變化多樣且危險(相比其他循環)的循環

for一般使用一個變量來引導循環的執行,該變量叫做循環變量i    index
for([1];[2];[3])
{
    [4];
}
[1]、給循環變量賦初值,C99以上標准才可以在此處定義循環變量 -std=gnu99
[2]、判斷循環變量是否到達邊界,如果沒到達,進入循環
[4]、被反複執行的代碼,成為循環體
[3]、改變循環變量,防止出現死循環,一般對循環變量進行自加、自减
執行順序:[1][2][4][3][2][4][3]...

大括號問題:
    1、建議上下對齊
    2、如果循環體中只有一行代碼,大括號可以省略
        但是不利於擴展,一般的商業代碼都要求大括號不能省略

for循環各種寫法:

1.
  for(;;)
  {
      //  死循環
  }


2.
  int i=0;
  for(; i<10; i++)
  {

  }


3.
  for(int i=0; ; i++)
  {
      if(i >= 10)
      {
          break;
      }
  }

4.
  for(int i=0; i<10; )
  {
      ...
      i++;
  }

十二、while循環語句

while(錶達式)
{
    //  循環體
}

當錶達式為真時執行循環體,執行完後重新判斷錶達式,以此類推,直到錶達式為假,結束循環
while相當於for的精簡版本    for(;錶達式;)

for循環專門負責解决明確知道循環次數的問題
while循環專門負責解决不確定循環次數的問題

十三、do-while 循環語句

do{
    //  循環體
}while(錶達式); 	//錶達式為真循環繼續,為假結束循環
先執行循環體,再判斷循環條件,該循環體至少執行一次   

適合先幹活、後檢查的特殊情况,例如輸入密碼、文件內容判斷

十四、循環嵌套

循環語句中包含了循環語句
外層循環執行一次,內層循環執行n次

版權聲明
本文為[Programmer_Xuyih]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/204/202207221749232035.html

隨機推薦