C語言中的重要概念有哪些
學習是一個循序漸進的過程,需要同學們不斷的學習和努力。下面yjbys考試網小編為大家分享C語言中的幾個重要概念,希望能幫助大家更好的複習所學的知識。
一、C語言的指針
1.指針説明
指針是包含另一變量的地址變量。
(1)int *p
p是一個指針,指向一個整形數。
(2)int *p()
p是一個函數,該函數返回一個指向整數的指針。
(3)int (*p)()
p是一個指針,該指針指向一個函數,這個函數返回一個整數。
(4)int *p[]
p是一個數組,該數組的每一個元素是指向整數的指針C語言中的幾個重要概念C語言中的幾個重要概念。
(5)int (*p)[]
p是一個指針,該指針指向一個數組,這個數組的每一個元素是一個整數。
(6)int *(*p)()
p是一個指針,該指針指向一個函數,這個函數返回一個指向整數的指針。
2.指針的初始化(賦地址)
(1)通過符號&取變量(包括結構變量、數組第一個元素)的地址賦給指針;
(2)把數組名賦給指針;
(3)把函數名賦給指向函數的指針;
(4)動態分配內存
例:struct c{double r,i;};
struct c *p;
p=(struct c *)malloc(sizeof(struct c));
3.指針與數組、函數的關係
(1)對於一維數組 int a[i] 或指針 int *a
a+i 指向 a[i]
(2)對於字符串 char s[i] 或指針 char *s
s+i 指向第 i個字符 s[i]
(3)對於二維數組int a[i][j]
*a+j 指向 a[0][j]
*(a+i) 指向 a[i][0]
*(a+i)+j 指向 a[i][j]
例:對於 a[2][3]={1,2,3,4,5,6,}; 有 *(*(a+1)+1)=5;
(4)對於字符串數組char p[i][j] 或字符型指針數組char *p[i]
*p+j 指向第 0個字符串的第 j個字符
*(p+i) 指向第 i個字符串的第 0個字符
*(p+i)+j 指向第 i個字符串的第 j個字符
例:對於 *p[]={"ABC","DEF"}; 有 *(*(p+1)+1)='E';
例:對於 char p[][3]={"ABC","DEF"}; 有 *(*(p+1)+1)='E';
(5)對於指針數組int *a[i]
a[i] 指向 變量i
即 *a[i]=變量i 或 a[i]=&變量i
(6)對於結構struct XY
{int x;int *y}*p;
p是指向結構XY的指針
(*p).x 或 p->x 是表示 x 的內容
(*p).y 或 p->y 是表示指針 y 的值(地址)
*(*p).y 或 *p->y 是表示 y 所指的內容
&(*p).x 或 &p->x 是表示 x 的地址
(7)指向函數的指針
對於 void func(char *str)
{…}; //定義了一個函數
void (*p)(char*);//定義了一個函數指針
p=func; //讓指針指向函數
則(*p)("…"); //用指針p可以調用函數func
(8)指向多個不同函數的指針數組
對於void function_1() {…};
…
void function_4() {…}; //定義了四個函數
typedef void(*menu_fcn)();//定義了指向函數的指針
menu_fcn command[4]; //定義了指針數組
command[0]=function_1;
…
command[3]=function_4; //讓指針數組指向四個函數
則command[0](); //用指針數組中的一個元素調用一個函數
4.指針的分類
(1)近指針(near):
近指針為16位指針,它只含有地址的偏移量部分。近指針用於不超過64K 字節的單個數據段或代碼段。在微、小和中編譯模式下產生的數據指針是近指針(缺省狀態);在微、小和中編譯模式下產生的碼指針(指向函數的指針)是近指針(缺省狀態)。
(2)遠指針(far)
遠指針為32位指針,指針的段地址和偏移量都在指針內。可用於任意編譯模式。每次使用遠指針時都要重裝段寄存器。遠指針可尋址的目標不能超過64K ,因為遠指針增減運算時,段地址不參與運算。在緊湊、大和巨模式下編譯產生的數據指針是遠指針(缺省狀態)C語言中的幾個重要概念計算機考試。
(3)巨指針(huge)
巨指針為32位指針,指針的段地址和偏移量都在指針內。可用於任意編譯模式。遠指針尋址的目標可以超過64K 。巨指針是規則化的指針。
5.指針的轉換
(1)遠指針轉換成巨指針
使用以下函數
void normalize(void far * * p)
{
*p=(void far *)(((long)*p&0xffff000f)+(((long)*p&0x0000fff00<<12));
}
6.指針的使用
(1)將浮點數轉換成二進制數
float ff=16.5;
unsigned char *cc;
(float*)cc=&ff;
//此時cc的內容為"00008441"
//即cc第一個字節=0;第二個字節=0;第三個字節=0x84;第四個字節=0x41;
(2)將二進制數轉換成浮點數
float ff;
unsigned char *cc;
cc=(unsigned char*)malloc(4);
cc=(unsigned char*)&ff;
*(cc+0)=0;
*(cc+1)=0;
*(cc+2)=0x84;
*(cc+3)=0x41;
//此時ff=16.5
free(cc);
二、C 語言的函數
1.用户自定義函數格式
類型 函數名(形式參數表)
參數説明
{
……
}
2.函數的調用方式
(1)傳值方式
①傳給被調用函數的是整型、長整型、浮點型或雙精度型變量。被調用的函數得定義相應的變量為形參。
②傳給被調用函數的是結構變量。被調用函數得定義結構變量為形參。
③傳給被調用函數的是結構變量的成員。被調用函數得定義與該成員同類的變量為形參。
(2)傳址方式
①傳給被調用函數的是變量的地址C語言中的幾個重要概念C語言中的幾個重要概念。被調用函數得定義指針變量為形參。
②傳給被調用函數的是數組的地址即數組名。被調用的函數得定義數組或指針變量為形參。
③傳給被調用函數的是函數的地址即函數名稱。被調用函數得定義指向函數的指針變量為形參。
④傳給被調用函數的是結構的地址。被調用函數得定義結構指針為形參。
3.函數調用(傳值方式)結果的返回
(1)返回的是數值
要求被調用的函數類型與接收返回值的.變量類型相同。
(2)返回的是指針
要求被調用的函數是指針函數,其指向的類型與接收的指針變量指向類型相同。
(3)不返回任何值
被調用的函數是void型
三、C 語言的信息壓縮法
1.使用位運算符
要把 5個數據的值壓縮到一個字(16位)中,假定其中三個(f1、f2、f3)是標記(真或偽)各佔一位;第四個是叫type的整數,其取值範圍為 1到12,需要 4位的存儲器;最後一個叫作index 的整數,其取值範圍為從 0到 500,需佔 9位C語言中的幾個重要概念計算機考試。為此定義一個整型變量:unsigned int packed_data,可包含此 5個值。下圖是位域分配。
typeindex
f1f2f3┌──┐┌───────┐
┌┬┬┬┬┬┬┬┬┬┬┬┬┬┬┬┐
└┴┴┴┴┴┴┴┴┴┴┴┴┴┴┴┘
把 n的 4個低位的值置入packed_data 的type域中,用下面的語句:
packed_data=(packed_data & ~(0xf<<9))|((n&0xf)<<9);
其中位或符號|左邊是將type域置 0,右邊是取 n的低 4位後左移9 位到type域中。
從packed_data 的type域中提取數值並把它賦予 n的語句是:
n=(packed_data>>9) & 0xf;
2.使用位域結構
(1)定義一個叫做 packed_struct的結構,含有 5個成員
struct packed_struct
{
unsigned int f1:1
unsigned int f2:1;
unsigned int f3:1;
unsigned int type:4;
unsigned int index:9;
};
(注:在結構中還可以放入普通數據類型,如char c;等)
(2)定義一個變量
struct packed_struct packed_data;
(3)把packed_data 的type 域置於n的低位,用語句
packed_=n;
(4)從packed_data 中提取type域(按要求,把它移到低位),並把它賦予 n,用語句
n=packed_;
3.使用聯合
(1)一個無符號整型數與一個結構(其中包含許多無符號變量)共用一存儲區,當無符號整型數被賦值後,可通過結構變量獲得各位的值。
例如,定義一個聯合
union {
unsigned equi;
struct {
unsigned boot :1;
unsigned copr :1;
unsigned rsize:2;
unsigned vmode:2;
unsigned dnum :2;
unsigned:1;
unsigned cnum :3;
unsigned gnum :1;
unsigned:1;
unsigned pnum :2;
}beq;
}eq;
當調用BIOS INT 11H中斷後,將AX的值賦給,就可以從得到PC機有無系統盤的信息;從得到PC機有無浮點運算部件的信息。......
(2)兩個結構共享同一存儲區域
例如:union REGS
struct WORDREGS{unsigned int ax,bx,cx,dx,si,di,cflag,flags};
struct BYTEREGS{unsigned char al,ah,bl,bh,cl,ch,dl,dh};
union REGS {struct WORDREGS x;struct BYTEREGS h;}
四 、位運算
1.數的編碼—補碼
(1).正數的補碼與原碼同。
(2).負數的補碼為
①第一位(符號位)為 1;
②剩餘原碼位數逐位取反;
③然後對整個數加 1。
2.位邏輯運算的特殊用途
(1).取一個數中的某些字節
例a & 0x00ff得到a的低字節,a & 0xff00得到a的高字節。
┌─┬───┬────┬────────┐
│數│十進制│十六進制│補碼│
├─┼───┼────┼────────┤
│ a││0x2cac│0010110010101100│
│││0x00ff│0000000011111111│
├─┴───┼────┼────────┤
│ 按位與 │ ox00ac │0000000010101100│
│ 運算結果 │││
└─────┴────┴────────┘
(2).將一個數的某些特定位置1
例a | 0x0f使a的低4位改為1。
┌─┬───┬────┬────────┐
│數││十六進制│補碼│
├─┼───┼────┼────────┤
│a ││0x0030│0000000000110000│
│││0x000f│0000000000001111│
├─┴───┼────┼────────┤
│按位或││0000000000111111│
│運算結果│││
└─────┴────┴────────┘
(3).將某數特定位置翻轉
例a ^ 0x000f使a的低4位翻轉(0變1;1變0)。
┌─┬───┬────┬────────┐
│數││十六進制│補碼│
├─┼───┼────┼────────┤
│a ││ 0x007a │0000000001111010│
│││ 0x000f │0000000000001111│
├─┴───┼────┼────────┤
│ 按位異或 ││0000000001110101│
│ 運算結果 │││
└─────┴────┴────────┘
(4)將a的右起第2位反向變化(1變0,0變1)
a=a^0x02;//(0x02=00000010),異或的意義是"同值為0"
(5).將兩個數(整型數)的值互換
例a=a^b;b=b^a;a=a^b; //三步使得a、b的值互換
3.移位運算的特殊用途
(1).將某數除以2(右移1位)
例a>>2 使得a被4除
①對於 signed a=-8,a>>2
a=-8
┌─┬─┬─┬─┬─┬─┬─┬─┐
│1 │1 │1 │1 │1 │0 │0 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
├─┬─┐──>└───┐
┌─┬─┬─┬─┬─┬─┬─┬─┐
│1 │1 │1 │1 │1 │1 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
a=-2
②對於unsigned a=248,a>>2
a=248
┌─┬─┬─┬─┬─┬─┬─┬─┐
│1 │1 │1 │1 │1 │0 │0 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
└───┐ ──> └───┐
┌─┬─┬─┬─┬─┬─┬─┬─┐
│0 │0 │1 │1 │1 │1 │1 │0 │
└─┴─┴─┴─┴─┴─┴─┴─┘
補0──┴─┘a=62
(2).將某數乘以2(左移1位)
注左移時signed 與unsigned變量的情況一樣,均要補0。
(3)將x的右起第n(n>=0)位置0
x&=~(1《n); 若x是long,則x&=~((long)1《n);
(4)將x的右起第n(n>=0)位置1
x|=1《n;
若x是長整形數則 x|=(long)1《n;
五、C語言訪問CPU寄存器的方法
1.使用聯合REGS,和函數 int86() / int86x() / intr()
REGS是用來在進行 DOS軟中斷調用時向各個寄存器傳輸數據或從各個寄存器取出返回值。
union REGS 示意圖
structstruct
WORDREGSBYTEREGS
┌ ┌───────┬──────┐──┬── ┐
│ ││ al │ 1 byte│
│ │ax├──────┤──┴─ 2 bytes
│ ││ ah │ │
│ ├───────┼──────┤───── ┘
│ ││ bl │
│ │bx├──────┤
│ ││ bh │
│ ├───────┼──────┤
│ ││ cl │
│ │cx├──────┤
│ ││ ch │
│ ├───────┼──────┤
│ ││ dl │
│ │dx├──────┤
│ ││ dh │
union regs├───────┼──────┤
│ │││
│ │si││
│ │││
│ ├───────┤│
│ │││
│ │di││
│ │││
│ ├───────┤│
│ │││
│ │cflag ││
│ │││
│ ├───────┤│
│ │││
│ │flags ││
│ │││
└ └───────┴──────┘
│x兩個結構變量h│
└──共享同一存儲域──┘
2.使用偽變量和函數geninterrupt()
Turbo C 允許使用偽變量直接訪問相應的8086寄存器。偽變量的類型有兩種。
① unsigned int : _AX、 _BX、 _CX、 _DX、 _CS、 _DS、 _SS、 _ES、 _SP、 _BP、 _DI、 _SI
② unsigned char: _AL、 _AH、 _BL、 _BH、 _CL、 _CH、 _DL、 _DH
六、C語言使用內存和寄存器的方法
1.段和段寄存器
CS用來存放代碼段的段地址;DS用來存放全局變量和靜態變量所在段(數據段)的段地址;SS用來存放局部變量,參數所在段(堆棧)的段地址。 此外,還有堆段,是動態分配的內存。
2.微模式編譯時段的使用情況
只有一個段,從底往高依此裝入代碼,靜態變量和全局變量,堆。從高往低裝入堆棧。
3.小模式編譯時段的使用情況
數據、堆棧和近堆共用一個段,代碼用一個段,還有一個遠堆(用far指針存取)。
4.中模式編譯時段的使用情況
中模式有多個代碼段,其餘與小模式一樣。函數指針用far指針。
5.緊湊模式編譯時段的使用情況
代碼,靜態數據,堆棧,堆(只有遠堆)各有自己的段。靜態數據的總量不得超過64K
6.大模式編譯時段的使用情況
靜態數據,堆,堆棧的分配與緊湊模式一樣;代碼段的分配與中模式一樣。數據指針和函數指針都是遠指針C語言中的幾個重要概念計算機考試。靜態數據的總量不得超過64K。
7.巨模式編譯時段的使用情況
來自不同源文件的代碼放在不同的段內,來自不同源文件的靜態數據也放在不同的段內,只有堆棧是合在一起的。
8.運行庫函數分配的內存:
常規內存區
遠堆(數據段之外) 用_fmalloc()分配,得到32位指針
├─────────┤
64│堆(未使用的內存)│用malloc()分配,得到16位的位移地址
KB├─────────┤
數│棧(局部變量)│
據├─────────┤
段│全局和靜態變量│
├─────────┤
七、用C語言寫中斷服務程序(如果中斷服務程序不牽涉到中斷鏈以及 DOS和其本身的重入問題。) ---Turbo C
1.函數類型為interrupt 的中斷服務程序定義如下:
#include
void interrupt 函數名(bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags);
unsigned int bp,di,si,ds,es,dx,cx,bx,ax,ip,cs,flags;
2.得先保留原中斷函數地址
void interrupt (*保留函數名)( );
保留函數名=getvect(0x中斷號);
3.在main函數中用自定義的中斷服務程序替換原來的程序
setvect(0x中斷號,函數名);
4.在main函數中激活自定義的中斷服務程序
(1)先設置要用到的寄存器的值(用偽變量),
(2)geninterrupt(0x中斷號);
若替換的是計時中斷程序,因PC機內的計時器每秒產生18.2次中斷,則每秒自動執行18.2次新的中斷程序。
5.事後得將原中斷函數地址裝回向量表中
setvect(0x中斷號,保留函數名);
-
C語言中遞歸函數的教學方法
導語:函數遞歸基於分治法思想,將複雜的大規模問題轉化為小規模問題進行求解,在算法設計中具有重要的理論意義和實用價值,是C語言教學的難點。下面就由小編為大家介紹一下C語言中遞歸函數的教學方法,歡迎大家閲讀!1.引言C語言是一種語法簡潔緊湊、運算符豐富、可移植...
-
win8系統安裝c語言方法
在win8/win8.1中C語言VC無法運行,那麼win8系統安裝c語言方法又變成了什麼呢?而現在的'計算機都是預裝win8/8.1系統,對於比較原始的TurboC是無法運行的,現在應屆畢業生小編向大家告訴大家win8系統運行TurboC軟件的方法。win8系統安裝c語言方法:win8系統運行TurboC...
-
C語言新人常見問題與錯誤
不知不覺,學習C語言也快一年了。雖然有C語言課,但是老師完全讓我們自己看書,在自學的過程中,和周圍同學交流中,以及後來在CSDN,BCCN,百度知道看帖回帖中,也看到許多C語言新人常遇到的問題與常犯的錯誤。不妨看看吧。以下僅供參考!對於完整的修正後的程序都在code::block...
-
C語言插入排序算法及實例代碼
插入排序是排序算法的一種,下面小編為大家整理了C語言插入排序算法及實例代碼,希望能幫到大家!這裏以從小到大排序為例進行講解。基本思想及舉例説明插入排序的基本思想是,將元素逐個添加到已經排序好的數組中去,同時要求,插入的元素必須在正確的位置,這樣原來排序好...