天天看點

C語言學習

​<code>​printf("i=%d\n",i);​</code>​

/*

printf的用法

%d表示以十進制輸出

%x或%x表示以十六進制輸出

%o表示以八進制輸出

*/

十六進制:在前面加上0x或0x;

八進制:在前面加數字 0

單個字元用單引号括起來

'a' 表示字元a

'ab' 錯誤

字元串用雙引号括起來

"a"正确,因為"a"代表了'a' '\0' 的組合

01組成的代碼可以表示資料也可以表示指令;

如果01組成的代碼表示的是資料的話,那麼同樣的01代碼組合以不同的輸出格式輸出就會有不同的輸出結果

用法一:scanf("輸入控制符",輸入參數);功能:将從鍵盤輸入的字元轉化為輸入控制符所規定的資料,然後存入以輸入參數的值為位址的變量中

‘ scanf("%d",&amp;i); //&amp;i表示i的位址,&amp;是一個取位址符 ’

用法二:scanf("非輸入控制符 輸入控制符",輸入參數);//非輸入控制符必須原樣輸入,同時無需像printf那樣添加\n

' scanf("m%d",&amp;i); //m123正确的輸入,123非法的輸入,輸入結果為123 '

功能:将從鍵盤輸入的字元轉化為輸入控制符所規定的資料,然後存入以輸入參數的值為位址的變量中scanf中盡量不要使用非輸入控制符,尤其是不要用\n

除法 / 的運算結果和運算對象的資料類型有關,兩個都是int,則商也是int;若商有小數,則删除小數部分;被除數和除數中隻要有一個或兩個都是浮點型資料,則商也是浮點型,不删除小數部分

取餘 % 的運算對象必須是 整數 ,如:1.5/2 錯誤; 結果是整除後的餘數,其餘數的符号與被除數相同

自增:i++ 或 i--(i++和++i單獨成一個語句,不要把它們作為一個完整複合語句的一部分來使用)

三目運算符:a?b:c 等價于 if(a)

b;

else

c;

逗号表達式:

格式:(a,b,c,d)

功能:從左到右執行,最終表達式的值是最後一項的值。

{

printf("大于\n");

printf("哈哈\n");

}

else if(a==0)

printf("等于\n");//編譯正确

注意:

大于90小于100不能寫成90&lt;=score&lt;=100;應寫成 score&gt;=90&amp;&amp;score&lt;=100

一些小算法的程式:

1、判斷一個數字是否是素數;

2、判斷一個數字是否是回文數,如121;

3、程式設計實作求一個十進制數的二進制形式;

4、求一個數字的每位是奇數的數字取出來組合成的新數字;

5、求一個數字倒過來 的數字

if常見的問題解析

1、空語句的問題

if (3&gt;2);

等價于

if (3&gt;2)

; //這是一個空語句

注意: 最後一個else的用法:

直接單個的else 或 else if+(表達式)//後者文法不會出錯,但邏輯有漏洞

格式:(資料類型)(表達式)

功能:把表達式的值強制轉化為前面所執行的資料類型

例子:(int)(4.5+2.2) 結果為6

(float)(5)結果為5.000000

1、 float和 double都不能保證可以精确的存儲一個小數

例子:

float i=99.9;

printf("%f\n",i);

輸出結果為:99.900002

舉例:判斷浮點型變量x的值是否為0:

if(|x-0.0000001|&lt;=0.0000001)

是0;

不是0;

2、為什麼循環中更新的變量不能定義成浮點型?

for(1;2;3)

a;

1;

while(2)

a;

3;

while和for可以互相轉化,但for的邏輯性更強,更不容易出錯,推薦多使用for。

格式:do

....

} while ( 表達式);

注意:do...while...并不等價于for,也不等價于while。

break和continue

break:

1、如果用于循環使用來終止循環;

2、如果用于switch,則是用于終止 switch

3、break不能直接用于if,除非if屬于循環内部的一個字句

for(i=0;i&lt;3;++i)

if(3&gt;2)

break; //break雖然是if内部的語句,但 終止的是外部的for循環

printf("嘿嘿!\n");//永遠不會輸出

4、在多層循環或者多層switch語句中,break隻能終止距離它最近的循環或者switch語句

在多層switch嵌套中break隻能終止距離它最近的switch語句

continue:

用于跳過本次循環餘下的語句,轉去判斷是否需要執行下次循環

數組定義:

為n個變量連續配置設定存儲空間

所有的變量資料類型必須相同

所有變量所占位元組大小必須相同

錯誤寫法:

int a[5];

a[5]={1,2,3,4,5}; //錯誤,a[5]元素不存在

隻有在定義數組的同時才可以整體指派,其他情況下整體指派都是錯誤的

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

int b[5];

如果要把a數組的值全部複制給b數組

錯誤的寫法:

b=a; // error

正确的寫法:

for(i=0;i&lt;5;++i)

b[i]=a[i];

一維數組名不代表數組中的所有元素,僅代表數組第一個元素的位址多元數組:

n維數組可以當作每個元素是n-1維數組的一維數組

int f (void) // 括号中的void表示該函數不能接受資料,int表示函數傳回值是int類型

void g (void) //函數名前面的void表示該函數沒有傳回值

函數定義

函數的傳回值 函數名 (函數的形參清單)

函數的執行體

函數傳回值的類型也稱為函數的類型,因為如果 函數名 前的傳回值類型和 函數執行體 中的 return表達式; 中表達式的類型不同的話,則最終函數傳回值的類型以 函數名 前的傳回值類型為準

1&gt;終止被調函數,向被調函數傳回表達式的值;

2&gt;如果表達式為空,則隻終止函數,不向被調函數傳回任何值;

3&gt;break是用來終止循環和switch的,return是用來終止函數的

一個程式必須有且隻能有一個主函數;主函數可以調用普通函數,普通函數不能調用主函數;普通函數可以互相調用主函數是程式的入口,也是程式的出口

如果函數調用寫在了函數定義的前面,則必須加函數前置聲明

函數前置聲明:

1、告訴編譯器即将可能出現的若幹個字母代表的是一個函數;

2、告訴編譯器即将可能出現的若幹個字母所代表的函數的形參和傳回值的具體情況

3、函數聲明是一個語句,末尾必須加分号;

4、對庫函數的聲明是通過 # include&lt;庫函數所在的檔案名字.h&gt;來實作的

形參和實參;

個數相同 位置一一對應 資料類型必須互相相容

常用的系統函數使用(百度)

按作用域分:

全局變量:在所有函數外部定義的變量叫做全局變量

全局變量使用範圍:從定義位置開始到整個程式結束

局部變量:在一個函數内部定義的變量或者函數的形參 都統稱為局部變量

void f (int i)

int j=20;

i,j都屬于局部變量

局部變量使用範圍:隻能在本函數内部使用

在一個函數内部如果定義的局部變量的名字和全局變量的名字一樣時,局部變量會屏蔽掉全局變量

include&lt;stdio.h&gt;

int main(void)

int *p;//p是變量的名字,int *表示p變量存放的是int類型變量的位址

//int *p: 不表示定義了一個名字叫做 *p 的變量

//int p: p是變量名,p變量的資料類型是int * 類型

//所謂int 類型就是存放int變量位址的類型

int i=3;

p=&amp;i;

/

1.p儲存了i的位址,是以p指向i

2.p不是i,i也不是p,修改p的值不影響i的值,修改i的值不影響p的值

3.如果一個指針變量指向了某個普通變量,則

指針變量 就完全等同于 普通變量

例子:如果p是一個指針變量,并且p存放了普通變量i的位址

則p指向了普通變量i

* p 就完全等同于 i

即在所有出現p的地方都可以替換成 i

在所有出現 i 的地方都可以替換成p

1、指針就是位址,位址就是指針

2、位址就是記憶體單元的編号

3、指針變量是存放位址的變量

4、指針和指針變量就是兩個不同的概念

5、要注意的是,通常我們叙述時可能會把指針變量簡稱為指針,實際它們含義不一樣

6、指針的本質就是一個操作受限的非負整數

void huhuan(int p, int q )

int t ;//如果要互換p和q的值,則t必須定義成int,不能定義成int ,否則出錯

t=p; // p是 int * 類型, p是 int類型

p=q;

q=t;

int main (void)

int a=3;

int b=5;

huhuan(&amp;a,&amp;b); //huhuan(p,q); 是錯誤的,huhuan(a,b); 也是錯誤的

printf("a=%d,b=%d\n",a,b);

return 0;

* 的定義

1、乘法;

2、定義指針變量

int *p; //定義了一個名字叫做p的變量,int *表示p隻能存放 int 變量的位址

3、指針運算符

該運算符放在已經定義好的指針變量的前面,如 p=i

如果p是一個已經定義好的指針變量,則p 表示以p的内容為位址的變量,即 i;

如何通過被調函數修改主調函數普通函數的值

1、實參必須為該普通變量的位址;

2、形參必須為指針變量

3、在被調函數中通過

*形參名 = ..... 的方式就可以修改主調函數相關變量的值

指針和一維數組:

一維數組名: 它是一個指針常量,存放的是一維數組的第一個元素的位址

下标和指針的關系

如果p是個指針變量,則p[i] 永遠等價于 *(p+i)

确定一個一維數組需要幾個參數

兩個參數: 數組第一個元素的位址、 數組的長度

*(parr+i)等價于 parr[i]

指針變量不能相加,不能相乘,也不能相除

如果兩個指針變量指向的是同一塊連續空間的不同存儲單元,則這兩個指針變量才可以相減

一個指針變量到底占幾個位元組

p指向char類型變量:一個位元組

q指向int類型變量:四個位元組

r指向double類型變量:八個位元組

p,q,r本身所占的位元組數是否一樣?

答案:p q r本身所占的位元組數是一樣的

sizeof(資料類型)

功能:傳回值是該資料類型所占的位元組數

sizeof(變量名)

功能:傳回值是該變量所占的位元組數

例如:sizeof(int)=4

總結

1、 一個指針變量,無論它指向的變量占幾個位元組,該指針變量本身隻占 四 個位元組(32位資料線表示位址,即32/8=4 個位元組)

2、 一個變量的位址使用該變量首位元組的位址來表示

傳統數組的缺點:

1、傳統形式定義的數組,該數組的記憶體程式員無法手動釋放,在一個函數運作期間,系統為該函數所配置設定的空間會一直存在,知道該函數運作完畢,數組的空間才會被系統釋放

2、 傳統方式定義的數組不能跨函數使用

malloc函數 是memory(記憶體) allocate(配置設定)的縮寫

1、使用malloc函數,必須添加malloc.h這個頭檔案

2、malloc函數隻有一個形參,并且形參是整型

3、malloc(4) 表示請求系統為本程式配置設定4個位元組

4、malloc函數隻能傳回第一個位元組的位址

free(p)表示把p指向的記憶體給釋放掉,但不能把p本身所占的記憶體給釋放,其在程式結束時由系統自動釋放。動态配置設定和靜态配置設定的比較

靜态記憶體是由系統自動配置設定,由系統自動釋放;

靜态記憶體是在 棧 配置設定的

動态記憶體是由程式員手動配置設定,手動釋放

動态記憶體是在 堆 配置設定的(函數終止時不釋放記憶體)

3種方式(推薦第一種):

1、struct student //定義了一個資料類型,而不是一個變量

int age;

float score;

char sex;

};

2、 struct student

}st;

3、struct

} st;

1、結構體變量名 . 成員名

2、指針變量名-&gt;成員名 (常用)

3、指針變量名-&gt;成員名 在計算機内部會被轉換成 (* 指針變量名). 成員名 的方式來執行

例如:

st.age=10;

pst-&gt;age=88; // 前面有 struct student * pst=&amp;st;

pst-&gt;age在計算機内部會被轉換成(*pst).age

結構體變量和結構體指針變量作為函數參數傳遞的問題

推薦使用結構體指針變量作為函數參數來傳遞

結構體變量的運算

結構體變量不能相加,不能相減,也不能互相乘除

但結構體變量可以互相指派。

多看多學!!!