八、函數
在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中 也可以可以使用定位來給二維數組賦初始值