c语言笔记照片_c语言笔记
如何看懂一個程序,分三步
1. 流程
2. 每個語句的功能
3. 試數(shù)
對于一些小程序的算法
嘗試自己去編程解決它,大部分人都無法自己解決
如果解決不了,嘗試看答案
關(guān)鍵要把答案看懂,這個要花很大的精力,也是我們學(xué)習(xí)的重點
看懂之后嘗試自己去更改程序,并且知道修改之后程序的不同輸出結(jié)果的含義
重要的運(yùn)算符
舉例:
1/2=0 1.0/2=0.5 1/2.0=0.5
1%2=1 2%2=0 n-1% n=n-1
指針
1. 指針就是地址 地址就是指針
2. 地址就是內(nèi)存單元的編號
3. 指針變量是存放地址的變量
4. 指針和指針變量是兩個不同的概念
5. 但是要注意,通常我們敘述時會把指針變量簡稱為指針,實際上它們含義并不一樣
指針的本質(zhì)就是操作受限的非負(fù)整數(shù).
#include
int main(void)
{
int *p; //p是變量的名字, int *表示p變量存的是int類型變量的地址
int i=3;
p=&I; 1.p保存了i的地址,因此p指向i;
2. p不是i,i也不是p,更準(zhǔn)確地說修改p的值不影響i的值,修改i的值也不影響p的值.
3.如果有一個指針變量指向了普通變量,則 *指針變量 就完全等同于 普通變量. *p 完全等同于i,或者說:在所有出現(xiàn)*p的地方都可以替換成i,在所有出現(xiàn)i的地方都可以替換成*p
*p就是以p的內(nèi)容為地址的變量
return 0;
}
指針的重要性:
1. 表示一些復(fù)雜的數(shù)據(jù)結(jié)構(gòu)
2. 快速的傳遞數(shù)據(jù)
3.使函數(shù)返回一個以上的值
4.能直接訪問硬件
5.能夠方便處理字符串
6.是理解面向?qū)ο笳Z言中應(yīng)用的基礎(chǔ)
總結(jié):c語言的靈魂
指針的定義:
地址:
內(nèi)存單元的編號
從零開始的非負(fù)整數(shù)
指針的分類:
1. 基本類型指針
2. 指針和數(shù)組
3. 指針和函數(shù)
4. 指針和結(jié)構(gòu)誒
5. 多級指針
*的三種含義:
1. 乘法
2.定義指針
Int *p ; // 定義了一個名字叫p的變量,int*表示p只能存放int 變量的地址
3.指針運(yùn)算符
該運(yùn)算符放在已經(jīng)定義好的指針變量的前面
如果p是一個已經(jīng)定義好的指針變量 則*p表示 以p的內(nèi)容為地址的變量]
如何通過被調(diào)函數(shù)修改主調(diào)函數(shù)普通變量的值
1. 實參必須為該普通變量的地址
2. 形參必須為指針變量
3. 在被調(diào)函數(shù)中通過
*形參名 =…… 的方式就可以修改主調(diào)函數(shù)相關(guān)變量的值
指針和數(shù)組
指針和一維數(shù)組
一維數(shù)組名是個指針常量,它存放的是一維數(shù)組第一個元素的地址
如int a[5] a就是a[0]的地址
下標(biāo)和指針的關(guān)系
如果p是一個指針變量,則p[i]永遠(yuǎn)等價于 *(p+i)
確定一個一維數(shù)組需要幾個參數(shù)(如果一個函數(shù)要處理一個一維數(shù)組,則需要接受該數(shù)組的哪些信息)
1. 數(shù)組第一個元素的地址 即數(shù)組名
2. 數(shù)組長度
Int a[5]; // a是數(shù)組名 5是數(shù)組元素的個數(shù) 元素就是變量 a[0]~a[5]
Int a[3] [4] // 3行4列 a[0][0]是第一個元素 a[i][j] 第i+1行第j+1列
指針變量的運(yùn)算
指針變量不能相加 不能相除 也不能相乘
如果這兩個指針變量指向的是同一塊連續(xù)空間的不同存儲單元,則這兩個指針才可以相減
一個指針變量到底占幾個字節(jié)
預(yù)備知識:
Sizeof (數(shù)據(jù)類型)
功能:返回值就是該數(shù)據(jù)類型所占的字節(jié)數(shù)
Sizeof(變量名)
功能:返回值就是該變量所占字節(jié)數(shù)例子: sizeof(int) =4 sizeof(char) =1
假設(shè)p指向char類型變量(1個字節(jié))
假設(shè)q指向int類型變量(4個字節(jié))
假設(shè)r指向double類型變量(8個字節(jié))
p q r 本身所占的字節(jié)是否一樣
一個指針變量,無論它指向的變量占幾個字節(jié),該指針變量本身只占四個字節(jié)
一個變量的地址使用該變量首字節(jié)的地址來表示
動態(tài)內(nèi)存分配
傳統(tǒng)數(shù)組的缺點:
1. 數(shù)組的長度必須事先制定,且只能是常整數(shù),不能是變量(c99之后可以?)
2. 傳統(tǒng)形式定義的數(shù)組,該數(shù)組的內(nèi)存無法手動釋放
在一個函數(shù)運(yùn)行期間,系統(tǒng)為該函數(shù)中數(shù)組所分配的空間會一直存在,直到該函數(shù)運(yùn)行完畢時,數(shù)組的空間才會被系統(tǒng)釋放
3. 數(shù)組的長度一旦定義,其長度不能再更改,數(shù)組的長度不能在函數(shù)運(yùn)行的過程中動態(tài)的擴(kuò)充或縮小
4. A函數(shù)定義的數(shù)組,在A函數(shù)運(yùn)行期間可以被其它函數(shù)使用,但A函數(shù)運(yùn)行完畢之后,A函數(shù)中的數(shù)組將無法在其它函數(shù)中使用
傳統(tǒng)方式定義的數(shù)組不能跨函數(shù)使用.
malloc memory(內(nèi)存) allocate(分配)的縮寫
#include
int * p = (int *) malloc (4);
1. 要使用malloc函數(shù),必須添加malloc.h這個頭文件
2. malloc函數(shù)只有一個形參,并且形參是整型
3. 4表示請求系統(tǒng)為本程序分配4個字節(jié)
4. malloc函數(shù)只能返回第一個字節(jié)的地址
5. 分配了8個字節(jié),p變量占4個字節(jié),p所指向的內(nèi)存地址也占4個字節(jié)
6. P本身所占的內(nèi)存是靜態(tài)分配的,p所指向的內(nèi)存是動態(tài)分配的
free(p)表示把p所指向的內(nèi)存給釋放掉,p本身的內(nèi)存是靜態(tài)的,不能由程序員手動釋放,p本身的內(nèi)存只能在p變量所在函數(shù)運(yùn)行終止時由系統(tǒng)釋放
為什么需要動態(tài)分配內(nèi)存
動態(tài)數(shù)組很好的解決了傳統(tǒng)數(shù)組的4個缺陷
動態(tài)數(shù)組的構(gòu)造
#include
int main(void)
{
int a[5] //如果int占4個字節(jié)的話,則本數(shù)組總共包含20個字節(jié),每4個字節(jié)被當(dāng)作 一個int變量來使用
int len;
int *pArr;
printf(“請輸入你要存放的元素的個數(shù):”)
scanf(“%d”,&len);
pArr =(int *)malloc(4* len) //本行動態(tài)的構(gòu)造了一個一維數(shù)組,該一維數(shù)組的長度是len
return 0;
}
動態(tài)內(nèi)存和靜態(tài)內(nèi)存的比較
靜態(tài)內(nèi)存是由系統(tǒng)自動分配,由系統(tǒng)自動釋放
靜態(tài)內(nèi)存是在棧分配的
動態(tài)內(nèi)存是由程序員手動分配的,手動釋放
動態(tài)內(nèi)存是在堆分配的
多級指針
#include
Int main(void)
{
Int i=10;
Int *p=&i; //p是int *類型 ,&p是int ** 類型
Int **q=&p;
Int ***r =&q;
因為r是int ***類型,r只能存放 int ** 類型變量的地址
跨函數(shù)使用內(nèi)存
# include
void f(int **q) q是個指針變量,無論q是什么類型的指針變量,都只占4個字節(jié)
{
Int i=5;
}
Int main(void)
{
Int *p;
f(&p);
return 0;
}
結(jié)構(gòu)體是根據(jù)用戶實際需要自己定義的復(fù)合數(shù)據(jù)類型
如何使用結(jié)構(gòu)體
兩種方式:
Struct Student st ={1000,”zhangsan”,20};
Struct Student *pst = &st;
1.
St.sid
2.
Pst->sid
Pst所指向的結(jié)構(gòu)體變量中的sid這個成員
注意事項:
結(jié)構(gòu)體變量不能加減乘除,但是可以相互賦值
普通結(jié)構(gòu)體變量和結(jié)構(gòu)體指針變量作為函數(shù)傳參的問題
#include
#include
struct Student{
int age;
char sex;
char name[100];
};
void InputStudent(struct Student * pstu);
void OutputStudent(struct Student ss);
int main(void)
{
struct Student st;
InputStudent(&st); //對結(jié)構(gòu)體變量的輸入
printf("%d %c %s\n",st.age ,st.sex, st.name);
OutputStudent(st); //對結(jié)構(gòu)體變量的輸出,可以發(fā)送st的地址也可以發(fā)送st的內(nèi)容
return 0;
}
void OutputStudent(struct Student ss)
{
printf("%d %c %s\n",ss.age, ss.sex , ss.name);
}
void InputStudent(struct Student * pstu) //pstu只占4個字節(jié)
{
(*pstu).age =10;
strcpy(pstu->name,"張三");
pstu->sex='f';
}
/*
//本函數(shù)無法修改主函數(shù)st的值,所以本函數(shù)是錯誤的
void InputStudent(struct Student stu)
{
stu.age=10;
strcpy(stu.name,"張三"); //不能寫成 stu.name="張三";
stu.sex='f';
}
*/
動態(tài)構(gòu)造存放學(xué)生信息的結(jié)構(gòu)體數(shù)組
//動態(tài)構(gòu)造一個數(shù)組,存放學(xué)生信息,然后按分?jǐn)?shù)排序輸出
#include
#include
struct Student
{
int age;
char sex;
float score;
char name[100];
};
int main(void)
{
int len;
struct Student * pArr;
int i,j;
struct Student t;
printf(" 請輸入學(xué)生的個數(shù):\n");
printf("len =");
scanf("%d",&len);
//動態(tài)地構(gòu)造一維數(shù)組
pArr =(struct Student *)malloc(len *sizeof(struct Student));
for (i=0;i
{
printf("請輸入第%d個學(xué)生的信息:\n",i+1);
printf("age=");
scanf("%d",&pArr[i].age);
printf("name=");
scanf("%s",pArr[i].name); //不用加&,因為name是數(shù)組名,本身就已經(jīng)是數(shù)組首元素的地址
printf("score=");
scanf("%f",&pArr[i].score);
}
//按學(xué)生成績升序,冒泡算法
for(i=0;i
{
for(j=0;j
{
if(pArr[j].score>pArr[j+1].score)
{
t=pArr[j];
pArr[j]=pArr[j+1];
pArr[j+1]=t; //換位置而不是換成績
}
}
}
printf("\n\n學(xué)生的信息是:\n");
//輸出
for (i=0;i
{
printf("第%d個學(xué)生的信息是:\n",i+1);
printf("age=%d\n",pArr[i].age);
printf("name=%s\n",pArr[i].name);
printf("score=%f\n",pArr[i].score);
printf("\n");
}
return 0;
}
枚舉
什么是枚舉?
把一個事物所有可能的取值一一列舉出來
怎樣使用枚舉
#include
//只定義了一個數(shù)據(jù)類型,并沒有定義變量,該數(shù)據(jù)類型的名字是 enumm WeekDay
enum WeekDay{
MonDay,TuesDay,WednesDay,ThursDay,FriDay,SaturDay,SunDay
};
int main(void)
{
// int day; day定義成int類型不太合適
enum WeekDay day=SunDay;
printf("%d\n",day);
return 0;
}
枚舉的優(yōu)缺點
代碼更安全
書寫麻煩
進(jìn)制轉(zhuǎn)換
預(yù)備知識:
小數(shù)除以大數(shù) 商為零 余數(shù)是小數(shù)本身
十進(jìn)制轉(zhuǎn)換為r進(jìn)制
方法
除r取余,直至商零,余數(shù)倒序排列
二進(jìn)制到十六進(jìn)制
方法: 從左往右,四位一段,分別轉(zhuǎn)化,不夠四位的補(bǔ)零
二進(jìn)制與八進(jìn)制相互轉(zhuǎn)換
原碼:
也叫符號-絕對值碼
最高位0表示正 1表示負(fù),其余二進(jìn)制位是該數(shù)字的絕對值的二進(jìn)制位
原碼簡單易懂
加減運(yùn)算復(fù)雜
存在加減乘除四種運(yùn)算,增加了cpu的復(fù)雜度
零的表示不唯一
反碼
反碼運(yùn)算不便,也沒有在計算機(jī)中運(yùn)用
移碼
移碼表示數(shù)值平移n位,n為偏移量
移碼主要用于浮點數(shù)的階碼的存儲
補(bǔ)碼
已知十進(jìn)制求二進(jìn)制
求正整數(shù)的二進(jìn)制
除2取零,直至商0,余數(shù)倒敘排序
求負(fù)整數(shù)的二進(jìn)制
先求與該負(fù)數(shù)相對應(yīng)的正整數(shù)的二進(jìn)制代碼,然后將所有位取反,末位加1,不夠位數(shù)時,左邊補(bǔ)1
求零的二進(jìn)制
全是零
已知二進(jìn)制求十進(jìn)制
如果首位是0,則表明是正整數(shù),按普通方法求
如果首位是1,則表明是負(fù)數(shù),將所有位取反,末尾加1,所得數(shù)字就是該負(fù)數(shù)的絕對值
如果全是0,則對應(yīng)的十進(jìn)制數(shù)字就是0
比方說:十進(jìn)制中的1用二進(jìn)制表示就是01,當(dāng)你二進(jìn)制轉(zhuǎn)十進(jìn)制的時候,你需要輸入01,系統(tǒng)是自動在01前頭補(bǔ)30個0來湊夠32位.這是正整數(shù)的時候,可是當(dāng)你是十進(jìn)制中的-1時,二進(jìn)制表示時,先取十進(jìn)制-1的絕對值1的二進(jìn)制.否則系統(tǒng)會自動給你補(bǔ)30個0,導(dǎo)致二進(jìn)制的11被認(rèn)為是正整數(shù)3而不是-1
算法:
通俗定義:
解題的方法和步驟
狹義定義:
對存儲數(shù)據(jù)的操作
對不同的存儲結(jié)構(gòu),要完成某一功能所執(zhí)行的操作是不一樣的
比如:
要輸出數(shù)組中所有元素的操作和要輸出鏈表中所有元素的操作肯定是不一樣的,這說明算法是依附于存儲結(jié)構(gòu)的,不同的存儲結(jié)構(gòu),所執(zhí)行的算法是不一樣的
廣義定義:
廣義的算法也叫泛型
無論數(shù)據(jù)是如何存儲的,對該數(shù)據(jù)的操作是一樣的
我們至少可以通過兩種結(jié)構(gòu)來存儲數(shù)據(jù)
數(shù)組:
優(yōu)點:
存取速度快
缺點:
需要一個連續(xù)的很大的內(nèi)存
插入和刪除元素的效率很低
鏈表
優(yōu)點:
插入刪除元素效率高
不需要一個連續(xù)的很大的內(nèi)存
缺點:
查找某個位置的元素效率很低
專業(yè)術(shù)語:
頭結(jié)點
頭結(jié)點的數(shù)據(jù)類型和首節(jié)點的類型一模一樣
頭結(jié)點是首節(jié)點前面的那個節(jié)點
頭結(jié)點并不存放有效數(shù)據(jù)
設(shè)置頭結(jié)點是為了方便對鏈表的操作
頭指針
存放頭結(jié)點地址的指針變量
首節(jié)點
存放第一個有效數(shù)據(jù)的節(jié)點
尾節(jié)點
存放最后一個有效數(shù)據(jù)的節(jié)點
確定一個鏈表需要一個參數(shù)(頭結(jié)點的地址)
郝斌老師的09年課程
總結(jié)
以上是生活随笔為你收集整理的c语言笔记照片_c语言笔记的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: idea创建包怎么让包分层_干货 | 通
- 下一篇: 人脸识别与膜虹识别_当人脸识别遭遇口罩,