全面學習C語言【三】:函數、本地變量、數組(一維數組、二維數組)

八、函數

在C中 函數是這樣的:

void hello(int id)
{
	printf("Hello!%d",id);
}

C不像Java 在C中定義函數的時候不需要權限修飾符 只有返回類型函數名

和Java一樣 在C中也是使用return來返回值

int calc(int count)
{
	int newCount=count-1;
	return newCount;
}

🎈函數的先後關係

C的編譯器是按照代碼書寫順序自上而下按順序分析代碼的
因此 要將函數定義在主函數(main)的上面 使得C先知道代碼中的函數
這樣 當main中需要調用的時候 才能執行對應的函數
否則 若是main函數在上面 函數書寫在下面 那麼在執行函數的時候 C是不知道下面有沒有對應的函數的 在編譯的時候可能會報錯

因此 若想讓主函數(main)寫在代碼的上面 必須讓C先了解代碼中有哪些函數 需將函數的原型聲明放在main的上面

比如:

#include <stdio.h>

// 函數的原型聲明 以分號結尾
int calc(int count);

int main()
{
	int a=5;
	int b;
	b=calc(a);
	printf("%d",b);
}

// 函數的定義
int calc(int count)
{
	int newCount=count-1;
	return newCount;
}

聲明並不是函數 只是先告訴C編譯器有這麼一個函數
在編譯到了函數的定義的時候還會再對聲明進行一次校驗
因此 必須保證函數的聲明和定義完全一致

在函數的原型聲明中還可以不帶有入參的名稱 只要有參數類型即可

比如:

int calc(int);

但爲了方便閱讀代碼 最好還是帶上參數的名稱

如果函數沒有參數 建議在參數裏面寫上void 而不要留空
留空意味着並不一定是沒有參數 而是函數的參數表未知
因此 當參數留空時 C會進行猜測 從而導致可能會產生一些類型轉換的問題

🚩當參數的類型不匹配時

在C語言中 調用函數時所給的值與參數的類型可以不匹配
編譯器會自動將類型進行轉換可能不會給出錯誤提示 因此可能會出現一些問題

C語言在調用函數時 永遠只能傳給函數 而不是傳變量

🎈本地變量的規則

  • 本地變量定義在塊中 可以是函數的塊 語句的塊 甚至是隨意一對花括號
    在程序運行進入到這個快的區域內之前 其中的變量是不存在的
    在離開這個塊之後 其中的變量就消失了

  • 塊的外部定義的變量在塊的裏面仍然是有效的 仍然可以使用

  • 在塊的內部 若定義了一個和外部同名的變量 那麼會掩蓋外面的變量 (個人覺得掩蓋比覆蓋用詞更爲妥當)
    在塊內部使用時 使用的是在塊內部定義的那個變量 而不是外部的同名變量 (然而在Java中就不行了 因此這是C和Java的一個區別)
    當到了塊的外部後 則外面的變量又會生效了

另 需要注意的是 在C語言中 不允許函數的嵌套
也就是不允許在一個函數的函數體內放入另外一個函數的函數體
但是可以放入另一個函數的聲明

main() 是程序的入口 也是一個函數
同樣 在main中 需要返回一個值 作爲程序的狀態碼
在傳統程序中 若返回0 則代表正常運行 若返回非0 則代表出現了一些異常

int main()
{
	return 0;
}

九、數組

🎈一維數組

🚩定義數組

格式:<類型> 變量名[數量];

例如:

int count[100]; // 定義一個長度100的類型爲int的名稱爲count的數組
double height[20]; // 定義一個長度20的類型爲double的名稱爲height的數組

:在C99之前 元素數量必須是編譯時確定的字面量 不能是變量

數組一旦創建 無法改變數組的大小
數組中的元素在內存中是緊密地依次排列的

如果定義一個數組:int i[100];
那麼 每個單元就是i[n]
在賦值號=的左邊的是左值 在右邊的是右值

在C語言中 無論是編譯器還是運行環境 都不會檢查代碼中的數組下標是否越界(無論是讀操作還是寫操作)
因此 一旦程序運行了 則越界的數組操作可能導致程序出現問題

數組集成初始化

對於數組 還有一種初始化的方式 就是在創建數組的時候給定數組中所有的值
比如:

 int i[]={1,2,3,4,5,6,7,8};

(當然 在Java中也有這種初始化的方式)

如果這麼定義:

int i[10]={1};

那麼 數組 i 的內部是這樣的:1 0 0 0 0 0 0 0 0 0
若未設置值 那麼默認會將數組中值設爲0

集成初始化的定位

C99中 還可以使用定位來給數組賦初始值
比如:

int i[10]={
	[1]=12,[3]=21,36
}

上述代碼的意思是:爲數組 i 中的第二項賦初始值爲12 爲第四項賦初始值爲21 爲第五項賦初始值爲36

🚩數組的大小和長度

在C中 使用sizeof來獲取整個數組所佔據的內容的大小(單位爲字節)

在C中不像Java有length能直接獲取數組的長度 但可以間接獲得
數組的大小除以數組中第一個單位的大小 (因爲數組中每個單位的大小都是相同的)

int i[6];
// 數組的大小 
printf("%d\n",sizeof(i)); // 24
// 數組中第一個單位的大小 
printf("%d\n",sizeof(i[0])); // 4

// 數組的長度
printf("%d\n",sizeof(i)/sizeof(i[0])); // 6

🚩數組的賦值

數組不能直接賦值 比如:

int a[]={1,2,3};
int b[]=a;

數組變量本身不能被賦值
若要將一個數組中的所有元素交給另一個數組 那麼必須採用遍歷 這是唯一的方式

在C中 數組在作爲函數的參數傳入時 必須再用另一個參數來傳入該數組的大小
因爲 在函數中 不能再使用sizeof來計算數組的元素個數了

🎈二維數組

🚩定義數組

格式:<類型> 變量名[行數量][列數量];

例如:

int count[3][5]; // 定義一個3行5列的類型爲int的名稱爲count的數組(矩陣)
數組集成初始化
int i[][5]=[
	{1,2,3,4,5},
	{6,7,8,9,10}
];

在初始化的時候 必須給出列數

若省略 則表示後面的值補爲默認的0

也可以寫成一行 就像一維數組一樣:
但是不方便閱讀

int i[][3] = {1,2,3,4,5,6,7,8,9};
相當於
int i[][3]=[
	{1,2,3},
	{4,5,6},
	{7,8,9}
];

當然 在C99中 也可以可以使用定位來給二維數組賦初始值


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章