<pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

          <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

          <p id="bbfd9"></p>

          <p id="bbfd9"><cite id="bbfd9"></cite></p>

            <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

            <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
            <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
            C語言

            C語言中的幾個重要概念

            時間:2025-04-28 00:53:32 C語言 我要投稿
            • 相關推薦

            C語言中的幾個重要概念

              學習是一個循序漸進的過程,需要同學們不斷的學習和努力。C語言中的幾個重要概念就為大家分享這里了,希望能幫助大家更好的復習所學的知識。

              一、C語言的指針

              1.指針說明

              指針是包含另一變量的地址變量。

              (1)int *p

              p是一個指針,指向一個整形數。

              (2)int *p()

              p是一個函數,該函數返回一個指向整數的指針。

              (3)int (*p)()

              p是一個指針,該指針指向一個函數,這個函數返回一個整數。

              (4)int *p[]

              p是一個數組,該數組的每一個元素是指向整數的指針。

              (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 ,因為遠指針增減運算時,段地址不參與運算。在緊湊、大和巨模式下編譯產生的數據指針是遠指針(缺省狀態)。

              (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)傳址方式

              ①傳給被調用函數的是變量的地址。被調用函數得定義指針變量為形參。

              ②傳給被調用函數的是數組的地址即數組名。被調用的函數得定義數組或指針變量為形參。

              ③傳給被調用函數的是函數的地址即函數名稱。被調用函數得定義指向函數的指針變量為形參。

              ④傳給被調用函數的是結構的地址。被調用函數得定義結構指針為形參。

              3.函數調用(傳值方式)結果的返回

              (1)返回的是數值

              要求被調用的函數類型與接收返回值的變量類型相同。

              (2)返回的是指針

              要求被調用的函數是指針函數,其指向的類型與接收的指針變量指向類型相同。

              (3)不返回任何值

              被調用的函數是void型。

              三、C 語言的信息壓縮法

              1.使用位運算符

              要把 5個數據的值壓縮到一個字(16位)中,假定其中三個(f1、f2、f3)是標記(真或偽)各占一位;第四個是叫type的整數,其取值范圍為 1到12,需要 4位的存儲器;最后一個叫作index 的整數,其取值范圍為從 0到 500,需占 9位。為此定義一個整型變量:unsigned int packed_data,可包含此 5個值。下圖是位域分配。

              type    index

              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_data.type=n;

              (4)從packed_data 中提取type域(按要求,把它移到低位),并把它賦予 n,用語句

              n=packed_data.type;

              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的值賦給eq.equi,就可以從eq.beq.boot得到PC機有無系統盤的信息;從eq.beq.copr得到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 示意圖

              struct     struct

              WORDREGS    BYTEREGS

              ┌  ┌───────┬──────┐──┬──  ┐

              │  │       │   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.大模式編譯時段的使用情況

              靜態數據,堆,堆棧的分配與緊湊模式一樣;代碼段的分配與中模式一樣。數據指針和函數指針都是遠指針。靜態數據的總量不得超過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語言中的重要概念有哪些04-10

            C語言中指針的概念03-16

            C語言中各種類型的指針的概念02-14

            C語言中各種類型的指針的概念總結11-24

            C語言中的整數06-16

            C語言中的字符07-18

            PHP語言中Session的概念08-03

            c語言中getch的用法06-01

            C語言中assert用法02-26

                    <pre id="bbfd9"><del id="bbfd9"><dfn id="bbfd9"></dfn></del></pre>

                    <ruby id="bbfd9"></ruby><p id="bbfd9"><mark id="bbfd9"></mark></p>

                    <p id="bbfd9"></p>

                    <p id="bbfd9"><cite id="bbfd9"></cite></p>

                      <th id="bbfd9"><form id="bbfd9"><dl id="bbfd9"></dl></form></th>

                      <p id="bbfd9"><cite id="bbfd9"></cite></p><p id="bbfd9"></p>
                      <p id="bbfd9"><cite id="bbfd9"><progress id="bbfd9"></progress></cite></p>
                      飘沙影院