郝斌老師C語言專題筆記_第1頁
郝斌老師C語言專題筆記_第2頁
郝斌老師C語言專題筆記_第3頁
郝斌老師C語言專題筆記_第4頁
郝斌老師C語言專題筆記_第5頁
已閱讀5頁,還剩18頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、專題:動態內存分配 (所有高級語言,沒有C里深刻)傳統數組的缺點:1.數組長度必須事先指定,而且只能是常整數,不能是變量例子int a5; /必須事先指定,而且只能是常整數 int len = 5; int alen;/error2.傳統形式定義的數組,該數組的內存程序員無法手動釋放數組一旦定義,系統為數組分配的內存空間就會一直存在,除非數組所在的函數運行終止。在一個函數運行期間,系統為該函數中的數組分配的空間會一直存在。直到該函數運行完畢時,數組的空間才會被系統自動釋放。例子:void f(void)int a5=1,2,3,4,5;./數組a 占20個字節的內存空間,程序員無法手動編程釋放

2、它,數組a只能在f()函數結束被系統釋放3. 數組的長度一旦定義,數組長度就不能再更改。數組的長度不能在函數運行的過程中動態的擴充或縮小4. 傳統方式定義的數組不能跨函數使用A函數定義的數組,只有在A函數運行期間才可以被其他函數使用,但A函數運行完畢后,A函數中的數組將無法在被其他函數使用。#include<stdio.h>void g(int * pArr, int len) pArr2 = 88; /parr2=a2 等價于 void f(void) int a5 = 1,2,3,4,5; /數組a 只在f()執行時有效 g(a,5);printf("%dn"

3、;, a2);int main(void) f(); / 結果: 88/printf("a0 = %dn", a0); / error return 0;為什么需要動態分配內存很好的解決的了傳統數組的4個缺陷動態內存分配舉例_動態數組的構造 難點/*2011-05-01malloc是memory(內存) allocate(分配)的縮寫動態內存空間是怎么造出來的?*/#include <stdio.h>#include <malloc.h>int main(void)int i = 5; /分配了4個字節,靜態分配int * p = (int *)ma

4、lloc(100);/*1. 要使用malloc函數,必須要添加malloc.h頭文件2. malloc函數只有一個形參,并且形參是整型3. 100表示請求系統為本程序分配()個字節4. malloc函數只能返回第一個字節的地址,并且這個地址被強制類型轉化成存放整型變量的地址,傳達出指向整型變量的信息5. 系統分配了104個字節的內存空間,p變量本身占4個字節,p所指向的內存占100個字節6. p本身所占的內存是靜態分配的,p所指向的內存是動態分配的*/free(p);/free(p)表示把p說指向的內存空間給釋放掉,/p本身的內存不能釋放,只有main函數終止時,由系統自動釋放*p = 5;

5、 /*p代表的就是一個這int變量,*p這個整型變量的內存分配方式和int i =5;不同。/*p是內存是動態分配的, int i是靜態的。printf("同志們好!n");return 0;-/*2011-05-01目的: malloc使用_2*/#include <stdio.h>#include <malloc.h>void f(int * q) /q是p的拷貝或副本 q等價于p *q等價于*p *q=200則*p=200/*p = 200; /error f()沒有p變量,p是在main()函數定義的/ q = 200; /q是指針變量,20

6、0是整數*q = 200; /OK!/ * *q 語法錯誤 !*q整型變量, 只有指針變量前可以加*/free(q);/把q指向的內存釋放掉int main(void)int * p = (int *)malloc(sizeof(int);/sizeof(int)=4;*p = 10;printf("%dn", *p); /10f(p);printf("%dn", *p); /200/ f()函數中 free(q),則輸出 -572662307return 0;/*2011-05-02目的:動態一維數組示例realloc(pArr, 100)/擴充動態內

7、存空間 (原來50變100;原來150變100)/保留原來動態內存中未被截取的內容*/#include <stdio.h>#include <malloc.h>int main(void) /int a5; /系統分配20個字節的空間給數組aint len;int *pArr;printf("請輸入你要存放的元素個數:" );scanf ("%d", &len);/5pArr = (int *)malloc(4*len);/pArr指向這20個字節動態空間的前4個字節/*動態的構造了一個一維數組,該數組的長度len, 數組

8、名是pArr, 數組元素類型是int類似與int pArrlenl; len可以變化*/對一維數組進行操作,如:對動態一維數組進行賦值for (int i=0; i<len; +i)scanf("%d", &pArri); printf("動態數組元素為: n");/對一維數組進行輸出for(i=0; i<len; +i)printf("%dn", pArri);free(pArr);/動態空間被釋放printf("%dn", *(pArr+1); /動態空間被釋放,原來動態數組數元素內容為垃圾

9、值-572662307return 0;/*-在VC+6.0輸出結果:請輸入你要存放的元素個數:44 6 8 10動態數組元素為:46810*/使用動態數組的優點:1.動態數組長度不需要事先給定;2.內存空間可以手動釋放;3.在程序運行中,動態內存空間大小可以通過realloc函數手動擴充或縮小靜態內存和動態內存的比較靜態內存是由系統自動分配,有系統自動釋放靜態內存是在棧分配的動態內存是由程序員手動分配,手動釋放動態內存是在堆分配的 /*2011-05-02目的: 多級指針/#include <stdio.h>int main(void) int i = 10;/ iint * p

10、 = &i;/ *p = i;int * q = &p; /int * r = &q; /r = &p; /error! 因為r是int*類型,只能存放int *類型變量的地址printf("i = %dn", *r);printf("i = %dn", *q);printf("i = %dn", *p);printf("i = %dn", i);return 0;/*-在VC+6.0輸出結果:i = 10i = 10i = 10i = 10*/#include <stdio.

11、h>/多級指針在函數中的應用void f(int * q)*q = 100;/*q就是pvoid g()int i = 10;int * p = &i;printf("i = %d *p = %dn", i, *p);f(&p); /p是int *類型&p就是int * 類型printf("i = %d *p = %dn", i, *p); int main(void) g();return 0;/*-在VC+6.0輸出結果:i = 10 *p = 10i = 100 *p = 100*/ #include <stdi

12、o.h>#include <malloc.h> void f(int * q) /q是p的拷貝副本*q = 1;void g(int *r)*r = 2;void h(int *s)*s = 3;void i(int *t)*t = 4;/要想修改函數變量的值,只能發送該變量的地址,修改一個以上的值,必須用指針int main(void) int *p = (int *)malloc(4);printf("*p = %dn", *p);/垃圾值f(p); /調用的是指針printf("*p = %dn", *p);/1 g(&p

13、);/調用的是指針變量的地址printf("*p = %dn", *p);/2/h(&(&p);/ error C2102: '&' requires l-valueint *pp = &p; /pp是存放p地址的指針, int * 整型指針的指針類型h(&pp); /調用的是存放p指針的指針的地址int *整型指針的指針的指針類型printf("*p = %dn", *p);/3int *ppp = &pp;i(&ppp);/調用的是一個三級指針的指針的地址,int * 整型四級指

14、針printf("*p = %dn", *p);/4return 0;跨函數使用內存的問題難點/*2011-05-02目的:跨函數使用內存 函數內的靜態空間,不能被其他函數調用訪問*/#include <stdio.h>void f(int *q) /理解為 int* *qint i =5;/*q等價于p*p和*q都不等價于p/*q = i;/error *q等價于p 推出 p=i; 錯!*q = &i;/*q = *p = i;int main(void) int *p;f(&p);printf("%dn", *p); /*

15、結果:5 本語句語法沒有問題,但邏輯上有問題 內存越界:程序訪問了一個不該被訪問的內存函數內的靜態空間,不能被其他函數調用訪問函數中的內存空間,隨函數終止而被釋放。內存空間釋放后的內容不屬于其他函數,其他函數無權限訪問。但釋放后的內存空間的地址是可以被其他函數讀取的。指針變量可以存貯任何函數中靜態內存空間的地址,p都能存垃圾,p想存誰存誰*/return 0;/*2011-05-02目的:動態內存可以跨函數訪問程序運行在棧頂進行靜態空間是在棧里面分配的,函數終止本質叫做出棧,所以靜態空間隨著函數終止而釋放,動態空間是在堆里面分配的,與棧無關,與函數終止無關,不隨著函數終止而釋放。可以用free

16、()釋放*/#include <stdio.h>#include <malloc.h>void f(int * q)/*q等價p 已經聲明了q的類型為int *q = (int *)malloc(sizeof(int);/sizeof(整數類型)/*不要用4,因為c語言只規定short int字節數<int字節數<long int字節數,沒有規定明確的字節數. 不同軟件系統可能出現不同,統一用sizeof(int)來獲取實際值int * p;在p聲明的情況下,構造動態空間也可以寫成 p = (int *)malloc(sizeof(int);*/ *q等價p

17、, 等價于 p = (int *)malloc(sizeof(int);/ q = 5;/error! q指針/ *q = 5;/error! p = 5 *q = 5;/OK! 等價于 *p = 5int main(void) int * p;f(&p);/只有調用變量的地址,才能改變變量的值printf("%dn", *p); /f函數中,沒有free(q);所以動態空間仍然保留,動態空間中的內容可以被訪問return 0;/*-在VC+6.0輸出結果:5*/枚舉什么是枚舉把一個事物所以可能的取值一一列舉出來/*日期:2011-05-04目的:枚舉*/#incl

18、ude <stdio.h>/自定義了一個數據類型,并沒有定義變量,該數據類型的名字 enum WeekDayenum WeekDay/MonDay, TuesDay, WednesDay, ThursDay, FriDay, SaturdDay, Sunday MonDay=10, TuesDay, WednesDay, ThursDay, FriDay, SaturdDay, Sunday;/分號int main(void)/int day;/day定義成int類型范圍太大不合適,day的取值只可能有7個(0-6),浪費空間enum WeekDay day = FriDay; /

19、初始化一個enum WeekDay 類型變量 dayprintf("%dn", day);return 0;/*-在VC+6.0輸出結果:414*/怎么使用枚舉/*日期:2011-05-04目的:枚舉2*/#include <stdio.h>enum weekdayMonDay, TuesDay, WednesDay, ThursDay, FriDay, SaturdDay, Sunday ;void f(enum weekday i)/本函數的目的只是期望接受0-6之間的數字,將形參定義為枚舉switch (i)case 0:printf("MonD

20、ay !n");break;case 1:printf("TuesDay !n");break;case 2:printf("WednesDay !n");break;case 3:printf("ThrusDay !n");break;case 4:printf("FriDay !n");break;case 5:printf("ThursDay !n");break;case 6:printf("SunDay !n");break;int main(void)f

21、(FriDay);/雖然FriDay本質上就是5,但直接寫出f(5);就是錯的,也不可能寫成return 0;枚舉的優缺點優點:代碼更安全,比較直觀缺點:書寫麻煩位運算符約翰·馮·諾依曼(JohnVonNouma,19031957),美藉匈牙利人計算機之父:2大貢獻二進制 計算機設備分類:運算器 控制器 存儲器 輸入設備 輸出設備 什么是進制數字是本質,進制只是不同表現方式一個十六進制位,要用4個二進制數表示,(1)16 = (0001)2 前面補齊二進制逢 二進一十進制 逢 十進一 dec八進制 逢 八進一 oct0數字int i = 05;十六進制 逢 十六進一 hex

22、0x數字 0X數字 int i = 0x5;int i = 0X5;生活中:七進制 七天進周 十二進制 十二月進年二十四進制 二十四小時進日六十進制六十分鐘進小時六十秒鐘進分鐘匯編里1101B 二進制1357O 八進制2049D 十進制3FB9H 十六進制十進制(D)二進制(B)八進制(O)十六進制(H)000011112102231133410044510155611066711177810001089100111910101012a (A)11101113b (B)12110014c (C)13110115d (D)14111016e (E)15111117f (F)16100002010

23、017 = 7 + 1*8 = 150x17 = 7 + 1*16 = 251234 = 4 + 1*10三次方 + 2*10二次方 + 3*10一次方 0x32c = c + 3*16二次方 + 2*16一次方 = 4354最高冪數是位數-1#include<stdio.h>int main(void)int i = 0x32c;printf("i = %dn", i);printf("i = %xn", i);printf("i = %on", i);/*printf的用法%d 以十進制輸出%x 或 %X 以十六進制輸

24、出%o 或 %O 以八進制輸出 */return 0;#include <stdio.h>int main(void)int i = 1000;print("%Xn", i) /3E8printf("%#Xn",i) /OX3E8 %#X 推薦return 0;補碼:原碼:也叫符號絕對值 最高位0表示正 1表示負,其余二進制位是該數字的絕對值的二進制位在計算機中,從未被使用!反碼反碼運行不便,也沒有在計算機中應用-移碼表示數值平移n位,n稱為移碼量移碼主要用于浮點數的階碼的存儲-補碼地址是內存單元編號 0到4G-1 2的32次方-1 總線32

25、位,32個0,1主要解決整數的存儲 int 4字節 32位個0,1已知十進制求二進制求正整數的二進制除2取余,直到商為零,余數倒序排列求負整數的二進制 先求出與該負數相對應的正整數的二進制代碼,然后,將所有位取反,末尾加1,不夠位數時,左邊補一-5 5 101 010 011 29個1,0114字節 int(-3) 011 100 101 補29個1,1012字節short int(-3)101 補13個1 101(-100) 16進制 64(16進制) 0110,0100 反 1001,1011 +1 1001,1100 FFFFFF9C 8位求零的二進制全是零已知二進制求十進制 如果首位是

26、0,則表明是正整數,按普通方法來求如果首位是1,則表明是負整數,將所有位取反,末尾加1,所得數字就是該負數的絕對值如果全是零,則對應的十進制數字就是零 學習目標:在在VC+6.0中一個int類型變量所能存儲的數字的范圍是多少(32位系統,32個0,1組合表示的內存單元,8個十六進制數組合)int類型變量所能存儲的最大正數用十六進制表示: 7FFFFFFFint類型變量所能存儲的絕對值最大負整數用十六進制表示: 80000000最小負數的二進制代碼是多少1(0-0 31個0)最大正數的二進制代碼是多少0(1-1 31個1)已知一個整數的二進制代碼求原始的數字 按“已知二進制求十進制”求數字超過最

27、大正數會怎樣變成負數 0111 1111=127 1000 0000 -128不同數據類型轉化丟失最高位.只截取2個數據類型中,所占字節小的位數的值鏈表C語言和數據結構的連接 鏈表是數據結構第一部分算法:通俗定義:解題的方法和步驟狹義定義:對存儲數據的操作對不同的存儲結構,要完成某一個功能所執行的操作是不一樣的。比如:要輸出數組中所有的元素的操作 和要輸出鏈表中所有的元素的操作 是不一樣的這說明:算法是依附于存儲結構的不同的存儲結構,所執行的算法是不一樣的廣義定義:廣義的算法也叫泛型 C+無論數據是如何存儲的,對該數據的操作都是一樣的分層思想,站在更高的層次看,把內部的實現給屏蔽數組和鏈表都是

28、線性的,都是輸出一個元素后,再輸出下一個元素我們至少可以通過兩種結構來存儲數據數組優點:存取速度快缺點:需要一整塊連續的空間插入和刪除元素效率很低鏈表優點:插入刪除元素效率高缺點:查找某個位置的元素效率低鏈表專業術語:首結點:存放第一個有效數據的結點尾結點:存放最后一個有效數據的結點,指針域的指針為NULL,尾結點的標志頭結點:頭結點的數據類型和首結點的類型是一模一樣的頭結點是首結點前面的那個節點頭結點并不存在有效數據設置頭結點的目的是為了方便對鏈表的操作頭指針:存放頭結點地址的指針變量確定一個鏈表需要一個參數,頭指針專題:字符串的處理& 按位與 -每一位都按位與 (區別&j取

29、地址) 1&1 = 11&0 = 0 0&0 = 0 0&1 = 0| 按位或 -每一位都按位與 取反 -每一位取反 按位異或 -相同為零 不同為1 10=1 01=1 11=0 00=0<< 按位左移 -左移n位相當于乘以2的n次方i<<3 表示把i的所有二進制位左移動3位,右邊補零面試題:A) i = i*8;B) i = i<<3;請問上述兩個語句,哪個語句執行的速度快答案:B快乘法在運算器里,運行原理比較復雜按位左移,簡單!>> 按位右移 -右移n位相當于除以2的n次方,首位為0補0,首位是1補1i>

30、>3 表示把i的所有二進制位右移動3位,左邊補零防止過度右移,容易喪失精度和意義位運算的現實意義:通過位運算符,我們可以對數據的操作精確到每一位。NULL二進制全部為零的含義: -0000000000 的含義1.數值零2.字符串結束標記 '0'3.空指針NULL NULL表示零,而這個零不代表數字零,而表示的內存單元的編號零我們計算機規定了,以零為編號的存儲單元的內容不可讀,不可寫free(p);p = NULL;*q = 0; 錯!把0號單元改寫!0單元是非常重要的數據。程序員不可能讀寫出0號單元信息純C的知識文件不是用'流'的思想,用函數實現,于jav

31、a C+沒聯系宏typedef期末考試1.什么叫分配內存,什么叫釋放內存分配內存:操作系統把某一塊內存空間的使用權力分配給該程序內存釋放:操作系統把分配給該程序的內存空間的使用權力收回, 該程序就不能使用這塊內存空間附注:釋放內存不是把該內存的數據清零2.變量為什么必須初始化不初始化,變量通常是垃圾值,很可能是上次程序結束遺留下來的數據。3.詳細說明系統如何執行:int i = 5; 這條語句的1> Vc+6.0軟件請求操作系統為i分配存儲空間2> 操作系統會在內存中尋找一塊空閑的區域,把該區域當作i來使用3> Vc+6.0會把i和這塊空間區域關聯起來,今后對字母i操作就是對

32、這塊空閑的區域操作。4> 把5存儲到字母i所關聯的內存區域中附注:所謂內存區域也就是內存的一塊存儲單元4.詳細列出C語言所有基本類型intlong intshort intcharfloat double5.在printf函數中,int用%d輸出,請問:long intchardouble float分別用什么輸出?%ld %c %lf%f6.函數的優點1>避免重復操作2>有利于程序的模塊化7.談談你對函數的理解. .8.什么是指針,什么是地址,什么是指針變量,三者之間的關系? 地址是內存單元的編號 指針就是地址 指針和地址是同一個概念指針變量是存放內存單元編號的變量指針變量

33、和指針是兩個完全不同的概念,只不過人們通常把指針變量稱作指針9.請寫出靜態變量和動態變量的異同相同點:都需要分配內存不同點:靜態變量是由系統自動分配,自動釋放,程序員無法在程序運行的過程當中手動分配,也無法在程序運行的過程中手動釋放。靜態變量是在棧中分配的,只有在函數終止之后,靜態變量的存儲空間會被系統自動釋放。動態內存是由程序員手動分配,程序員可以在程序運行的過程當中手動分配,手動釋放。動態變量是在堆中分配的,程序員可以在行是執行過程中的任何時刻手動釋放動態變量的空間不需要等到函數終止才釋放。10.C語言中哪些知識點是我們學習的重點,請一一列舉出來流程控制 函數 指針 靜態內存和動態內存 1

34、1.for(1;2;3)A;B;1> 2成立,會繼續執行哪條語句:A2> 3執行完畢后,會繼續執行哪條語句: 23> A執行完畢后,會繼續執行哪個語句:34> 1總共會執行幾次:1次12.for(1;2;3)for(4;5;6)A;B;C;1> 6執行完畢后,會繼續執行哪個語句:52> 5成立,會繼續執行哪個語句:A3> 5不成立,會繼續執行哪個語句:34> 2不成立,會繼續執行哪個語句:C5> 2成立,會繼續執行哪個語句:46> A 和 B語句是否一定會被執行 不會 (2或5不成)7> C語句是否一定會執行 是13.for(1

35、;2;3)while(4)5;6;break;if(7) 8; 9;10;1> 5執行完畢后,會繼續執行哪個語句:42> break終止什么? 終止for, break終止最里層包裹它的循環3> 如果8是break語句,則8執行完畢之后會繼續執行哪個語句 104> 如果7不成立,會繼續執行哪條語句 9方法:調整清楚for(1;2;3)while(4)5;6;break;if(7)8; 9;10;14 判斷下列程序語法上是否有錯誤,說出錯誤原因 A) int *p; *p = 10; 錯 p沒有指向,*p數據不可讀和操作B) char *p; char ch=A; p=&

36、amp;ch; 錯 A改成'A' A非法無意義C) int i,j; i=j=0; int *p; p=&i;對 i=j=0; 從右向左D) int *p; int *q; q = &p; 對 指針的指針是int * 類型E) int *p; int i=5; p=&i; *p=10;對 p指向i,*p=5;把10賦值給*p15 編程實現:如果x大于0,則y為1.如果x小于0,則y為-1,如果x等于0,則y為0,以下程序段中,不能根據x值正確計算出y值的是 CDA)if(x>0) y=1; else if(x=0) y=0; else y=-1;B

37、) y=0;if(x>0) y=1;else if(x<0) y=-1;C) y=0;if(x>=0);(;空語句)if(x>0) y=1;D) if(x>=0)if(x>0) y=1;else y=0;16.若變量已正確定義,有以下程序段int a=3, b=5, c=7;if (a>b)a=b;c=a;if(c!=a)c=b;printf("%d, %d, %dn", a, b, c);輸出結果是:BA)程序段有語法錯誤B)3,5,3C)3,5,5D) 3,5,717.執行以下程序后,輸出'#'的個數是:6#include <stdio.h>int main(void)int i,j;for(i=1; i<5;i+)for(j=2; j<=i; j+)printf("%cn",'#');return 0;18.有以下程序#include <stdio.h>int main(void) int i,s=0;for(i=1; i<10; i+=2)s+=i+1; /s = s + (i

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論