萬字整理,C語言最全入門筆記!

2021-03-02 人人都是極客

【推薦閱讀】

C語言指針-從底層原理到花式技巧,用圖文和代碼幫你講解透徹

嵌入式工程師常用的宏定義

C語言實現面向對象的原理

C語言中的結構體和聯合體

C語言一經出現就以其功能豐富、表達能力強、靈活方便、應用面廣等特點迅速在全世界普及和推廣。C語言不但執行效率高而且可移植性好,可以用來開發應用軟體、驅動、作業系統等。C語言也是其它眾多高級語言的鼻祖語言,所以說學習C語言是進入編程世界的必修課。

hello,world

#include<stdio.h> 
int main()
{
    /*在雙引號中間輸入Hello World*/ 
    printf("Hello World");
    return 0; 
}

註:在最新的C標準中,main函數前的類型為int而不是void

c語言的具體結構

簡單來說,一個C程序就是由若干頭文件和函數組成。

#include <stdio.h>就是一條預處理命令, 它的作用是通知C語言編譯系統在對C程序進行正式編譯之前需做一些預處理工作。

必不可少之主函數

一個C程序有且只有一個主函數,即main函數。

C程序就是執行主函數裡的代碼,也可以說這個主函數就是C語言中的唯一入口

main前面的int就是主函數的類型.

printf()是格式輸出函數,這裡就記住它的功能就是在屏幕上輸出指定的信息

return是函數的返回值,根據函數類型的不同,返回的值也是不同的。

\n是轉義字符中的換行符。(注意:C程序一定是從主函數開始執行的)

良好習慣之規範

一個說明或一個語句佔一行,例如:包含頭文件、一個可執行語句結束都需要換行

函數體內的語句要有明顯縮進通常以按一下Tab鍵為一個縮進

括號要成對寫,如果需要刪除的話也要成對刪除

當一句可執行語句結束的時候末尾需要有分號

代碼中所有符號均為英文半角符號

程序解釋——注釋

注釋是寫給程式設計師看的,不是寫給電腦看的。

C語言注釋方法有兩種:

多行注釋: /* 注釋內容 */

單行注釋: //注釋一行

有名有姓的C(標識符)

C語言規定,標識符可以是字母(A~Z,a~z)、數字(0~9)、下劃線_組成的字符串,並且第一個字符必須是字母或下劃線。在使用標識符時還有注意以下幾點:

標識符的長度最好不要超過8位,因為在某些版本的C中規定標識符前8位有效,當兩個標識符前8位相同時,則被認為是同一個標識符。

標識符是嚴格區分大小寫的。例如Imooc和imooc 是兩個不同的標識符。

標識符最好選擇有意義的英文單詞組成做到"見名知意",不要使用中文。

標識符不能是C語言的關鍵字。想了解更多C語言關鍵字的知識。

變量及賦值

變量就是可以變化的量,而每個變量都會有一個名字(標識符)。變量佔據內存中一定的存儲單元。使用變量之前必須先定義變量,要區分變量名變量值是兩個不同的概念。

變量定義的一般形式為:數據類型 變量名;

多個類型相同的變量:數據類型 變量名, 變量名, 變量名...;

注意:在定義中不允許連續賦值,如int a=b=c=5;是不合法的。

變量的賦值分為兩種方式:

先聲明再賦值

聲明的同時賦值

基本數據類型

C語言中,數據類型可分為:

基本數據類型

構造數據類型

指針類型

空類型四大類

最常用的整型, 實型與字符型(char,int,float,double):

整型數據是指不帶小數的數字(int,short int,long int, unsigned int, unsigned short int,unsigned long int):

註:

int short int long int是根據編譯環境的不同,所取範圍不同。

而其中short int和long int至少是表中所寫範圍, 但是int在表中是以16位編譯環境寫的取值範圍。

另外 c語言int的取值範圍在於他佔用的字節數 ,不同的編譯器,規定是不一樣。

ANSI標準定義int是佔2個字節,TC是按ANSI標準的,它的int是佔2個字節的。但是在VC裡,一個int是佔4個字節的。

浮點數據是指帶小數的數字。

生活中有很多信息適合使用浮點型數據來表示,比如:人的體重(單位:公斤)、商品價格、圓周率等等。

因為精度的不同又分為3種(float,double,long double):

註:C語言中不存在字符串變量,字符串只能存在字符數組中,這個後面會講。

格式化輸出語句

格式化輸出語句,也可以說是佔位輸出,是將各種類型的數據按照格式化後的類型及指定的位置從計算機上顯示。

其格式為:printf("輸出格式符",輸出項);

當輸出語句中包含普通字符時,可以採用一下格式:

printf("普通字符輸出格式符", 輸出項);

注意:格式符個數要與變量、常量或者表達式的個數一一對應

不可改變的常量

在程序執行過程中,值不發生改變的量稱為常量

mtianyan: C語言的常量可以分為直接常量和符號常量。

在C語言中,可以用一個標識符來表示一個常量,稱之為符號常量。符號常量在使用之前必須先定義,其一般形式為:

#define 標識符 常量值

#include <stdio.h>
#define POCKETMONEY 10    //定義常量及常量值
int main()
{
    // POCKETMONEY = 12;  //小明私自增加零花錢對嗎?
    printf("小明今天又得到%d元零花錢\n", POCKETMONEY);
    return 0;  
}

符號常量不可以被改變。

自動類型轉換

數據類型存在自動轉換的情況.
自動轉換發生在不同數據類型運算時,在編譯的時候自動完成

char類型數據轉換為int類型數據遵循ASCII碼中的對應值.

注:

字節小的可以向字節大的自動轉換,但字節大的不能向字節小的自動轉換

char可以轉換為int,int可以轉換為double,char可以轉換為double。但是不可以反向。

強制類型轉換

強制類型轉換是通過定義類型轉換運算來實現的。其一般形式為:

(數據類型) (表達式)

其作用是把表達式的運算結果強制轉換成類型說明符所表示的類型

在使用強制轉換時應注意以下問題:

數據類型和表達式都必須加括號, 如把(int)(x/2+y)寫成(int)x/2+y則成了把x轉換成int型之後再除2再與y相加了。

轉換後不會改變原數據的類型及變量值,只在本次運算中臨時性轉換

強制轉換後的運算結果不遵循四捨五入原則。

運算符號

C語言中運算符:

※ 算術運算符
※ 賦值運算符
※ 關係運算符
※ 邏輯運算符
※ 三目運算符

算術運算符

c語言基本運算符:

除法運算中注意

如果相除的兩個數都是整數的話,則結果也為整數,小數部分省略,如8/3 = 2;

而兩數中有一個為小數,結果則為小數,如:9.0/2 = 4.500000。

mtianyan: 取餘運算中注意

該運算只適合用兩個整數進行取餘運算,如:10%3 = 1;

mtianyan: notes: 而10.0%3則是錯誤的;運算後的符號取決於被模數的符號,如(-10)%3 = -1;而10%(-3) = 1;

mtianyan: %%表示這裡就是一個%符.

註:C語言中沒有乘方這個運算符,也不能用×, ÷等算術符號。

自增與自減運算符

自增運算符為++,其功能是使變量的值自增1

自減運算符為--,其功能是使變量值自減1。

它們經常使用在循環中。自增自減運算符有以下幾種形式:

賦值運算符

C語言中賦值運算符分為簡單賦值運算符複合賦值運算符

簡單賦值運算符=號了,下面講一下複合賦值運算符:

複合賦值運算符就是在簡單賦值符=之前加上其它運算符構成.

例如+=、-=、*=、/=、%=

分析:定義整型變量a並賦值為3,a += 5;這個算式就等價於a = a+5; 將變量a和5相加之後再賦值給a

注意:複合運算符中運算符和等號之間是不存在空格的。

關係運算符

C語言中的關係運算符:

關係表達式的值是真和假,在C程序用整數1和0表示。

注意:>=, <=, ==, !=這種符號之間不能存在空格

邏輯運算符

C語言中的邏輯運算符:

邏輯運算的值也是有兩種分別為真和假,C語言中用整型的1和0來表示。其求值規則如下:

參與運算的兩個變量都為真時,結果才為真,否則為假。例如:5>=5 && 7>5 ,運算結果為真;

參與運算的兩個變量只要有一個為真,結果就為真。兩個量都為假時,結果為假。例如:5>=5||5>8,運算結果為真;

參與運算的變量為真時,結果為假;參與運算量為假時,結果為真。例如:!(5>8),運算結果為真。

三目運算符

C語言中的三目運算符:?:,其格式為:

表達式1 ? 表達式2 : 表達式3;

執行過程是:

先判斷表達式1的值是否為真,如果是真的話執行表達式2;如果是假的話執行表達式3。

#include <stdio.h>
int main()
{
    //定義小編兜裡的錢
    double money =12.0      ; 
    //定義打車回家的費用
    double cost =11.5       ;  
    printf("小編能不能打車回家呢:"); 
    //輸出y小編就打車回家了,輸出n小編就不能打車回家
    printf("%c\n",money>=cost?'y':'n'                        );
    return 0;
}

運算符大比拼之優先級比較

各種運算符號的順序:

優先級別為1的優先級最高,優先級別為10的優先級別最低。

分支結構之簡單if語句

C語言中的分支結構語句中的if條件語句。

簡單if語句的基本結構如下:

if(表達式)
{
執行代碼塊;
}

其語義是:如果表達式的值為真,則執行其後的語句,否則不執行該語句。

注意:if()後面沒有分號,直接寫{}

分支結構之簡單if-else語句

簡單的if-else語句的基本結構:

語義是: 如果表達式的值為真,則執行代碼塊1,否則執行代碼塊2。

注意:

if()後面沒有分號,直接寫{},else後面也沒有分號,直接寫{}

分支結構之多重if-else語句

C語言中多重if-else語句,其結構如下:

語義是:依次判斷表達式的值,當出現某個值為真時,則執行對應代碼塊,否則執行代碼塊n。

注意:當某一條件為真的時候,則不會向下執行該分支結構的其他語句。

分支結構之嵌套if-else語句

C語言中嵌套if-else語句。嵌套if-else語句的意思,就是在if-else語句中,再寫if-else語句。其一般形式為:

循環結構之while循環

反覆不停的執行某個動作就是江湖人稱的循環 。

C語言中有三種循環結構,先看一下C語言while循環的結構

其中表達式表示循環條件,執行代碼塊為循環體

while語句的語義是:計算表達式的值,當值為真(非0)時, 執行循環體代碼塊。

while語句中的表達式一般是關係表達或邏輯表達式,當表達式的值為假時不執行循環體,反之則循環體一直執行。

一定要記著在循環體中改變循環變量的值,否則會出現死循環(無休止的執行)。

循環體如果包括有一個以上的語句,則必須用{}括起來,組成複合語句。

循環結構之do-while循環

C語言中的do-while循環,一般形式如下:

do-while循環語句的語義是:

它先執行循環中的執行代碼塊,然後再判斷while中表達式是否為真,如果為真則繼續循環;如果為假,則終止循環。因此,do-while循環至少要執行一次循環語句

注意:mtianyan: 使用do-while結構語句時,while括號後必須有分號。

循環結構之for循環(一)

c語言中for循環一般形式:

它的執行過程如下:

執行表達式1,對循環變量做初始化;

判斷表達式2,若其值為真(非0),則執行for循環體中執行代碼塊,然後向下執行;若其值為假(0),則結束循環;

執行表達式3,(i++)等對於循環變量進行操作的語句;

執行for循環中執行代碼塊後執行第二步;第一步初始化只會執行一次。

循環結束,程序繼續向下執行。

注意:for循環中的兩個分號一定要寫

循環結構之for循環(二)

在for循環中:

表達式1是一個或多個賦值語句,它用來控制變量的初始值

表達式2是一個關係表達式,它決定什麼時候退出循環;

表達式3是循環變量的步進值,定義控制循環變量每循環一次後按什麼方式變化。

這三部分之間用分號 ; 分開。

使用for語句應該注意

for循環中的「表達式1、2、3」均可不寫為空,但兩個分號(;;)不能預設。

省略「表達式1(循環變量賦初值)」,表示不對循環變量賦初始值。

省略「表達式2(循環條件)」,不做其它處理,循環一直執行(死循環)。

省略「表達式3(循環變量增減量)」,不做其他處理,循環一直執行(死循環)。

表達式1可以是設置循環變量的初值的賦值表達式,也可以是其他表達式

表達式1和表達式3可以是一個簡單表達式也可以是多個表達式以逗號分割。

表達式2一般是關係表達式邏輯表達式,但也可是數值表達式或字符表達式,只要其值非零,就執行循環體。

各表達式中的變量一定要在for循環之前定義

怎麼獲得一個數的百位,十位和個位循環結構之三種循環比較

while, do-while和for三種循環在具體的使用場合上是有區別的,如下:

知道循環次數的情況下更適合使用for循環;

在不知道循環次數的情況下適合使用while或者do-while循環:

如果有可能一次都不循環應考慮使用while循環

如果至少循環一次應考慮使用do-while循環。

但是從本質上講,while,do-while和for循環之間是可以相互轉換的。

循環結構之多重循環

多重循環就是在循環結構的循環體中又出現循環結構。

在實際開發中一般最多用到三層重循環

因為循環層數越多,運行時間越長,程序越複雜,所以一般用2-3層多重循環就可以了。另外不同循環之間也是可以嵌套的。

多重循環在執行的過程中,外層循環為父循環,內層循環為子循環

父循環一次,子循環需要全部執行完,直到跳出循環。父循環再進入下一次,子循環繼續執行...

mtianyan: 列印三角形星星堆

#include <stdio.h>
int main()
{
    int i, j, k;
    for(i=1; i<5; i++)
    {
        /* 觀察每行的空格數量,補全循環條件 */
        for(j=i; j<5; j++)  
        {
            printf(" ");    //輸出空格
        }
        /* 觀察每行*號的數量,補全循環條件 */
        for( k=0;k<2*i-1;k++) 
        {
            printf("*");   //每行輸出的*號
        }
        printf("\n");     //每次循環換行
    }
    return 0;
}

使用for循環列印9×9乘法表

#include <stdio.h>
int main() 

    // 定義相乘數字i,j以及結果result
    int i, j, result;
     for(i=9;i>=1;i--)
     {
        for(j=1;j<=i;j++)
        {
            printf("%d*%d=%d ",i,j,result=i*j);
        }
        printf("\n");
     }
    return 0;
}

結束語句之break語句

那麼循環5次的時候,需要中斷不繼續訓練。在C語言中,可以使用break語句進行該操作.

使用break語句時注意以下幾點:

在沒有循環結構的情況下,break不能用在單獨的if-else語句中。

在多層循環中,一個break語句只跳出當前循環。

結束語句之continue語句

那麼循環5次的時候,需要中斷後繼續訓練。在C語言中,可以使用continue語句進行該操作

continue語句的作用是結束本次循環開始執行下一次循環。

break語句與continue語句的區別是:

break是跳出當前整個循環,continue是結束本次循環開始下一次循環。

分支結構之switch語句

switch語句結構如下:

mtianyan: switch語句時還應注意以下幾點:

在case後的各常量表達式的值不能相同,否則會出現錯誤。

在case子句後如果沒有break;會一直往後執行一直到遇到break;才會跳出switch語句。

switch後面的表達式語句只能是整型或者字符類型

在case後,允許有多個語句,可以不用{}括起來。

各case和default子句的先後順序可以變動,而不會影響程序執行結果。

default子句可以省略不用。

mtianyan: switch與if語句的應用(計算是該年的第幾天)

#include <stdio.h>

int main() 



    /* 定義需要計算的日期 */

    int date = 0;

    int year = 2008;

    int month = 8;

    int day = 8;

    switch(month)

    {

        case 12:date+=30;

        case 11:date+=31;

        case 10:date+=30;

        case 9:date+=31;

        case 8:date+=31;

        case 7:date+=30;

        case 6:date+=31;

        case 5:date+=30;

        case 4:date+=31;

        case 3:

        if((year%4==0&&year%100!=0)||year%400==0)

        {

            date+=29;

        }

        else

        {

            date+=28;

        }
        case 2:

        date+=31;

        case 1:

        date+=day;

        printf("%d年%d月%d日是該年的第%d天",year,month,day,date);

        break;

        default:

        printf("error");

        break;

    }

    return 0;

}

正確: continue只能用在循環體內

臭名遠揚之goto語句

C語言中也有這樣的語句,就是goto語句,goto語句是一種無條件分支語句.

goto 語句的使用格式為:

goto 語句標號;

自創函數

C語言提供了大量的庫函數: 比如stdio.h提供輸出函數

自定義函數的一般形式:

注意:

[] 包含的內容可以省略,數據類型說明省略,默認是 int 類型函數; 參數省略表示該函數是無參函數,參數不省略表示該函數是有參函數;

函數名稱遵循標識符命名規範;

mtianyan: 自定義函數儘量放在 main 函數之前,如果要放在main函數後面的話, 需要在main函數之前先聲明自定義函數,聲明格式為:

[數據類型說明] 函數名稱([參數]);

函數調用

我們需要用到自定義的函數的時候,就得調用它,那麼在調用的時候就稱之為函數調用

在C語言中,函數調用的一般形式為:

函數名([參數]);

注意:

對無參函數調用的時候可以將[]包含的省略。

[]中可以是常數,變量或其它構造類型數據及表達式,多個參數之間用逗號分隔。

有參與無參

在函數中不需要函數參數的稱之為無參函數,在函數中需要函數參數的稱之為有參函數。

有參和無參函數的一般形式如下:

有參函數和無參函數的唯一區別在於:函數 () 中多了一個參數列表。

mtianyan: 形參與實參

函數的參數分為形參實參兩種。

就類似小明,說了的話而不實際行動;

就如小剛能實際行動起來。

函數的形參和實參具有以下特點:

函數調用結束返回主調函數後則不能再使用該形參變量。

無論實參是何種類型的量,在進行函數調用時,它們都必須具有確定的值,以便把這些值傳送給形參。因此應預先用賦值等辦法使實參獲得確定值。

函數的返回值

函數的返回值是指函數被調用之後,執行函數體中的程序段所取得的並返回給主調函數的值。

函數的返回值要注意以下幾點:

return語句的一般形式為:

return 表達式 或者為:return (表達式);

notes: 如果兩者不一致,則以函數返回類型為準,自動進行類型轉換。

注意:

void 函數中可以有執行代碼塊,但是不能有返回值.

mtianyan: void函數中如果有return語句,該語句只能起到結束函數運行的功能。其格式為: return;

遞歸函數(一)

遞歸就是一個函數在它的函數體內調用它自身。

執行遞歸函數將反覆調用其自身,每調用一次就進入新的一層。

注意遞歸函數必須有結束條件

遞歸函數(二)

5的階乘這個例子進行一下剖析,看一看他的運算過程:

程序在計算5的階乘的時候,先執行遞推,當n=1或者n=0的時候返回1,再回推將計算並返回。由此可以看出遞歸函數必須有結束條件。

遞歸函數特點:

每一級函數調用時都有自己的變量,但是函數代碼並不會得到複製,如計算5的階乘時每遞推一次變量都不同;

每次調用都會有一次返回,如計算5的階乘時每遞推一次都返回進行下一次;

遞歸函數中,位於遞歸調用前的語句和各級被調用函數具有相同的執行順序;

遞歸函數中,位於遞歸調用後的語句的執行順序和各個被調用函數的順序相反;

遞歸函數中必須有終止語句。

一句話總結遞歸:自我調用且有完成狀態

任務
猴子第一天摘下N個桃子,當時就吃了一半,還不過癮,就又多吃了一個。第二天又將剩下的桃子吃掉一半,又多吃了一個。以後每天都吃前一天剩下的一半零一個。到第10天在想吃的時候就剩一個桃子了,問第一天共摘下來多少個桃子?並反向列印每天所剩桃子數。

#include <stdio.h>
int getPeachNumber(int n)  
{
    int num;    
    if(n==10)
    {
       return 1;      
    } 
    else
    {
        num = (getPeachNumber(n+1)+1)*2;  
        printf("第%d天所剩桃子%d個\n", n, num); 
    }
    return num;
}
int main()
{
    int num = getPeachNumber(1);
    printf("猴子第一天摘了:%d個桃子。\n", num);
    return 0;
}

遞歸demo。

有5個人坐在一起,問第5個人多少歲?他說比第4個人大2歲。問第4個人歲數,他說比第3個人大2歲。問第3個人,又說比第2人大兩歲。問第2個人,說比第1個人大兩歲。最後 問第1個人,他說是10歲。請問第5個人多大?

程序分析:
利用遞歸的方法,遞歸分為回推和遞推兩個階段。要想知道第5個人歲數,需知道第4人的歲數,依次類推,推到第1人(10歲),再往回推。

#include <stdio.h> 
int dfs(int n) {
    return n == 1 ? 10 : dfs(n - 1) + 2;
}
int main() 
{

    printf("第5個人的年齡是%d歲", dfs(5)); 
    return 0;

局部與全局

C語言中的變量,按作用域範圍可分為兩種,即局部變量和全局變量。

變量存儲類別

mtianyan: C語言根據變量的生存周期來劃分,可以分為靜態存儲方式和動態存儲方式。

C語言中存儲類別又分為四類:

自動(auto)、

靜態(static)、

寄存器的(register)

外部的(extern)。

1、用關鍵字auto定義的變量為自動變量,auto可以省略,auto不寫則隱含定為「自動存儲類別」,屬於動態存儲方式。如:

2、用static修飾的為靜態變量,如果定義在函數內部的,稱之為靜態局部變量;如果定義在函數外部,稱之為靜態外部變量。如下為靜態局部變量:

注意:靜態局部變量屬於靜態存儲類別,在靜態存儲區內分配存儲單元,在程序整個運行期間都不釋放;靜態局部變量在編譯時賦初值,即只賦初值一次;如果在定義局部變量時不賦初值的話,則對靜態局部變量來說,編譯時自動賦初值0(對數值型變量)或空字符(對字符變量)。

3、為了提高效率,C語言允許將局部變量得值放在CPU中的寄存器中,這種變量叫「寄存器變量」,用關鍵字register作聲明。例如:

mtianyan: 注意:只有局部自動變量和形式參數可以作為寄存器變量;一個計算機系統中的寄存器數目有限,不能定義任意多個寄存器變量;局部靜態變量不能定義為寄存器變量。

4、用extern聲明的的變量是外部變量,外部變量的意義是某函數可以調用在該函數之後定義的變量。如:

內部函數與外部函數

在C語言中不能被其他源文件調用的函數稱謂內部函數 ,內部函數由static關鍵字來定義,因此又被稱謂靜態函數,形式為:
static [數據類型] 函數名([參數])

這裡的static是對函數的作用範圍的一個限定,限定該函數只能在其所處的源文件中使用,因此在不同文件中出現相同的函數名稱的內部函數是沒有問題的。

在C語言中能被其他源文件調用的函數稱謂外部函數 ,外部函數由extern關鍵字來定義,形式為:
extern [數據類型] 函數名([參數])

C語言規定,在沒有指定函數的作用範圍時,系統會默認認為是外部函數,因此當需要定義外部函數時extern也可以省略。

靜態變量只賦值一次

外部函數練習

hello.c

#include <stdio.h>
#include "test.c"   //引用test.c文件
extern void printLine()     //這裡定義的方法對嗎?
{
   printf("**************\n");   
}
int main()
{
    say();
    return 0;
}

test.c

#include <stdio.h>
void printLine();
static void say(){
printLine();
printf("I love imooc\n");
printf("good good study!\n");
printf("day day up!\n");
printLine();
}

對於hello.c來說,直接引入了test.c文件。那麼就可以調用testc中的static方法say()
而對於test.c並沒有引入,可以通過聲明來調用另一個源文件中暴露出來的方法。

綜合練習

北京市計程車打車計費規則如下:

每公裡單價計費2.3元

起步價13元(包含3公裡)

晚上23點(含)至次日凌晨5點(不含)打車,每公裡單價計費加收20%。

每次乘車加收1元錢的燃油附加稅。
小明每天上下班都要打車,公司和家的距離為12公裡,上午上班時間為9點,下午下班時間為6點。
請編寫一個小程序計算小明每天打車的總費用。

#include <stdio.h>

float taxifee(int clock,int miles)
{
    float money;
    if(miles<=3)
    {
        money=14;
        printf("費用為14\n");
    }
    else
    {
        if(clock>=23 || clock<5)
        {
            money=13+1+2.3*(miles-3)*1.2;
            printf("夜間車費為:%f\n",money);
        }
        else
        {
            money=13+1+2.3*(miles-3);
            printf("日間車費為:%f\n",money);
        }
    }

    return money;    
}
int main()
{
    printf("打的總費用:%.1f\n",taxifee(9,12)+taxifee(18,12));
    return 0;
}

數組初體驗

程序中也需要容器,只不過該容器有點特殊,它在程序中是一塊連續的,大小固定並且裡面的數據類型一致的內存空間,它還有個好聽的名字叫數組。可以將數組理解為大小固定,所放物品為同類的一個購物袋,在該購
物袋中的物品是按一定順序放置的。

我們來看一下如何聲明一個數組:

數據類型 數組名稱[長度];

數組只聲明也不行啊,看一下數組是如何初始化的。說到初始化,C語言中的數組初始化是有三種形式的,分別是:

數據類型 數組名稱[長度n] = {元素1,元素2…元素n};

數據類型 數組名稱[] = {元素1,元素2…元素n};

數據類型 數組名稱[長度n]; 數組名稱[0] = 元素1; 數組名稱[1] = 元素2; 數組名稱[n-1] = 元素n;

我們將數據放到數組中之後又如何獲取數組中的元素呢?

獲取數組元素時:數組名稱[元素所對應下標];

如:初始化一個數組 int arr[3] = {1,2,3}; 那麼arr[0]就是元素1。

注意:

數組的下標均以0開始

數組在初始化的時候,數組內元素的個數不能大於聲明的數組長度;

mtianyan: 如果採用第一種初始化方式,元素個數小於數組的長度時,多餘的數組元素初始化為0;

在聲明數組後沒有進行初始化的時候,靜態(static)和外部(extern)類型的數組元素初始化元素為0,自動(auto)類型的數組的元素初始化值不確定。

數組的遍歷

數組就可以採用循環的方式將每個元素遍歷出來,而不用人為的每次獲取指定某個位置上的元素,例如我們用for循環遍歷一個數組:

注意以下幾點:

最好避免出現數組越界訪問,循環變量最好不要超出數組的長度.

C語言的數組長度一經聲明,長度就是固定,無法改變,並且C語言並不提供計算數組長度的方法

由於C語言是沒有檢查數組長度改變或者數組越界的這個機制,可能會在編輯器中編譯並通過,但是結果就不能肯定了,因此還是不要越界或者改變數組的長度

c語言獲取數組長度

int length = sizeof(arr)/sizeof(arr[0]);

數組作為函數參數

數組可以由整個數組當作函數的參數,也可以由數組中的某個元素當作函數的參數:

整個數組當作函數參數,即把數組名稱傳入函數中,例如:

數組中的元素當作函數參數,即把數組中的參數傳入函數中,例如:

數組作為函數參數時注意以下事項:

數組名作為函數實參傳遞時,函數定義處作為接收參數的數組類型形參既可以指定長度也可以不指定長度。

數組元素作為函數實參傳遞時,數組元素類型必須與形參數據類型一致。

mtianyan: 數組的應用(一)[冒泡排序]

以升序排序為例冒泡排序的思想:相鄰元素兩兩比較,將較大的數字放在後面,直到將所有數字全部排序。就像小學排隊時按大小個排一樣,將一個同學拉出來和後面的比比,如果高就放後面,一直把隊伍排好。

#include <stdio.h>
int main()
{
    double arr[]={1.78, 1.77, 1.82, 1.79, 1.85, 1.75, 1.86, 1.77, 1.81, 1.80};
    int i,j;
    printf("\n************排隊前*************\n");
    for(i=0;i<10;i++)
    {
        if(i != 9)   
            printf("%1.2f, ", arr[i]);  //%1.2f表示小數點前一位,小數點後精確到兩位
        else
            printf("%1.2f", arr[i]);    //%1.2f表示小數點前一位,小數點後精確到兩位
    }
    for(i=8; i>=0; i--)
    {
        for(j=0;j<=i;j++)
        {
            if( arr[j]>arr[j+1])      //當前面的數比後面的數大時
            {
                double temp;    //定義臨時變量temp
                temp=arr[j];//將前面的數賦值給temp
                arr[j]=arr[j+1];             //前後之數顛倒位置
                arr[j+1]=temp;//將較大的數放在後面    
            }                 
        }                
    }
    printf("\n************排隊後*************\n");
    for(i=0;i<10;i++)
    {
        if(i != 9)   
            printf("%1.2f, ", arr[i]);  //%1.2f表示小數點前一位,小數點後精確到兩位     
        else
            printf("%1.2f", arr[i]);    //%1.2f表示小數點前一位,小數點後精確到兩位
    }
    return 0;    
}

數組的應用(二)[數組查找功能]

當我們購物之後,拎著購物袋回到家,會一一檢查購物袋中的物品看是否缺少或者都是想購之物。

那麼應用到程序中,可以使用數組查找功能,看看是否存在該數據,如果存在並返回該元素的下標。

#include <stdio.h>
int getIndex(int arr[5],int value)
{
    int i;
    int index;
    for(i=0;i<5;i++)
    {
       /* 請完善數組查詢功能 */
       if(arr[i]==value)
        {
            index=i;
            break;
        }  
       index=-1;
    }
    return index;
}

int main()
{
    int arr[5]={3,12,9,8,6};
    int value = 8;
    int index = getIndex(arr,value);      //這裡應該傳什麼參數呢?
    if(index!=-1)
    {
        printf("%d在數組中存在,下標為:%d\n",value,index);             
    }
    else
    {
        printf("%d在數組中不存在。\n",value);    
    }
    return 0;    
}

字符串與數組

C語言中,是沒有辦法直接定義字符串數據類型的,但是我們可以使用數組來定義我們所要的字符串。一般有以下兩種格式:

char 字符串名稱[長度] = "字符串值";

char 字符串名稱[長度] = {'字符1','字符2',...,'字符n','\0'};

注意:

[]中的長度是可以省略不寫的;

採用第2種方式的時候最後一個元素必須是'\0','\0'表示字符串的結束標誌;

採用第2種方式的時候在數組中不能寫中文。
在輸出字符串的時候要使用:printf(「%s」,字符數組名字);或者puts(字符數組名字);。

mtianyan:字符串函數

常用的字符串函數如下(strlen,strcmp,strcpy,strcat,atoi):

使用字符串函數注意以下事項:

strlen()獲取字符串的長度,在字符串長度中是不包括『\0』而且漢字和字母的長度是不一樣的。比如:

strcmp()在比較的時候會把字符串先轉換成ASCII碼再進行比較,返回的結果為0表示s1和s2的ASCII碼相等,返回結果為1表示s1比s2的ASCII碼大,返回結果為-1表示s1比s2的ASCII碼小,例如:

strcpy()拷貝之後會覆蓋原來字符串且不能對字符串常量進行拷貝,比如:

strcat在使用時s1與s2指的內存空間不能重疊,且s1要有足夠的空間來容納要複製的字符串,如:

多維數組

多維數組的定義格式是:
數據類型 數組名稱[常量表達式1][常量表達式2]...[常量表達式n];

定義了一個名稱為num,數據類型為int的二維數組。其中第一個[3]表示第一維下標的長度,就像購物時分類存放的購物;第二個[3]表示第二維下標的長度,就像每個購物袋中的元素。

多維數組的初始化與一維數組的初始化類似也是分兩種:

數據類型 數組名稱[常量表達式1][常量表達式2]...[常量表達式n] = {{值1,..,值n},{值1,..,值n},...,{值1,..,值n}};

數據類型 數組名稱[常量表達式1][常量表達式2]...[常量表達式n]; 數組名稱[下標1][下標2]...[下標n] = 值;

多維數組初始化要注意以下事項:

採用第一種始化時數組聲明必須指定列的維數。mtianyan: 因為系統會根據數組中元素的總個數來分配空間,當知道元素總個數以及列的維數後,會直接計算出行的維數;

採用第二種初始化時數組聲明必須同時指定行和列的維數。

二維數組定義的時候,可以不指定行的數量,但是必須指定列的數量

二維數組定義的時候,可以不指定行的數量,但是必須指定列的數量。

多維數組的遍歷

多維數組也是存在遍歷的,和一維數組遍歷一樣,也是需要用到循環。不一樣的就是多維數組需要採用嵌套循環。

注意:多維數組的每一維下標均不能越界。

綜合練習:

#include <stdio.h>
#define N 10
//列印分數 
void printScore(int score[])
{
    int i;
    printf("\n");
    for(i=0;i<N;i++)
    {
        printf("%d ",score[i]);               
    }
    printf("\n");     
}
//計算考試總分 
int getTotalScore(int score[])
{
    int sum = 0;
    int i;
    for(i=0;i<N;i++)
    {
        sum+=score[i];                
    } 
    return sum;
}
//計算平均分 
int getAvgScore(int score[])
{
    return getTotalScore(score)/N;   
}
//計算最高分 
int getMax(int score[])
{
    int max = -1;
    int i;
    for(i=0;i<N;i++)
    {
        if(score[i]>max)
        {
            max = score[i];              
        }                
    } 
    return max;
}
//計算最低分 
int getMin(int score[])
{
    int min =100;
    int i;
    for(i=0;i<N;i++)
    {
        if(score[i]< min)
        {
            min = score[i];              
        }                
    } 
    return min;
}
//分數降序排序 
void sort(int score[])
{
    int i,j;
    for(i=N-2;i>=0;i--)
    {
        for(j=0;j<=i;j++)
        {
            if(score[j]<score[j+1])
            {
                int temp;
                temp = score[j];
                score[j] = score[j+1]; 
                score[j+1]=temp;                  
            }                 
        }                   
    }
    printScore(score);     
}

int main()
{
    int score[N]={67,98,75,63,82,79,81,91,66,84};
    int sum,avg,max,min;
    sum = getTotalScore(score);
    avg = getAvgScore(score);
    max = getMax(score);
    min = getMin(score);
    printf("總分是:%d\n",sum);
    printf("平均分是:%d\n",avg);
    printf("最高分是:%d\n",max);
    printf("最低分是:%d\n",min);
    printf("成績排名----\n");
    sort(score);
    return 0;    
}

5T技術資源大放送!包括但不限於:C/C++,Arm, Linux,Android,人工智慧,單片機,樹莓派,等等。在公眾號內回復「peter」,即可免費獲取!!

 記得點擊分享在看,給我充點兒電吧

相關焦點

  • 「C語言從入門到入土」必備C語言基礎筆記整理
    一、C語言1、什麼是C語言?C語言是人寫機器看的一種語言。C語言是高級語言中的低級語言。C語言貼近硬體。C語言的入門學習比較簡單。彙編語言——>B語言——>C語言2、C語言的特性首先C語言就是你的女朋友。無論你讓它幹什麼,它絕對不會自己找到方法。
  • C語言學習資源整理
    (文中連結請點擊最下方閱讀原文打開)包括四個方面,依次是:C語言入門課程:主要針對入門新手做的課程整理,如果你有一定的C語言基礎,可以跳過這部分內容;(小白新手,推薦看)C語言實踐項目:整理了一些C語言實戰項目以及項目列表,可以找到很多項目開發點子
  • 深度學習全網最全學習資料匯總之入門篇
    因此,雷鋒網(公眾號:雷鋒網)將圍繞深度學習技術整理一個系列文章,全面覆蓋與其相關的各項知識點。本文針對如何入門深度學習這一話題,整理了若干參考資料,希望對廣大開發者有所裨益。需要提前說明的是,無論教程怎樣淺顯易懂,如果要深刻理解深度學習的技術原理,一些基礎的數學知識還是必不可少的,包括微積分、線性代數和概率論等。
  • 學習C語言必看的最經典書籍
    來源:互動出版網學習c語言必看的最經典書籍推薦一:《新概念51單片機C語言教程--入門
  • c語言從入門到精通幾個階段
    本文主要結合往期學員學習階段,因材施教整理的幾個階段學習路線知識點:1.初級教程初級c語言入門教程比較適合零基礎的小白,這個周期一般在22天,度過這個階段的小白,基本上已經擁有了編程思維,且能開發簡單的
  • C語言結構體(struct)最全的講解(萬字乾貨)
    (整理本文出於傳播相關技術知識,版權歸原作者所有。)在C語言中,可以定義結構體類型,將多個相關的變量包裝成為一個整體使用。在結構體中的變量,可以是相同、部分相同,或完全不同的數據類型。在C語言中,結構體不能包含函數。在面向對象的程序設計中,對象具有狀態(屬性)和行為,狀態保存在成員變量中,行為通過成員方法(函數)來實現。C語言中的結構體只能描述一個對象的狀態,不能描述一個對象的行為。
  • 門外漢入門級C語言學習筆記——從東拉西扯中硬核回歸
    筆記主要摘自於:華章科技 《手把手教你學C語言》1.2 實踐角度 比如語言運行速度的比較——機器語言越低級速度越快,高級語言中C最快,C++其次,最慢的是java和C#,當然,改進之處在於——他倆雖慢但任何機器都可運行,且結果一致。
  • c語言入門教程
    導讀:隨著微型計算機的日益普及,C語言成為世界上最流行、使用最廣泛的高級程序設計語言之一。下面我們就一起來了解一下C語言的世界是什麼樣子的吧。這本書被 C語言開發者們稱為"K&R",很多年來被當作 C語言的非正式的標準說明。人們稱這個版本的 C語言為"K&R C"。  c語言宣傳圖1970到80年代,C語言被廣泛應用,從大型主機到小型微機,也衍生了C語言的很多不同版本。
  • 學習c語言筆記——C庫函數printf()
    c語言中的printf是什麼來的?」。我答:「它是一個函數,主要用來輸出運算結果。」 ,下面就給大家介紹C庫函數printf()使用方法。下面我們通過一個調用c庫函數的c語言案例來說明printf()函數的使用方法,如c語言1。
  • 門外漢入門級C語言學習筆記第二課
    比如提一下普通的、能被調用的函數聲明應該是這個樣子的——以max函數為例int max(int x,int y)第三行{是函數體的大括號,表明是一個類裡面的,裡面內容屬於局部內容,只能再裡面使用,出來就用不了了,就是會出現編譯錯誤,這個需要我們在C語言學習中全面滲透理解。
  • 《C語言入門指南》上篇
    話所在前面:《C語言入門指南》,全文分為3篇。此為上篇,涵蓋知識點為:發展史、快速入門、程序運行機制、基礎知識、常量、運算符、二進位和位運算、程序的控制結構、枚舉,上篇全文共計20000餘字,適用初學者入門C語言,非初學者也可以通過本文複習C語言相關知識點,強化記憶!十三發布這篇筆記也是為了複習C語言!
  • C 語言程序設計---入門篇
    從本篇文章開始,我將分享 C 系列,將 C 語言的方方面面,從最基礎的語法帶領大家入門
  • C語言入門教程(一)
    C語言入門教程(一):輸入輸出函數、程序中的數據實驗環境Ubuntu 16.04 終端gcc
  • C語言入門教程-Scanf
    打開APP C語言入門教程-Scanf 佚名 發表於 2009-07-29 10:44:04 雖然scanf函數可以做許多事情,但是除了最簡單的工作外,一般而言並不很可靠。原因是它不能很好地處理人為錯誤。不過,對於簡單的程序來說,scanf還是很合適的,而且易於使用。
  • 《C語言入門指南》中篇
    話所在前面:《C語言入門指南》,全文分為3篇。
  • c語言50本電子書
    《C程序設計語言(中文版)》(第2版).pdfC語言從初學到精通.pdfC語言函數手冊.PDFC語言各章節知識點總結.pdfC語言常見問題集.pdfC語言開發從入門到精通.pdfC語言深度剖析.pdfC語言程序設計 李健 文字版.pdfC語言程序設計(第四版)譚浩強.pdfC
  • 入門C語言!
    也許有很多同學想學習C語言,卻不知道從什麼地方入手。或者有一些同學,學了一些基礎,太簡單的覺得枯燥無趣,有點複雜的又靜不下心來細細琢磨,也就是所謂的瓶頸時期,如果過了這個時期,C語言的學習就會順暢很多,高度也會大幅度提升。
  • 上海師範大學古籍整理研究所編纂整理:《全宋筆記》增訂本
    內容簡介上海師範大學古籍整理研究所編纂整理的《全宋筆記》增訂本,近日由大象出版社出版,全一百零二冊,二千三百萬字。《全宋筆記》是由戴建國教授領銜主持的國家社科基金重大項目「《全宋筆記》編纂整理與研究」成果的一部分,該項目分為宋人筆記編纂整理和宋人筆記研究兩大塊。中國古代筆記作為一種文體,乃隨筆記事而非刻意著作之文,其以質樸、不事雕琢的特色生動呈現了古代社會生活場景。
  • 《C語言入門指南》完結篇
    話所在前面:《C語言入門指南》,全文分為3篇。此為下篇,涵蓋知識點為:斷點調試、指針、結構體、共用體、CRM系統、文件操作,中篇全文共計12000餘字,適用初學者入門C語言,非初學者也可以通過本文複習C語言相關知識點,強化記憶!十三發布這篇筆記也是為了複習C語言!
  • 物聯網開發筆記——嵌入式開發之Linux系統中C語言分支判斷語句
    所以就先做小的系統,例如構建一整套智能家居系統,從硬體到軟體全系列。下面就開始這套智能家居系統是如何在物聯網基礎上構建。在這裡你可以0開始,然後到1質變,僅僅需要一起跟我學物聯網系列的開發筆記的文章。第五節