97骚碰,毛片大片免费看,亚洲第一天堂,99re思思,色好看在线视频播放,久久成人免费大片,国产又爽又色在线观看

c語(yǔ)言重點(diǎn)知識點(diǎn)總結

時(shí)間:2024-04-13 11:27:22 金磊 總結 我要投稿
  • 相關(guān)推薦

c語(yǔ)言重點(diǎn)知識點(diǎn)總結

  上學(xué)的時(shí)候,說(shuō)起知識點(diǎn),應該沒(méi)有人不熟悉吧?知識點(diǎn)是指某個(gè)模塊知識的重點(diǎn)、核心內容、關(guān)鍵部分。還在苦惱沒(méi)有知識點(diǎn)總結嗎?下面是小編幫大家整理的c語(yǔ)言重點(diǎn)知識點(diǎn)總結,歡迎大家分享。

c語(yǔ)言重點(diǎn)知識點(diǎn)總結

  c語(yǔ)言重點(diǎn)知識點(diǎn)總結 1

  ◆知識點(diǎn)1:交換兩個(gè)變量值的方法

  1)采用第三方變量(最容易想到的方法)

  2)采用加減法進(jìn)行值得交換(面試時(shí)常用**)

  代碼如下:

  b = a - b;

  a = a - b;

  b = a + b;

  3)采用按位異或的位方式

  代碼如下:

  a = a^b;

  b = a^b;

  a = a^b;

  ◆知識點(diǎn)2:取語(yǔ)言重點(diǎn)知識點(diǎn)總結余運算%的結果與被除的符號相同,結果為兩個(gè)正數取余后前面加符號

  ◆知識點(diǎn)3:sizeof的使用

  sizeof是一種運算符不要想當然理解為函數

  sizeof使用時(shí)可以不加()

  sizeof可以加變量、常量、數據類(lèi)型

  跟數據類(lèi)型是必須加()

  ◆知識點(diǎn)4:static和 extern區別是能否進(jìn)行跨文件訪(fǎng)問(wèn)

 、俸瘮

 、谧兞

  1、對函數的作用:

  外部函數:定義的函數能被本文件和其他文件訪(fǎng)問(wèn)

  內部函數:定義的函數只能被本文件訪(fǎng)問(wèn)

  默認情況下,所有函數都是外部函數(相當于帶關(guān)鍵字extern),所以可以省略

  extern作用:

  完整的定義和引用一個(gè)外部函數都加extern

  引用時(shí)也是默認是外部函數所以也省略extern

  static作用:定義一個(gè)內部函數

  使用:static返回類(lèi)型函數名(參數列表)

  不能被其他文件調用

  一個(gè)項目中,本文件的外部函數名不能和其他文件的外部函數同名(error)

  本文件中的.內部函數(static)可以和其他文件的函數名同名的

  2、對變量的作用:

  全局變量分為兩種:

  外部變量:定義的變量可以被其他文件訪(fǎng)問(wèn)

 、倌J情況下所有的全局變量都是外部變量

 、诓煌募械耐獠孔兞慷即硗粋(gè)

 、鄱x一個(gè)外部變量不加extern,聲明才加extern

  同樣的聲明是沒(méi)有錯誤的

  內部變量:定義的變量不能被其他文件訪(fǎng)問(wèn)

  不同文件的同名內部變量互不影響

  ◆知識點(diǎn)5:數組的幾種初始化方式如下:

  int a[3] = {10, 9, 6};

  int a[3] = {10,9};

  int a[] = {11, 7, 6};

  int a[4] = {[1]=11,[0] = 7};(知道有此種初始化方式即可)

  ◆知識點(diǎn)6:數組的內存分析和注意點(diǎn)

  存儲空間的劃分(內存的分配是從高地址到低地址進(jìn)行的,但一個(gè)數組內部元素又是從低到高進(jìn)行的)【注:對于以后學(xué)習重要】

  數組名的作用,查看元素地址

  注意數組不要越界

  ◆知識點(diǎn)7:字符串知識點(diǎn)

  "123”其實(shí)是由’1’、’2’、’3’、’’組成

  字符串的輸出”%s”,’’是不會(huì )輸出的

  ◆知識點(diǎn)8 : 字符串處理函數:strlen()

  計算的是字符數,不是字數

  計算的字符不包括’’,一個(gè)漢字相當于3個(gè)字符

  例子:"哈haha" 字符數為7

  從某個(gè)地址開(kāi)始的數字符個(gè)數,知道遇到’’為止

  指針部分在C語(yǔ)言中占據重要地位,所以重點(diǎn)學(xué)習與整理了指針的知識:

  ◆知識點(diǎn)9:指針定義的格式

  變量類(lèi)型 *變量名

  如:Int *p

  ◆知識點(diǎn)10:指針作用

  能夠根據一個(gè)地址值,訪(fǎng)問(wèn)對應的存儲空間

  例:

  Int *p;

  Int a = 90;

  P = &a;

  *p = 10;//把10賦值給p所指的存儲空間

  ◆知識點(diǎn)11:指針使用注意

  Int *p只能指向int類(lèi)型的數據

  指針變量只能存儲地址

  指針變量未經(jīng)初始化不要拿來(lái)間接訪(fǎng)問(wèn)其他存儲空間

  ◆知識點(diǎn)12:指針與數組

  遍歷數組

  int ages[5] = {10, 4, 9, 44, 99};

  for(int i = 0; i<5; i++)

  {

  printf("%d ", ages[i]);

  }

  使用指針遍歷數組:

  int *p;

  // 指針變量P指向了數組的首地址

  p = &ages[0];

  // 使用指針遍歷數組

  for(int i = 0; i<5; I++)

  {

  printf("ages[%d] = %d ", i, *(p + i));

  }

  注:指針+ 1取決于指針的類(lèi)型

  注:數組的訪(fǎng)問(wèn)方式

  數組名[下標]

  指針變量名[下標]

  *(p + i)

  ◆知識點(diǎn)12:指針與字符串

  定義字符串的兩種方式:

  1、利用數組

  Char name[] = “Andyzhao”

  特點(diǎn):字符串里的字符可以修改

  適用場(chǎng)合:字符串內容需要經(jīng)常修改

  2、利用指針

  Char *name = “itcast”

  特點(diǎn):字符串是一個(gè)常量,字符串里面的字符不能修改

  使用場(chǎng)合:字符串的內容不需要修改,而這個(gè)字符串經(jīng)常使用

  ◆知識點(diǎn)13:預處理指令(三種):

  宏定義

  條件編譯

  文件包含

  1、宏定義的配對使用和帶參數的宏:

  #define

  #undef

  帶參數的宏:

  #define sum(v1,v2) ((v1) + (v2))//括號是必須的

  例如:

  #define pingfang(a) a*a

  #define pingfang(a) (a*a)

  調用時(shí)

  pingfang(10)/pingfang(2)//不正確

  pingfang(5+5)//不正確

  帶參數的宏效率比函數高

  2、條件編譯(一般是判斷宏的值)

  #if 條件

  #elif 條件

  #else

  #endif(非常重要)不然后面的代碼全部無(wú)效

  3、文件包含:

  <>表示系統自帶的文件,""表示自定義文件

  不允許循環(huán)包含,比如ah包含bh,bh又包含ah

  ◆知識點(diǎn)14:typedef 只是給類(lèi)型起了個(gè)別名并不是定義新類(lèi)型

  struct Student{

  int age;

  char *name;

  };

  typedef struct Student Student;

  等價(jià)于

  typedef struct Student{

  int age;

  char *name;

  }Student;

  也等價(jià)于

  typedef struct {

  int age;

  char *name;

  }Student;

  類(lèi)似的給枚舉類(lèi)型起名

  typedef enum Sex

  {

  Man,Women

  }Sex;

  下面這種情況的寫(xiě)法比較特殊

  //下面是函數指針類(lèi)型的自定義數據類(lèi)型,返回值類(lèi)型和參數類(lèi)型要匹配

  #include

  typedef int (*TypeFuncPointer)(int, int);

  int add(int a, intb)

  {

  return a + b;

  }

  int minus(int a, intb)

  {

  return a - b;

  }

  int main()

  {

  TypeFuncPointer p = add;//使用自定義類(lèi)型

  TypeFuncPointer p2 = minus;//使用自定義類(lèi)型

  printf("add = %d ",p(1, 2));

  printf("minus = %d ",p2(1, 2));

  return 0;

  }

  下面是定義結構體的指針類(lèi)型

  typedef struct Student{

  int age;

  char *name;

  }*PtrStu;

  //使用方式

  Student stu ={18, "zhangsan"};

  PtrStu p = &stu;

  宏定義也是可以為類(lèi)型起名的

  #define Integer int

  相當于

  typedef int Integer

  注意和typedef的區別

  例如:

  typedef char * String

  #define String2char *

  c語(yǔ)言重點(diǎn)知識點(diǎn)總結 2

  C語(yǔ)言位運算基礎知識

  1、程序中的所有數在計算機內存中都是以二進(jìn)制的形式儲存的。位運算說(shuō)穿了,就是直接對整數在內存中的二進(jìn)制位進(jìn)行操作。

  2、與運算:只有前后兩個(gè)運算數都是 1 的時(shí)候結果才是1。

  3、或運算:有1位為1,結果便為1。

  4、異或:不相同則為1。

  5、取反運算:將1變?yōu)?,將0變?yōu)?。

  6、移位運算:左移則乘2,右移則除2。如果超出邊界,則舍棄。

  c語(yǔ)言入門(mén)知識:位運算

  一、位運算符

  在計算機中,數據都是以二進(jìn)制數形式存放的,位運算就是指對存儲單元中二進(jìn)制位的運算。C語(yǔ)言提供6種位運算符。

  二、位運算

  位運算符 & |~<< >> ∧ 按優(yōu)先級從高到低排列的順序是:

  位運算符中求反運算“~“優(yōu)先級最高,而左移和右移相同,居于第二,接下來(lái)的順序是按位與 “&“、按位異或 “∧“和按位或 “|“。順序為~ << >> & ∧ | 。

  例1:左移運算符“<<”是雙目運算符。其功能把“<< ”左邊的運算數的各二進(jìn)位全部左移若干位,由“<<”右邊的數指定移動(dòng)的位數,高位丟棄,低位補0。

  例如:

  a<<4

  指把a的各二進(jìn)位向左移動(dòng)4位。如a=00000011(十進(jìn)制3),左移4位后為00110000(十進(jìn)制48)。

  例2:右移運算符“>>”是雙目運算符。其功能是把“>> ”左邊的運算數的'各二進(jìn)位全部右移若干位,“>>”右邊的數指定移動(dòng)的位數。

  例如:

  設 a=15,a>>2

  表示把000001111右移為00000011(十進(jìn)制3)。

  應該說(shuō)明的是,對于有符號數,在右移時(shí),符號位將隨同移動(dòng)。當為正數時(shí),最高位補0,而為負數時(shí),符號位為1,最高位是補0或是補1 取決于編譯系統的規定。

  例3:設二進(jìn)制數a是00101101 ,若通過(guò)異或運算a∧b 使a的高4位取反,低4位不變,則二進(jìn)制數b是。

  解析:異或運算常用來(lái)使特定位翻轉,只要使需翻轉的位與1進(jìn)行異或操作就可以了,因為原數中值為1的位與1進(jìn)行異或運算得0 ,原數中值為0的位與1進(jìn)行異或運算結果得1。而與0進(jìn)行異或的位將保持原值。異或運算還可用來(lái)交換兩個(gè)值,不用臨時(shí)變量。

  如 int a=3 , b=4;,想將a與b的值互換,可用如下語(yǔ)句實(shí)現:

  a=a∧b;

  b=b∧a;

  a=a∧b;

  所以本題的答案為: 11110000 。

  c語(yǔ)言重點(diǎn)知識點(diǎn)總結 3

  基本問(wèn)題

  在計算機中,所有的數據都是存放在存儲器中的,不同的數據類(lèi)型占有的內存空間的大小各不相同。內存是以字節為單位的連續編址空間,每一個(gè)字節單元對應著(zhù)一個(gè)獨一的編號,這個(gè)編號被稱(chēng)為內存單元的地址。比如:int 類(lèi)型占 4 個(gè)字節,char 類(lèi)型占 1 個(gè)字節等。系統在內存中,為變量分配存儲空間的首個(gè)字節單元的地址,稱(chēng)之為該變量的地址。地址用來(lái)標識每一個(gè)存儲單元,方便用戶(hù)對存儲單元中的數據進(jìn)行正確的訪(fǎng)問(wèn)。在高級語(yǔ)言中地址形象地稱(chēng)為指針。

  地址與指針

  指針相對于一個(gè)內存單元來(lái)說(shuō),指的是單元的地址,該單元的內容里面存放的是數據。在 C 語(yǔ)言中,允許用指針變量來(lái)存放指針,因此,一個(gè)指針變量的值就是某個(gè)內存單元的地址或稱(chēng)為某內存單元的指針。

  變量及其定義

  指針變量是存放一個(gè)內存地址的變量,不同于其他類(lèi)型變量,它是專(zhuān)門(mén)用來(lái)存放內存地址的,也稱(chēng)為地址變量。定義指針變量的一般形式為:類(lèi)型說(shuō)明符*變量名。

  類(lèi)型說(shuō)明符表示指針變量所指向變量的數據類(lèi)型;*表示這是一個(gè)指針變量;變量名表示定義的指針變量名,其值是一個(gè)地址,例如:char*p1;表示 p1 是一個(gè)指針變量,它的值是某個(gè)字符變量的地址。

  1.1 指針與指針變量的概念,指針與地址運算符

  1.在C語(yǔ)言中,指針是指一個(gè)變量的`地址,通過(guò)變量的地址″指向″的位置找到變量的值,這種″指向″變量地址可形象地看作″指針″。用來(lái)存放指針的變量稱(chēng)為指針變量,它是一種特殊的變量,它存放的是地址值。

  2.定義指針變量的一般形式為:

  類(lèi)型名 *指針變量1,*指針變量2,…;

  ″類(lèi)型名″稱(chēng)為″基類(lèi)型″它規定了后面的指針變量中存放的數據類(lèi)型,″*″號表明后面的″指針變量1″,″指針變量2″等是指針變量,″*″號在定義時(shí)不能省略,否則就會(huì )變成一般變量的定義了!逯羔樧兞1″,″指針變量2″等稱(chēng)為指針變量名。

  3.一個(gè)指針變量只能指向同一類(lèi)型的變量。

  4.與指針和指針變量有關(guān)的兩個(gè)運算符:

  (1)*:指針運算符(或稱(chēng)″間接訪(fǎng)問(wèn)″運算符)

  (2)&:取地址運算符

  通過(guò)*號可以引用一個(gè)存儲單元,如有如下定義:

  int i=123,*p,k;

  則 p=&I;或k=*p;或k=*&I;都將變量i中的值賦給k。

  *p=10;或*&i=10;都能把整數10賦給變量i。這里,等號左邊的表達式*p和*&i都代表變量i的存儲單元。

  1.2 變量、數組、字符串、函數、結構體的指針以及指向它們的指針變量

  1.變量的指針和指向變量的指針變量。

  2.數組的指針和指向數組的指針變量。

  所謂數組的指針是指數組的起始地址,數組元素的指針是數組元素的地址。

  C語(yǔ)言規定數組名代表數組的首地址,也就是第一個(gè)元素的地址。

  3.字符串的指針和指向字符串的指針變量。

  我們可以通過(guò)定義說(shuō)明一個(gè)指針指向一個(gè)字符串。

  C語(yǔ)言將字符串隱含處理成一維字符數組,但數組的每個(gè)元素沒(méi)有具體的名字,這一點(diǎn)跟字符數組不一樣。要引用字符串中的某個(gè)字符,只能通過(guò)指針來(lái)引用:*(s+0),*(s+1),…,*(s+n)。

  4.函數的指針和指向函數的指針變量。

  指向函數的指針變量的一般形式為 :

  數據類(lèi)型標識符 (*指針變量名)();

  這里的″數據類(lèi)型標識符″是指函數返回值的類(lèi)型。

  函數的調用可以通過(guò)函數名調用,也可以通過(guò)函數指針調用(即用指向函數的指針變量調用)。

  指向函數的指針變量表示定義了一個(gè)指向函數的指針變量,它不是固定指向哪一個(gè)函數,而只是定義了這樣的一個(gè)類(lèi)型變量,它專(zhuān)門(mén)用來(lái)存放函數的入口地址。在程序中把哪一個(gè)函數的地址賦給它,它就指向哪一個(gè)函數。在一個(gè)程序中,一個(gè)指針變量可以先后指向不同的函數。

  在給函數指針變量賦值時(shí),只需給出函數名而不必給出參數。因為函數指針賦的值僅是函數的入口地址,而不涉及到實(shí)參與形參的結合問(wèn)題。

  對指向函數的指針變量,表達式p+n,p++,p--等都無(wú)意義。

  5.結構體的指針與指向結構體的指針變量

  一個(gè)結構體變量的指針就是該變量所占據的內存段的起始地址?梢栽O一個(gè)指針變量,用來(lái)指向一個(gè)結構體變量,此時(shí)該指針變量的值是結構體變量的起始地址。指針變量也可以用來(lái)指向結構體數組中的元素。

  1.3 用指針做函數參數

  函數的參數不僅可以是整型、實(shí)型、字符型等數據,還可以是指針類(lèi)型,它的作用是將一個(gè)變量的地址傳送到另一個(gè)函數中。

  1.4 返回指針值的指針函數

  一個(gè)函數可以返回一個(gè)整型值、字符值、實(shí)型值等,也可以返回指針型數據 ,即地址這種帶回指針值的函數,一般的定義形式為:

  類(lèi)型標識符 *函數名(形參表);

  1.5 指針數組、指向指針的指針

  1.指針數組指的是一個(gè)數組,其元素均為指針類(lèi)型數據,也就是說(shuō),指針數組中的每一個(gè)元素都是指針變量。指針數組的定義形式為:

  類(lèi)型標識 *數組名[數組長(cháng)度說(shuō)明]

  指針數組可以使字符串處理更加方便。

  2.指向指針的指針是指指向指針數據的指針變量,一個(gè)指向指針數據的指針變量的一般形式為:

  類(lèi)型標識 * *p;

  1.6 main函數的命令參數

  指針數組的一個(gè)重要應用是作為main函數的形參,一般來(lái)說(shuō),main函數后的括號中是空的,即沒(méi)有參數。實(shí)際上main可以有參數,如:

  main(argc,argv)

  其中,argc和argv就是main函數的形參。其他函數形參的值可以通過(guò)函數調用語(yǔ)句的實(shí)參中得到,由于main函數是由系統調用的,因而main函數的形參值不能從程序中得到,但可以在操作系統狀態(tài)下,將實(shí)參和命令一起給出,從而使main函數的形參得到值。命令行的一般形式為:

  命令名 參數1 參數2…參數n

  命令名和各參數之間用空格分隔開(kāi)。

  1.7 動(dòng)態(tài)存儲分配

  在C語(yǔ)言中有一種稱(chēng)為“動(dòng)態(tài)存儲分配”的內存空間分配方式:程序在執行期間需要存儲空間時(shí),通過(guò)“申請”分配指定的內存空間;當閑置不用時(shí),可隨時(shí)將其釋放,由系統另作它用。本節介紹C語(yǔ)言中動(dòng)態(tài)分配系統的主要函數:malloc()、calloc()、free()及realloc(),使用這些函數時(shí),必須在程序開(kāi)頭包含文件stdlib.h。

  1.主內存分配函數—malloc()

  函數格式:void*malloc(unsigned size);

  函數功能:從內存中分配一大小為size字節的塊。

  參數說(shuō)明:size為無(wú)符號整型,用于指定需要分配的內存空間的字節數。

  返回值:新分配內存的地址,如無(wú)足夠的內存可分配,則返回NULL。

  說(shuō)明:當size為0時(shí),返回NULL。

  2.主內存分配函數——calloc()

  函數格式:void*malloc(unsigned n,unsigned size);

  函數功能:從內存中分配n個(gè)同一類(lèi)型數據項的連續存儲空間,每個(gè)數據項的大小為size字節。

  參數說(shuō)明:n為無(wú)符號整型,用于指定分配的數據項的個(gè)數size為無(wú)符號整型,用于指定需要分配的數據項所占內存空間的字節數。

  返回值:新分配內存的地址,如無(wú)足夠的內存可分配,則返回NULL。

  3.重新分配內存空間函數——realloc()

  函數格式:void*realloc(void *block,unsigned size);

  函數功能:將block所指內存區的大小改為size字節的塊。

  參數說(shuō)明:block為void類(lèi)型的指針,指向內存中某塊,size為無(wú)符號整型,用于指定需要分配的內存空間的字節數。

  返回值:新分配內存的地址,如無(wú)足夠的內存可分配,則返回NULL。

  4.釋放內存函數—free()

  函數格式:void free(void*block);

  函數功能:將calloc()、malloc()及realloc()函數所分配的內存空間釋放為自由空間。

  參數說(shuō)明:block為void類(lèi)型的指針,指向要釋放的內存空間。

  返回值:無(wú)。

  c語(yǔ)言重點(diǎn)知識點(diǎn)總結 4

  指針簡(jiǎn)介

  指針是C語(yǔ)言中廣泛使用的一種數據類(lèi)型。運用指針編程是C語(yǔ)言最主要的風(fēng)格之一。利用指針變量可以表示各種數據結構; 能很方便地使用數組和字符串; 并能象匯編語(yǔ)言一樣處理內存地址,從而編出精練而高效的程序。指針極大地豐富了C語(yǔ)言的功能。 學(xué)習指針是學(xué)習C語(yǔ)言中最重要的一環(huán), 能否正確理解和使用指針是我們是否掌握C語(yǔ)言的一個(gè)標志。同時(shí), 指針也是C語(yǔ)言中最為困難的一部分,在學(xué)習中除了要正確理解基本概念,還必須要多編程,上機調試。只要作到這些,指針也是不難掌握的。

  指針的基本概念

  在計算機中,所有的數據都是存放在存儲器中的。 一般把存儲器中的一個(gè)字節稱(chēng)為一個(gè)內存單元, 不同的數據類(lèi)型所占用的內存單元數不等,如整型量占2個(gè)單元,字符量占1個(gè)單元等, 在第二章中已有詳細的介紹。為了正確地訪(fǎng)問(wèn)這些內存單元, 必須為每個(gè)內存單元編上號。 根據一個(gè)內存單元的編號即可準確地找到該內存單元。內存單元的編號也叫做地址。 既然根據內存單元的編號或地址就可以找到所需的內存單元,所以通常也把這個(gè)地址稱(chēng)為指針。 內存單元的指針和內存單元的內容是兩個(gè)不同的概念。 可以用一個(gè)通俗的例子來(lái)說(shuō)明它們之間的關(guān)系。我們到銀行去存取款時(shí), 銀行工作人員將根據我們的帳號去找我們的存款單, 找到之后在存單上寫(xiě)入存款、取款的金額。在這里,帳號就是存單的指針, 存款數是存單的內容。對于一個(gè)內存單元來(lái)說(shuō),單元的地址即為指針, 其中存放的數據才是該單元的內容。在C語(yǔ)言中, 允許用一個(gè)變量來(lái)存放指針,這種變量稱(chēng)為指針變量。因此, 一個(gè)指針變量的值就是某個(gè)內存單元的地址或稱(chēng)為某內存單元的指針。圖中,設有字符變量C,其內容為“K”(ASCII碼為十進(jìn)制數 75),C占用了011A號單元(地址用十六進(jìn)數表示)。設有指針變量P,內容為011A, 這種情況我們稱(chēng)為P指向變量C,或說(shuō)P是指向變量C的指針。 嚴格地說(shuō),一個(gè)指針是一個(gè)地址, 是一個(gè)常量。而一個(gè)指針變量卻可以被賦予不同的指針值,是變。 但在常把指針變量簡(jiǎn)稱(chēng)為指針。為了避免混淆,我們中約定:“指針”是指地址, 是常量,“指針變量”是指取值為地址的變量。 定義指針的目的是為了通過(guò)指針去訪(fǎng)問(wèn)內存單元。

  既然指針變量的值是一個(gè)地址, 那么這個(gè)地址不僅可以是變量的地址, 也可以是其它數據結構的地址。在一個(gè)指針變量中存放一

  個(gè)數組或一個(gè)函數的首地址有何意義呢? 因為數組或函數都是連續存放的。通過(guò)訪(fǎng)問(wèn)指針變量取得了數組或函數的首地址, 也就找到了該數組或函數。這樣一來(lái), 凡是出現數組,函數的地方都可以用一個(gè)指針變量來(lái)表示, 只要該指針變量中賦予數組或函數的首地址即可。這樣做, 將會(huì )使程序的概念十分清楚,程序本身也精練,高效。在C語(yǔ)言中, 一種數據類(lèi)型或數據結構往往都占有一組連續的內存單元。 用“地址”這個(gè)概念并不能很好地描述一種數據類(lèi)型或數據結構, 而“指針”雖然實(shí)際上也是一個(gè)地址,但它卻是一個(gè)數據結構的首地址, 它是“指向”一個(gè)數據結構的,因而概念更為清楚,表示更為明確。 這也是引入“指針”概念的一個(gè)重要原因。

  指針變量的類(lèi)型說(shuō)明

  對指針變量的類(lèi)型說(shuō)明包括三個(gè)內容:

  (1)指針類(lèi)型說(shuō)明,即定義變量為一個(gè)指針變量;

  (2)指針變量名;

  (3)變量值(指針)所指向的變量的數據類(lèi)型。

  其一般形式為: 類(lèi)型說(shuō)明符 *變量名;

  其中,*表示這是一個(gè)指針變量,變量名即為定義的指針變量名,類(lèi)型說(shuō)明符表示本指針變量所指向的變量的數據類(lèi)型。

  例如: int *p1;表示p1是一個(gè)指針變量,它的值是某個(gè)整型變量的地址。 或者說(shuō)p1指向一個(gè)整型變量。至于p1究竟指向哪一個(gè)整型變量, 應由向p1賦予的地址來(lái)決定。

  再如:

  staic int *p2; /*p2是指向靜態(tài)整型變量的指針變量*/

  float *p3; /*p3是指向浮點(diǎn)變量的指針變量*/

  char *p4; /*p4是指向字符變量的指針變量*/ 應該注意的是,一個(gè)指針變量只能指向同類(lèi)型的變量,如P3 只能指向浮點(diǎn)變量,不能時(shí)而指向一個(gè)浮點(diǎn)變量, 時(shí)而又指向一個(gè)字符變量。

  指針變量的賦值

  指針變量同普通變量一樣,使用之前不僅要定義說(shuō)明, 而且必須賦予具體的值。未經(jīng)賦值的指針變量不能使用, 否則將造成系統混亂,甚至死機。指針變量的賦值只能賦予地址, 決不能賦予任何其它數據,否則將引起錯誤。在C語(yǔ)言中, 變量的地址是由編譯系統分配的,對用戶(hù)完全透明,用戶(hù)不知道變量的具體地址。 C語(yǔ)言中提供了地址運算符&來(lái)表示變量的地址。其一般形式為: & 變量名; 如&a變示變量a的地址,&b表示變量b的地址。 變量本身必須預先說(shuō)明。設有指向整型變量的指針變量p,如要把整型變量a 的地址賦予p可以有以下兩種方式:

  (1)指針變量初始化的方法 int a;

  int *p=&a;

  (2)賦值語(yǔ)句的方法 int a;

  int *p;

  p=&a;

  不允許把一個(gè)數賦予指針變量,故下面的賦值是錯誤的: int *p;p=1000; 被賦值的指針變量前不能再加“*”說(shuō)明符,如寫(xiě)為*p=&a 也是錯誤的

  指針變量的運算

  指針變量可以進(jìn)行某些運算,但其運算的種類(lèi)是有限的。 它只能進(jìn)行賦值運算和部分算術(shù)運算及關(guān)系運算。

  1.指針運算符

  (1)取地址運算符&

  取地址運算符&是單目運算符,其結合性為自右至左,其功能是取變量的地址。在scanf函數及前面介紹指針變量賦值中,我們已經(jīng)了解并使用了&運算符。

  (2)取內容運算符*

  取內容運算符*是單目運算符,其結合性為自右至左,用來(lái)表示指針變量所指的變量。在*運算符之后跟的變量必須是指針變量。需要注意的是指針運算符*和指針變量說(shuō)明中的指針說(shuō)明符* 不是一回事。在指針變量說(shuō)明中,“*”是類(lèi)型說(shuō)明符,表示其后的變量是指針類(lèi)型。而表達式中出現的“*”則是一個(gè)運算符用以表示指針變量所指的變量。

  main(){

  int a=5,*p=&a;

  printf ("%d",*p);

  }

  ......

  表示指針變量p取得了整型變量a的地址。本語(yǔ)句表示輸出變量a的值。

  2.指針變量的運算

  (1)賦值運算

  指針變量的賦值運算有以下幾種形式:

 、僦羔樧兞砍跏蓟x值,前面已作介紹。

 、诎岩粋(gè)變量的地址賦予指向相同數據類(lèi)型的指針變量。例如:

  int a,*pa;

  pa=&a; /*把整型變量a的地址賦予整型指針變量pa*/

 、郯岩粋(gè)指針變量的值賦予指向相同類(lèi)型變量的另一個(gè)指針變量。如:

  int a,*pa=&a,*pb;

  pb=pa; /*把a的地址賦予指針變量pb*/

  由于pa,pb均為指向整型變量的指針變量,因此可以相互賦值。 ④把數組的首地址賦予指向數組的指針變量。

  例如: int a[5],*pa;

  pa=a; (數組名表示數組的首地址,故可賦予指向數組的指針變量pa)

  也可寫(xiě)為:

  pa=&a[0]; /*數組第一個(gè)元素的地址也是整個(gè)數組的首地址,也可賦予pa*/

  當然也可采取初始化賦值的方法:

  int a[5],*pa=a;

 、莅炎址氖椎刂焚x予指向字符類(lèi)型的指針變量。例如: char *pc;pc="c language";或用初始化賦值的方法寫(xiě)為: char *pc="C Language"; 這里應說(shuō)明的是并不是把整個(gè)字符串裝入指針變量, 而是把存放該字符串的字符數組的首地址裝入指針變量。 在后面還將詳細介紹。

 、薨押瘮档娜肟诘刂焚x予指向函數的指針變量。例如: int (*pf)();pf=f; /*f為函數名*/

  (2)加減算術(shù)運算

  對于指向數組的指針變量,可以加上或減去一個(gè)整數n。設pa是指向數組a的指針變量,則pa+n,pa-n,pa++,++pa,pa--,--pa 運算都是合法的。指針變量加或減一個(gè)整數n的意義是把指針指向的當前位置(指向某數組元素)向前或向后移動(dòng)n個(gè)位置。應該注意,數組指針變量向前或向后移動(dòng)一個(gè)位置和地址加1或減1 在概念上是不同的。因為數組可以有不同的類(lèi)型, 各種類(lèi)型的數組元素所占的字節長(cháng)度是不同的。如指針變量加1,即向后移動(dòng)1 個(gè)位置表示指針變量指向下一個(gè)數據元素的首地址。而不是在原地址基礎上加1。

  例如:

  int a[5],*pa;

  pa=a; /*pa指向數組a,也是指向a[0]*/

  pa=pa+2; /*pa指向a[2],即pa的值為&pa[2]*/ 指針變量的加減運算只能對數組指針變量進(jìn)行, 對指向其它類(lèi)型變量的指針變量作加減運算是毫無(wú)意義的。(3)兩個(gè)指針變量之間的運算只有指向同一數組的兩個(gè)指針變量之間才能進(jìn)行運算, 否則運算毫無(wú)意義。

 、賰芍羔樧兞肯鄿p

  兩指針變量相減所得之差是兩個(gè)指針所指數組元素之間相差的元素個(gè)數。實(shí)際上是兩個(gè)指針值(地址) 相減之差再除以該數組元素的長(cháng)度(字節數)。例如pf1和pf2 是指向同一浮點(diǎn)數組的兩個(gè)指針變量,設pf1的值為2010H,pf2的值為2000H,而浮點(diǎn)數組每個(gè)元素占4個(gè)字節,所以pf1-pf2的結果為(2000H-2010H)/4=4,表示pf1和 pf2之間相差4個(gè)元素。兩個(gè)指針變量不能進(jìn)行加法運算。 例如, pf1+pf2是什么意思呢?毫無(wú)實(shí)際意義。

 、趦芍羔樧兞窟M(jìn)行關(guān)系運算

  指向同一數組的兩指針變量進(jìn)行關(guān)系運算可表示它們所指數組元素之間的關(guān)系。例如:

  pf1==pf2表示pf1和pf2指向同一數組元素

  pf1>pf2表示pf1處于高地址位置

  pf1  main(){

  int a=10,b=20,s,t,*pa,*pb;

  pa=&a;

  pb=&b;

  s=*pa+*pb;

  t=*pa**pb;

  printf("a=%d b=%d a+b=%d a*b=%d ",a,b,a+b,a*b);

  printf("s=%d t=%d ",s,t);

  }

  ......

  說(shuō)明pa,pb為整型指針變量

  給指針變量pa賦值,pa指向變量a。

  給指針變量pb賦值,pb指向變量b。

  本行的意義是求a+b之和,(*pa就是a,*pb就是b)。

  本行是求a*b之積。

  輸出結果。

  輸出結果。

  ......

  指針變量還可以與0比較。設p為指針變量,則p==0表明p是空指針,它不指向任何變量;p!=0表示p不是空指針?罩羔樖怯蓪χ羔樧兞抠x予0值而得到的。例如: #define NULL 0 int *p=NULL; 對指針變量賦0值和不賦值是不同的。指針變量未賦值時(shí),可以是任意值,是不能使用的。否則將造成意外錯誤。而指針變量賦0值后,則可以使用,只是它不指向具體的變量而已。

  main(){

  int a,b,c,*pmax,*pmin;

  printf("input three numbers: ");

  scanf("%d%d%d",&a,&b,&c);

  if(a>b){

  pmax=&a;

  pmin=&b;}

  else{

  pmax=&b;

  pmin=&a;}

  if(c>*pmax) pmax=&c;

  if(c<*pmin) pmin=&c;

  printf("max=%d min=%d ",*pmax,*pmin);

  }

  ......

  pmax,pmin為整型指針變量。

  輸入提示。

  輸入三個(gè)數字。

  如果第一個(gè)數字大于第二個(gè)數字...

  指針變量賦值

  指針變量賦值

  指針變量賦值

  指針變量賦值

  判斷并賦值

  判斷并賦值

  輸出結果

  ......

  數組指針變量的說(shuō)明和使用

  指向數組的指針變量稱(chēng)為數組指針變量。 在討論數組指針變量的說(shuō)明和使用之前,我們先明確幾個(gè)關(guān)系。

  一個(gè)數組是由連續的一塊內存單元組成的。 數組名就是這塊連續內存單元的首地址。一個(gè)數組也是由各個(gè)數組元素(下標變量) 組成的。每個(gè)數組元素按其類(lèi)型不同占有幾個(gè)連續的內存單元。 一個(gè)數組元素的首地址也是指它所占有的幾個(gè)內存單元的首地址。 一個(gè)指針變量既可以指向一個(gè)數組,也可以指向一個(gè)數組元素, 可把數組名或第一個(gè)元素的地址賦予它。如要使指針變量指向第i號元素可以把i元素的首地址賦予它或把數組名加i賦予它。

  設有實(shí)數組a,指向a的指針變量為pa,從圖6.3中我們可以看出有以下關(guān)系:

  pa,a,&a[0]均指向同一單元,它們是數組a的首地址,也是0 號元素a[0]的首地址。pa+1,a+1,&a[1]均指向1號元素a[1]。類(lèi)推可知a+i,a+i,&a[i]

  指向i號元素a[i]。應該說(shuō)明的是pa是變量,而a,&a[i]都是常量。在編程時(shí)應予以注意。

  main(){

  int a[5],i;

  for(i=0;i<5;i++){

  a[i]=i;

  printf("a[%d]=%d ",i,a[i]);

  }

  printf(" ");

  }

  主函數

  定義一個(gè)整型數組和一個(gè)整型變量

  循環(huán)語(yǔ)句

  給數組賦值

  打印每一個(gè)數組的值

  ......

  輸出換行

  ......

  數組指針變量說(shuō)明的一般形式為:

  類(lèi)型說(shuō)明符 * 指針變量名

  其中類(lèi)型說(shuō)明符表示所指數組的類(lèi)型。 從一般形式可以看出指向數組的指針變量和指向普通變量的指針變量的說(shuō)明是相同的。

  引入指針變量后,就可以用兩種方法來(lái)訪(fǎng)問(wèn)數組元素了。

  第一種方法為下標法,即用a[i]形式訪(fǎng)問(wèn)數組元素。 在第四章中介紹數組時(shí)都是采用這種方法。

  第二種方法為指針?lè ),即采?(pa+i)形式,用間接訪(fǎng)問(wèn)的方法來(lái)訪(fǎng)問(wèn)數組元素。

  main(){

  int a[5],i,*pa;

  pa=a;

  for(i=0;i<5;i++){

  *pa=i;

  pa++;

  }

  pa=a;

  for(i=0;i<5;i++){

  printf("a[%d]=%d ",i,*pa);

  pa++;

  }

  }

  主函數

  定義整型數組和指針

  將指針pa指向數組a

  循環(huán)

  將變量i的值賦給由指針pa指向的a[]的數組單元

  將指針pa指向a[]的下一個(gè)單元

  ......

  指針pa重新取得數組a的首地址

  循環(huán)

  用數組方式輸出數組a中的所有元素

  將指針pa指向a[]的下一個(gè)單元

  ......

  ......

  下面,另舉一例,該例與上例本意相同,但是實(shí)現方式不同。

  main(){

  int a[5],i,*pa=a;

  for(i=0;i<5;){

  *pa=i;

  printf("a[%d]=%d ",i++,*pa++);

  }

  }

  主函數

  定義整型數組和指針,并使指針指向數組a

  循環(huán)

  將變量i的值賦給由指針pa指向的a[]的數組單元

  用指針輸出數組a中的所有元素,同時(shí)指針pa指向a[]的下一個(gè)單元

  ......

  ......

  數組名和數組指針變量作函數參數

  在第五章中曾經(jīng)介紹過(guò)用數組名作函數的實(shí)參和形參的問(wèn)題。在學(xué)習指針變量之后就更容易理解這個(gè)問(wèn)題了。 數組名就是數組的首地址,實(shí)參向形參傳送數組名實(shí)際上就是傳送數組的地址, 形參得到該地址后也指向同一數組。 這就好象同一件物品有兩個(gè)彼此不同的名稱(chēng)一樣。同樣,指針變量的值也是地址, 數組指針變量的值即為數組的首地址,當然也可作為函數的參數使用。

  float aver(float *pa);

  main(){

  float sco[5],av,*sp;

  int i;

  sp=sco;

  printf(" input 5 scores: ");

  for(i=0;i<5;i++) scanf("%f",&sco[i]);

  av=aver(sp);

  printf("average score is %5.2f",av);

  }

  float aver(float *pa)

  {

  int i;

  float av,s=0;

  for(i=0;i<5;i++) s=s+*pa++;

  av=s/5;

  return av;

  }

  指向多維數組的指針變量

  本小節以二維數組為例介紹多維數組的指針變量。

  一、多維數組地址的表示方法

  設有整型二維數組a[3][4]如下:

  0 1 2 3

  4 5 6 7

  8 9 10 11

  設數組a的首地址為1000,各下標變量的首地址及其值如圖所示。在第四章中介紹過(guò), C語(yǔ)言允許把一個(gè)二維數組分解為多個(gè)一維數組來(lái)處理。因此數組a可分解為三個(gè)一維數組,即a[0],a[1],a[2]。每一個(gè)一維數組又含有四個(gè)元素。例如a[0]數組,含有a[0][0],a[0][1],a[0][2],a[0][3]四個(gè)元素。 數組及數組元素的地址表示如下:a是二維數組名,也是二維數組0行的首地址,等于1000。a[0]是第一個(gè)一維數組的數組名和首地址,因此也為1000。*(a+0)或*a是與a[0]等效的, 它表示一維數組a[0]0 號元素的首地址。 也為1000。&a[0][0]是二維數組a的0行0列元素首地址,同樣是1000。因此,a,a[0],*(a+0),*a?amp;a[0][0]是相等的。同理,a+1是二維數組1行的首地址,等于1008。a[1]是第二個(gè)一維數組的數組名和首地址,因此也為1008。 &a[1][0]是二維數組a的1行0列元素地址,也是1008。因此a+1,a[1],*(a+1),&a[1][0]是等同的。 由此可得出:a+i,a[i],*(a+i),&a[i][0]是等同的。 此外,&a[i]和a[i]也是等同的。因為在二維數組中不能把&a[i]理解為元素a[i]的地址,不存在元素a[i]。

  C語(yǔ)言規定,它是一種地址計算方法,表示數組a第i行首地址。由此,我們得出:a[i],&a[i],*(a+i)和a+i也都是等同的。另外,a[0]也

  可以看成是a[0]+0是一維數組a[0]的0號元素的首地址, 而a[0]+1則是a[0]的1號元素首地址,由此可得出a[i]+j則是一維數組a[i]的j號元素首地址,它等于&a[i][j]。由a[i]=*(a+i)得a[i]+j=*(a+i)+j,由于*(a+i)+j是二維數組a的i行j列元素的首地址。該元素的值等于*(*(a+i)+j)。

  [Explain]#define PF "%d,%d,%d,%d,%d, "

  main(){

  static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

  printf(PF,a,*a,a[0],&a[0],&a[0][0]);

  printf(PF,a+1,*(a+1),a[1],&a[1],&a[1][0]);

  printf(PF,a+2,*(a+2),a[2],&a[2],&a[2][0]);

  printf("%d,%d ",a[1]+1,*(a+1)+1);

  printf("%d,%d ",*(a[1]+1),*(*(a+1)+1));

  }

  二、多維數組的指針變量

  把二維數組a 分解為一維數組a[0],a[1],a[2]之后,設p為指向二維數組的指針變量?啥x為: int (*p)[4] 它表示p是一個(gè)指針變量,它指向二維數組a 或指向第一個(gè)一維數組a[0],其值等于a,a[0],或&a[0][0]等。而p+i則指向一維數組a[i]。從前面的分析可得出*(p+i)+j是二維數組i行j 列的元素的地址,而*(*(p+i)+j)則是i行j列元素的值。

  二維數組指針變量說(shuō)明的一般形式為: 類(lèi)型說(shuō)明符 (*指針變量名)[長(cháng)度] 其中“類(lèi)型說(shuō)明符”為所指數組的數據類(lèi)型!*”表示其后的變量是指針類(lèi)型。 “長(cháng)度”表示二維數組分解為多個(gè)一維數組時(shí), 一維數組的長(cháng)度,也就是二維數組的列數。應注意“(*指針變量名)”兩邊的括號不可少,如缺少括號則表示是指針數組(本章后面介紹),意義就完全不同了。

  [Explain]main(){

  static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

  int(*p)[4];

  int i,j;

  p=a;

  for(i=0;i<3;i++)

  for(j=0;j<4;j++) printf("- ",*(*(p+i)+j));

  }

  Expain字符串指針變量的說(shuō)明和使用字符串指針變量的定義說(shuō)明與指向字符變量的指針變量說(shuō)明是相同的。只能按對指針變量的賦值不同來(lái)區別。 對指向字符變量的指針變量應賦予該字符變量的地址。如: char c,*p=&c;表示p是一個(gè)指向字符變量c的指針變量。而: char *s="C Language";則表示s是一個(gè)指向字符串的指針變量。把字符串的首地址賦予s。

  請看下面一例。

  main(){

  char *ps;

  ps="C Language";

  printf("%s",ps);

  }

  運行結果為:

  C Language

  上例中,首先定義ps是一個(gè)字符指針變量, 然后把字符串的首地址賦予ps(應寫(xiě)出整個(gè)字符串,以便編譯系統把該串裝入連續的一塊內存單元),并把首地址送入ps。程序中的: char *ps;ps="C Language";等效于: char *ps="C Language";輸出字符串中n個(gè)字符后的所有字符。

  main(){

  char *ps="this is a book";

  int n=10;

  ps=ps+n;

  printf("%s ",ps);

  }

  運行結果為:

  book 在程序中對ps初始化時(shí),即把字符串首地址賦予ps,當ps= ps+10之后,ps指向字符“b”,因此輸出為"book"。

  main(){

  char st[20],*ps;

  int i;

  printf("input a string: ");

  ps=st;

  scanf("%s",ps);

  for(i=0;ps[i]!=;i++)

  if(ps[i]==k){

  printf("there is a k in the string ");

  break;

  }

  if(ps[i]==) printf("There is no k in the string ");

  }

  本例是在輸入的字符串中查找有無(wú)‘k’字符。 下面這個(gè)例子是將指針變量指向一個(gè)格式字符串,用在printf函數中,用于輸出二維數組的各種地址表示的值。但在printf語(yǔ)句中用指針變量PF代替了格式串。 這也是程序中常用的方法。

  main(){

  static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};

  char *PF;

  PF="%d,%d,%d,%d,%d ";

  printf(PF,a,*a,a[0],&a[0],&a[0][0]);

  printf(PF,a+1,*(a+1),a[1],&a[1],&a[1][0]);

  printf(PF,a+2,*(a+2),a[2],&a[2],&a[2][0]);

  printf("%d,%d ",a[1]+1,*(a+1)+1);

  printf("%d,%d ",*(a[1]+1),*(*(a+1)+1));

  }

  在下例是講解,把字符串指針作為函數參數的使用。要求把一個(gè)字符串的內容復制到另一個(gè)字符串中,并且不能使用strcpy函數。函數cprstr的形參為兩個(gè)字符指針變量。pss指向源字符串,pds指向目標字符串。表達式:

  (*pds=*pss)!=`

  cpystr(char *pss,char *pds){

  while((*pds=*pss)!=){

  pds++;

  pss++; }

  }

  main(){

  char *pa="CHINA",b[10],*pb;

  pb=b;

  cpystr(pa,pb);

  printf("string a=%s string b=%s ",pa,pb);

  }

  在上例中,程序完成了兩項工作:一是把pss指向的源字符復制到pds所指向的目標字符中,二是判斷所復制的字符是否為`,若是則表明源字符串結束,不再循環(huán)。否則,pds和pss都加1,指向下一字符。在主函數中,以指針變量pa,pb為實(shí)參,分別取得確定值后調用cprstr函數。由于采用的指針變量pa和pss,pb和pds均指向同一字符串,因此在主函數和cprstr函數中均可使用這些字符串。也可以把cprstr函數簡(jiǎn)化為以下形式:

  cprstr(char *pss,char*pds)

  {while ((*pds++=*pss++)!=`);}

  即把指針的移動(dòng)和賦值合并在一個(gè)語(yǔ)句中。 進(jìn)一步分析還可發(fā)現`的ASCⅡ碼為0,對于while語(yǔ)句只看表達式的值為非0就循環(huán),為0則結束循環(huán),因此也可省去“!=`”這一判斷部分,而寫(xiě)為以下形式:

  cprstr (char *pss,char *pds)

  {while (*pdss++=*pss++);}

  表達式的意義可解釋為,源字符向目標字符賦值, 移動(dòng)指針,若所賦值為非0則循環(huán),否則結束循環(huán)。這樣使程序更加簡(jiǎn)潔。簡(jiǎn)化后的程序如下所示。

  cpystr(char *pss,char *pds){

  while(*pds++=*pss++);

  }

  main(){

  char *pa="CHINA",b[10],*pb;

  pb=b;

  cpystr(pa,pb);

  printf("string a=%s string b=%s ",pa,pb);

  }

  使用字符串指針變量與字符數組的區別

  用字符數組和字符指針變量都可實(shí)現字符串的存儲和運算。 但是兩者是有區別的。在使用時(shí)應注意以下幾個(gè)問(wèn)題:

  1. 字符串指針變量本身是一個(gè)變量,用于存放字符串的首地址。而字符串本身是存放在以該首地址為首的一塊連續的內存空間中并以‘’作為串的結束。字符數組是由于若干個(gè)數組元素組成的,它可用來(lái)存放整個(gè)字符串。

  2. 對字符數組作初始化賦值,必須采用外部類(lèi)型或靜態(tài)類(lèi)型,如: static char st[]={“C Language”};而對字符串指針變量則無(wú)此限制,如: char *ps="C Language";

  3. 對字符串指針?lè )绞?char *ps="C Language";可以寫(xiě)為: char *ps; ps="C Language";而對數組方式:

  static char st[]={"C Language"};

  不能寫(xiě)為:

  char st[20];st={"C Language"};

  而只能對字符數組的各元素逐個(gè)賦值。

  從以上幾點(diǎn)可以看出字符串指針變量與字符數組在使用時(shí)的區別,同時(shí)也可看出使用指針變量更加方便。前面說(shuō)過(guò),當一個(gè)指針變量在未取得確定地址前使用是危險的,容易引起錯誤。但是對指針變量直接賦值是可以的。因為C系統對指針變量賦值時(shí)要給以確定的地址。因此,char *ps="C Langage";

  或者 char *ps;

  ps="C Language";都是合法的。

  函數指針變量

  在C語(yǔ)言中規定,一個(gè)函數總是占用一段連續的內存區, 而函數名就是該函數所占內存區的首地址。 我們可以把函數的這個(gè)首地址(或稱(chēng)入口地址)賦予一個(gè)指針變量, 使該指針變量指向該函數。然后通過(guò)指針變量就可以找到并調用這個(gè)函數。 我們把這種指向函數的指針變量稱(chēng)為“函數指針變量”。

  函數指針變量定義的一般形式為:

  類(lèi)型說(shuō)明符 (*指針變量名)();

  其中“類(lèi)型說(shuō)明符”表示被指函數的返回值的類(lèi)型!(* 指針變量名)”表示“*”后面的變量是定義的指針變量。 最后的空括號表示指針變量所指的是一個(gè)函數。

  例如: int (*pf)();

  表示pf是一個(gè)指向函數入口的指針變量,該函數的返回值(函數值)是整型。

  下面通過(guò)例子來(lái)說(shuō)明用指針形式實(shí)現對函數調用的方法。

  int max(int a,int b){

  if(a>b)return a;

  else return b;

  }

  main(){

  int max(int a,int b);

  int(*pmax)();

  int x,y,z;

  pmax=max;

  printf("input two numbers: ");

  scanf("%d%d",&x,&y);

  z=(*pmax)(x,y);

  printf("maxmum=%d",z);

  }

  從上述程序可以看出用,函數指針變量形式調用函數的步驟如下:1. 先定義函數指針變量,如后一程序中第9行 int (*pmax)();定義pmax為函數指針變量。

  2. 把被調函數的入口地址(函數名)賦予該函數指針變量,如程序中第11行 pmax=max;

  3. 用函數指針變量形式調用函數,如程序第14行 z=(*pmax)(x,y); 調用函數的一般形式為: (*指針變量名) (實(shí)參表)使用函數指針變量還應注意以下兩點(diǎn):

  a. 函數指針變量不能進(jìn)行算術(shù)運算,這是與數組指針變量不同的。數組指針變量加減一個(gè)整數可使指針移動(dòng)指向后面或前面的數組元素,而函數指針的移動(dòng)是毫無(wú)意義的。

  b. 函數調用中"(*指針變量名)"的兩邊的括號不可少,其中的*不應該理解為求值運算,在此處它只是一種表示符號。

  指針型函數

  前面我們介紹過(guò),所謂函數類(lèi)型是指函數返回值的類(lèi)型。 在C語(yǔ)言中允許一個(gè)函數的返回值是一個(gè)指針(即地址), 這種返回指針值的函數稱(chēng)為指針型函數。

  定義指針型函數的一般形式為:

  類(lèi)型說(shuō)明符 *函數名(形參表)

  {

  …… /*函數體*/

  }

  其中函數名之前加了“*”號表明這是一個(gè)指針型函數,即返回值是一個(gè)指針。類(lèi)型說(shuō)明符表示了返回的指針值所指向的數據類(lèi)型。

  如:

  int *ap(int x,int y)

  {

  ...... /*函數體*/

  }

  表示ap是一個(gè)返回指針值的指針型函數, 它返回的指針指向一個(gè)整型變量。下例中定義了一個(gè)指針型函數 day-name,它的返回值指向一個(gè)字符串。該函數中定義了一個(gè)靜態(tài)指針數組name。name 數組初始化賦值為八個(gè)字符串,分別表示各個(gè)星期名及出錯提示。形參n表示與星期名所對應的整數。在主函數中, 把輸入的整數i作為實(shí)參, 在printf語(yǔ)句中調用day-name函數并把i值傳送給形參 n。day-name函數中的return語(yǔ)句包含一個(gè)條件表達式, n 值若大于7或小于1則把name[0] 指針?lè )祷刂骱瘮递敵龀鲥e提示字符串“Illegal day”。否則返回主函數輸出對應的星期名。主函數中的第7行是個(gè)條件語(yǔ)句,其語(yǔ)義是,如輸入為負數(i<0)則中止程序運行退出程序。exit是一個(gè)庫函數,exit(1)表示發(fā)生錯誤后退出程序, exit(0)表示正常退出。

  應該特別注意的是函數指針變量和指針型函數這兩者在寫(xiě)法和意義上的區別。如int(*p)()和int *p()是兩個(gè)完全不同的量。int(*p)()是一個(gè)變量說(shuō)明,說(shuō)明p 是一個(gè)指向函數入口的指針變量,該函數的返回值是整型量,(*p)的兩邊的括號不能少。int *p() 則不是變量說(shuō)明而是函數說(shuō)明,說(shuō)明p是一個(gè)指針型函數,其返回值是一個(gè)指向整型量的指針,*p兩邊沒(méi)有括號。作為函數說(shuō)明, 在括號內最好寫(xiě)入形式參數,這樣便于與變量說(shuō)明區別。 對于指針型函數定義,int *p()只是函數頭部分,一般還應該有函數體部分。

  main(){

  int i;

  char *day-name(int n);

  printf("input Day No: ");

  scanf("%d",&i);

  if(i<0) exit(1);

  printf("Day No:--->%s ",i,day-name(i));

  }

  char *day-name(int n){

  static char *name[]={ "Illegal day","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

  return((n<1||n>7) ? name[0] : name[n]);

  }

  本程序是通過(guò)指針函數,輸入一個(gè)1~7之間的整數, 輸出對應的星期名。指針數組的說(shuō)明與使用一個(gè)數組的元素值為指針則是指針數組。 指針數組是一組有序的指針的'集合。 指針數組的所有元素都必須是具有相同存儲類(lèi)型和指向相同數據類(lèi)型的指針變量。

  指針數組說(shuō)明的一般形式為: 類(lèi)型說(shuō)明符*數組名[數組長(cháng)度]

  其中類(lèi)型說(shuō)明符為指針值所指向的變量的類(lèi)型。例如: int *pa[3] 表示pa是一個(gè)指針數組,它有三個(gè)數組元素, 每個(gè)元素值都是一個(gè)指針,指向整型變量。通?捎靡粋(gè)指針數組來(lái)指向一個(gè)二維數組。 指針數組中的每個(gè)元素被賦予二維數組每一行的首地址, 因此也可理解為指向一個(gè)一維數組。圖6—6表示了這種關(guān)系。

  int a[3][3]={1,2,3,4,5,6,7,8,9};

  int *pa[3]={a[0],a[1],a[2]};

  int *p=a[0];

  main(){

  int i;

  for(i=0;i<3;i++)

  printf("%d,%d,%d ",a[i][2-i],*a[i],*(*(a+i)+i));

  for(i=0;i<3;i++)

  printf("%d,%d,%d ",*pa[i],p[i],*(p+i));

  }

  本例程序中,pa是一個(gè)指針數組,三個(gè)元素分別指向二維數組a的各行。然后用循環(huán)語(yǔ)句輸出指定的數組元素。其中*a[i]表示i行0列元素值;*(*(a+i)+i)表示i行i列的元素值;*pa[i]表示i行0列元素值;由于p與a[0]相同,故p[i]表示0行i列的值;*(p+i)表示0行i列的值。讀者可仔細領(lǐng)會(huì )元素值的各種不同的表示方法。 應該注意指針數組和二維數組指針變量的區別。 這兩者雖然都可用來(lái)表示二維數組,但是其表示方法和意義是不同的。

  二維數組指針變量是單個(gè)的變量,其一般形式中"(*指針變量名)"兩邊的括號不可少。而指針數組類(lèi)型表示的是多個(gè)指針( 一組有序指針)在一般形式中"*指針數組名"兩邊不能有括號。例如: int (*p)[3];表示一個(gè)指向二維數組的指針變量。該二維數組的列數為3或分解為一維數組的長(cháng)度為3。 int *p[3] 表示p是一個(gè)指針數組,有三個(gè)下標變量p[0],p[1],p[2]均為指針變量。

  指針數組也常用來(lái)表示一組字符串, 這時(shí)指針數組的每個(gè)元素被賦予一個(gè)字符串的首地址。 指向字符串的指針數組的初始化更為簡(jiǎn)單。例如在例6.20中即采用指針數組來(lái)表示一組字符串。 其初始化賦值為:

  char *name[]={"Illagal day","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

  完成這個(gè)初始化賦值之后,name[0]即指向字符串"Illegal day",name[1]指?quot;Monday"......。

  指針數組也可以用作函數參數。在本例主函數中,定義了一個(gè)指針數組name,并對name 作了初始化賦值。其每個(gè)元素都指向一個(gè)字符串。然后又以name 作為實(shí)參調用指針型函數day name,在調用時(shí)把數組名 name 賦予形參變量name,輸入的整數i作為第二個(gè)實(shí)參賦予形參n。在day name函數中定義了兩個(gè)指針變量pp1和pp2,pp1被賦予name[0]的值(即*name),pp2被賦予name[n]的值即*(name+ n)。由條件表達式?jīng)Q定返回pp1或pp2指針給主函數中的指針變量ps。最后輸出i和ps的值。

  指針數組作指針型函數的參數

  main(){

  static char *name[]={ "Illegal day","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};

  char *ps;

  int i;

  char *day name(char *name[],int n);

  printf("input Day No: ");

  scanf("%d",&i);

  if(i<0) exit(1);

  ps=day name(name,i);

  printf("Day No:--->%s ",i,ps);

  }

  char *day name(char *name[],int n)

  {

  char *pp1,*pp2;

  pp1=*name;

  pp2=*(name+n);

  return((n<1||n>7)? pp1:pp2);

  }

  下例要求輸入5個(gè)國名并按字母順序排列后輸出。在以前的例子中采用了普通的排序方法, 逐個(gè)比較之后交換字符串的位置。交換字符串的物理位置是通過(guò)字符串復制函數完成的。 反復的交換將使程序執行的速度很慢,同時(shí)由于各字符串(國名) 的長(cháng)度不同,又增加了存儲管理的負擔。 用指針數組能很好地解決這些問(wèn)題。把所有的字符串存放在一個(gè)數組中, 把這些字符數組的首地址放在一個(gè)指針數組中,當需要交換兩個(gè)字符串時(shí), 只須交換指針數組相應兩元素的內容(地址)即可,而不必交換字符串本身。程序中定義了兩個(gè)函數,一個(gè)名為sort完成排序, 其形參為指

  針數組name,即為待排序的各字符串數組的指針。形參n為字符串的個(gè)數。另一個(gè)函數名為print,用于排序后字符串的輸出,其形參與sort的形參相同。主函數main中,定義了指針數組name 并作了初始化賦值。然后分別調用sort函數和print函數完成排序和輸出。值得說(shuō)明的是在sort函數中,對兩個(gè)字符串比較,采用了strcmp 函數,strcmp函數允許參與比較的串以指針?lè )绞匠霈F。name[k]和name[ j]均為指針,因此是合法的。字符串比較后需要交換時(shí), 只交換指針數組元素的值,而不交換具體的字符串, 這樣將大大減少時(shí)間的開(kāi)銷(xiāo),提高了運行效率。

  現編程如下:

  #include"string.h"

  main(){

  void sort(char *name[],int n);

  void print(char *name[],int n);

  static char *name[]={ "CHINA","AMERICA","AUSTRALIA","FRANCE","GERMAN"};

  int n=5;

  sort(name,n);

  print(name,n);

  }

  void sort(char *name[],int n){

  char *pt;

  int i,j,k;

  for(i=0;i  k=i;

  for(j=i+1;j  if(strcmp(name[k],name[j])>0) k=j;

  if(k!=i){

  pt=name[i];

  name[i]=name[k];

  name[k]=pt;

  }

  }

  }

  void print(char *name[],int n){

  int i;

  for (i=0;i  }

  main函數的參數

  前面介紹的main函數都是不帶參數的。因此main 后的括號都是空括號。實(shí)際上,main函數可以帶參數,這個(gè)參數可以認為是 main函數的形式參數。C語(yǔ)言規定main函數的參數只能有兩個(gè), 習慣上這兩個(gè)參數寫(xiě)為argc和argv。因此,main函數的函數頭可寫(xiě)為: main (argc,argv)C語(yǔ)言還規定argc(第一個(gè)形參)必須是整型變量,argv( 第二個(gè)形參)必須是指向字符串的指針數組。加上形參說(shuō)明后,main函數的函數頭應寫(xiě)為:

  main (argc,argv)

  int argv;

  char *argv[];或寫(xiě)成:

  main (int argc,char *argv[])

  由于main函數不能被其它函數調用, 因此不可能在程序內部取得實(shí)際值。那么,在何處把實(shí)參值賦予main函數的形參呢? 實(shí)際上,main函數的參數值是從操作系統命令行上獲得的。當我們要運行一個(gè)可執行文件時(shí),在DOS提示符下鍵入文件名,再輸入實(shí)際參數即可把這些實(shí)參傳送到main的形參中去。

  DOS提示符下命令行的一般形式為: C:>可執行文件名 參數 參數……; 但是應該特別注意的是,main 的兩個(gè)形參和命令行中的參數在

  位置上不是一一對應的。因為,main的形參只有二個(gè),而命令行中的參數個(gè)數原則上未加限制。argc參數表示了命令行中參數的個(gè)數(注意:文件名本身也算一個(gè)參數),argc的值是在輸入命令行時(shí)由系統按實(shí)際參數的個(gè)數自動(dòng)賦予的。例如有命令行為: C:>E6 24 BASIC dbase FORTRAN由于文件名E6 24本身也算一個(gè)參數,所以共有4個(gè)參數,因此argc取得的值為4。argv參數是字符串指針數組,其各元素值為命令行中各字符串(參數均按字符串處理)的首地址。 指針數組的長(cháng)度即為參數個(gè)數。數組元素初值由系統自動(dòng)賦予。其表示如圖6.8所示:

  main(int argc,char *argv){

  while(argc-->1)

  printf("%s ",*++argv);

  }

  本例是顯示命令行中輸入的參數如果上例的可執行文件名為e24.exe,存放在A(yíng)驅動(dòng)器的盤(pán)內。

  因此輸入的命令行為: C:>a:e24 BASIC dBASE FORTRAN

  則運行結果為:

  BASIC

  dBASE

  FORTRAN

  該行共有4個(gè)參數,執行main時(shí),argc的初值即為4。argv的4個(gè)元素分為4個(gè)字符串的首地址。執行while語(yǔ)句,每循環(huán)一次 argv值減1,當argv等于1時(shí)停止循環(huán),共循環(huán)三次, 因此共可輸出三個(gè)參數。在printf函數中,由于打印項*++argv是先加1再打印, 故第一次打印的是argv[1]所指的字符串BASIC。第二、 三次循環(huán)分別打印后二個(gè)字符串。而參數e24是文件名,不必輸出。

  下例的命令行中有兩個(gè)參數,第二個(gè)參數20即為輸入的n值。在程序中*++argv的值為字符串“20”,然后用函數"atoi"把它換為整型作為while語(yǔ)句中的循環(huán)控制變量,輸出20個(gè)偶數。

  #include"stdlib.h"

  main(int argc,char*argv[]){

  int a=0,n;

  n=atoi(*++argv);

  while(n--) printf("%d ",a++*2);

  }

  本程序是從0開(kāi)始輸出n個(gè)偶數。指向指針的指針變量如果一個(gè)指針變量存放的又是另一個(gè)指針變量的地址, 則稱(chēng)這個(gè)指針變量為指向指針的指針變量。

  在前面已經(jīng)介紹過(guò),通過(guò)指針訪(fǎng)問(wèn)變量稱(chēng)為間接訪(fǎng)問(wèn), 簡(jiǎn)稱(chēng)間訪(fǎng)。由于指針變量直接指向變量,所以稱(chēng)為單級間訪(fǎng)。 而如果通過(guò)指向指針的指針變量來(lái)訪(fǎng)問(wèn)變量則構成了二級或多級間訪(fǎng)。在C語(yǔ)言程序中,對間訪(fǎng)的級數并未明確限制, 但是間訪(fǎng)級數太多時(shí)不容易理解解,也容易出錯,因此,一般很少超過(guò)二級間訪(fǎng)。 指向指針的指針變量說(shuō)明的一般形式為:

  類(lèi)型說(shuō)明符** 指針變量名;

  例如: int ** pp; 表示pp是一個(gè)指針變量,它指向另一個(gè)指針變量, 而這個(gè)指針變量指向一個(gè)整型量。下面舉一個(gè)例子來(lái)說(shuō)明這種關(guān)系。

  main(){

  int x,*p,**pp;

  x=10;

  p=&x;

  pp=&p;

  printf("x=%d ",**pp);

  }

  上例程序中p 是一個(gè)指針變量,指向整型量x;pp也是一個(gè)指針變量, 它指向指針變量p。通過(guò)pp變量訪(fǎng)問(wèn)x的寫(xiě)法是**pp。程序最后輸出x的值為10。通過(guò)上例,讀者可以學(xué)習指向指針的指針變量的說(shuō)明和使用方法。

  下述程序中首先定義說(shuō)明了指針數組ps并作了初始化賦值。 又說(shuō)明了pps是一個(gè)指向指針的指針變量。在5次循環(huán)中, pps 分別取得了ps[0],ps[1],ps[2],ps[3],ps[4]的地址值(如圖6.10所示)。再通過(guò)這些地址即可找到該字符串。

  main(){

  static char *ps[]={ "BASIC","DBASE","C","FORTRAN","PASCAL"};

  char **pps;

  int i;

  for(i=0;i<5;i++){

  pps=ps+i;

  printf("%s ",*pps);

  }

  }

  本程序是用指向指針的指針變量編程,輸出多個(gè)字符串。

  本章小結

  1. 指針是C語(yǔ)言中一個(gè)重要的組成部分,使用指針編程有以下優(yōu)點(diǎn):

  (1)提高程序的編譯效率和執行速度。

  (2)通過(guò)指針可使用主調函數和被調函數之間共享變量或數據結構,便于實(shí)現雙向數據通訊。

  (3)可以實(shí)現動(dòng)態(tài)的存儲分配。

  (4)便于表示各種數據結構,編寫(xiě)高質(zhì)量的程序。

  2. 指針的運算

  (1)取地址運算符&:求變量的地址

  (2)取內容運算符*:表示指針所指的變量

  (3)賦值運算

  ·把變量地址賦予指針變量

  ·同類(lèi)型指針變量相互賦值

  ·把數組,字符串的首地址賦予指針變量

  ·把函數入口地址賦予指針變量

  (4)加減運算

  對指向數組,字符串的指針變量可以進(jìn)行加減運算,如p+n,p-n,p++,p--等。對指向同一數組的兩個(gè)指針變量可以相減。對指向其它類(lèi)型的指針變量作加減運算是無(wú)意義的。

  (5)關(guān)系運算

  指向同一數組的兩個(gè)指針變量之間可以進(jìn)行大于、小于、 等于比較運算。指針可與0比較,p==0表示p為空指針。

  3. 與指針有關(guān)的各種說(shuō)明和意義見(jiàn)下表。

  int *p; p為指向整型量的指針變量

  int *p[n]; p為指針數組,由n個(gè)指向整型量的指針元素組成。

  int (*p)[n]; p為指向整型二維數組的指針變量,二維數組的列數為n

  int *p() p為返回指針值的函數,該指針指向整型量

  int (*p)() p為指向函數的指針,該函數返回整型量

  int **p p為一個(gè)指向另一指針的指針變量,該指針指向一個(gè)整型量。

  4. 有關(guān)指針的說(shuō)明很多是由指針,數組,函數說(shuō)明組合而成的。

  但并不是可以任意組合,例如數組不能由函數組成,即數組元素不能是一個(gè)函數;函數也不能返回一個(gè)數組或返回另一個(gè)函數。例如

  int a[5]();就是錯誤的。

  5. 關(guān)于括號

  在解釋組合說(shuō)明符時(shí), 標識符右邊的方括號和圓括號優(yōu)先于標識符左邊的“*”號,而方括號和圓括號以相同的優(yōu)先級從左到右結合。但可以用圓括號改變約定的結合順序。

  6. 閱讀組合說(shuō)明符的規則是“從里向外”。

  從標識符開(kāi)始,先看它右邊有無(wú)方括號或園括號,如有則先作出解釋?zhuān)倏醋筮呌袩o(wú)*號。 如果在任何時(shí)候遇到了閉括號,則在繼續之前必須用相同的規則處理括號內的內容。例如:

  int*(*(*a)())[10]

  ↑ ↑↑↑↑↑↑

  7 6 4 2 1 3 5

  上面給出了由內向外的閱讀順序,下面來(lái)解釋它:

  (1)標識符a被說(shuō)明為;

  (2)一個(gè)指針變量,它指向;

  (3)一個(gè)函數,它返回;

  (4)一個(gè)指針,該指針指向;

  (5)一個(gè)有10個(gè)元素的數組,其類(lèi)型為;

  (6)指針型,它指向;

  (7)int型數據。

  因此a是一個(gè)函數指針變量,該函數返回的一個(gè)指針值又指向一個(gè)指針數組,該指針數組的元素指向整型量。

  基本數據類(lèi)型

  void:聲明函數無(wú)返回值或無(wú)參數,聲明無(wú)類(lèi)型指針,顯示丟棄運算結果。(C89標準新增)

  char:字符型類(lèi)型數據,屬于整型數據的一種。(K&R時(shí)期引入)

  int:整型數據,表示范圍通常為編譯器指定的內存字節長(cháng)。(K&R時(shí)期引入)

  float:?jiǎn)尉雀↑c(diǎn)型數據,屬于浮點(diǎn)數據的一種。(K&R時(shí)期引入)

  double:雙精度浮點(diǎn)型數據,屬于浮點(diǎn)數據的一種。(K&R時(shí)期引入)

  -Bool:布爾型(C99標準新增)

  -Complex:復數的基本類(lèi)型(C99標準新增)

  -Imaginary:虛數,與復數基本類(lèi)型相似,沒(méi)有實(shí)部的純虛數(C99標準新增)

  -Generic:提供重載的接口入口(C11標準新增)

  類(lèi)型修飾關(guān)鍵字

  short:修飾int,短整型數據,可省略被修飾的int。(K&R時(shí)期引入)

  long:修飾int,長(cháng)整型數據,可省略被修飾的int。(K&R時(shí)期引入)

  long long:修飾int,超長(cháng)整型數據,可省略被修飾的int。(C99標準新增)

  signed:修飾整型數據,有符號數據類(lèi)型。(C89標準新增)

  unsigned:修飾整型數據,無(wú)符號數據類(lèi)型。(K&R時(shí)期引入)

  restrict:用于限定和約束指針,并表明指針是訪(fǎng)問(wèn)一個(gè)數據對象的唯一且初始的方式。(C99標準新增)

  復雜類(lèi)型關(guān)鍵字

  struct:結構體聲明。(K&R時(shí)期引入)

  union:聯(lián)合體聲明。(K&R時(shí)期引入)

  enum:枚舉聲明。(C89標準新增)

  typedef:聲明類(lèi)型別名。(K&R時(shí)期引入)

  sizeof:得到特定類(lèi)型或特定類(lèi)型變量的大小。(K&R時(shí)期引入)

  inline:內聯(lián)函數用于取代宏定義,會(huì )在任何調用它的地方展開(kāi)。(C99標準新增)

  存儲級別關(guān)鍵字

  auto:指定為自動(dòng)變量,由編譯器自動(dòng)分配及釋放。通常在棧上分配。與static相反。當變量未指定時(shí)默認為auto。(K&R時(shí)期引入)

  static:指定為靜態(tài)變量,分配在靜態(tài)變量區,修飾函數時(shí),指定函數作用域為文件內部。(K&R時(shí)期引入)

  register:指定為寄存器變量,建議編譯器將變量存儲到寄存器中使用,也可以修飾函數形參,建議編譯器通過(guò)寄存器而不是堆棧傳遞參數。(K&R時(shí)期引入)

  extern:指定對應變量為外部變量,即標示變量或者函數的定義在別的文件中,提示編譯器遇到此變量和函數時(shí)在其他模塊中尋找其定義。(K&R時(shí)期引入)

  const:指定變量不可被當前線(xiàn)程改變(但有可能被系統或其他線(xiàn)程改變)。(C89標準新增)

  volatile:指定變量的值有可能會(huì )被系統或其他線(xiàn)程改變,強制編譯器每次從內存中取得該變量的值,阻止編譯器把該變量?jì)?yōu)化成寄存器變量。(C89標準新增)

  流程控制關(guān)鍵字

  跳轉結構

  return:用在函數體中,返回特定值(如果是void類(lèi)型,則不返回函數值)。(K&R時(shí)期引入)

  continue:結束當前循環(huán),開(kāi)始下一輪循環(huán)。(K&R時(shí)期引入)

  break:跳出當前循環(huán)或switch結構。(K&R時(shí)期引入)

  goto:無(wú)條件跳轉語(yǔ)句。(K&R時(shí)期引入)

  分支結構

  if:條件語(yǔ)句,后面不需要放分號。(K&R時(shí)期引入)

  else:條件語(yǔ)句否定分支(與if連用)。(K&R時(shí)期引入)

  switch:開(kāi)關(guān)語(yǔ)句(多重分支語(yǔ)句)。(K&R時(shí)期引入)

  case:開(kāi)關(guān)語(yǔ)句中的分支標記,與switch連用。(K&R時(shí)期引入)

  default:開(kāi)關(guān)語(yǔ)句中的“其他”分支,可選。(K&R時(shí)期引入)

  編譯

  #define 預編譯宏

  #if 表達式 #else if 表達式 #else #endif 條件編譯

  #ifdef 宏 #else #endif 條件編譯

  #ifndef 宏 #else #endif 條件編譯與條件編譯

  c語(yǔ)言知識易錯點(diǎn)

  1.書(shū)寫(xiě)標識符時(shí),忽略了大小寫(xiě)字母的區別。

  2.忽略了變量的類(lèi)型,進(jìn)行了不合法的運算。

  3.將字符常量與字符串常量混淆。

  4.忽略了“=”與“==”的區別。

  5.忘記加分號。分號是C語(yǔ)句中不可缺少的一部分,語(yǔ)句末尾必須有分號。

  6.多加分號。 復合語(yǔ)句的花括號后不應再加分號,否則將會(huì )畫(huà)蛇添足。

  7.輸入變量時(shí)忘記加地址運算符“&”。

  8.輸入數據的方式與要求不符。代碼①scanf("%d%d",&a,&b);輸入時(shí),不能用逗號作兩個(gè)數據間的分隔符②scanf("%d,%d",&a,&b);C規定:如果在“格式控制”字符串中除了格式說(shuō)明以外還有其它字符,則在輸入數據時(shí)應輸入與這些字符相同的字符。

  9.輸入字符的格式與要求不一致。在用“%c”格式輸入字符時(shí),“空格字符”和“轉義字符”都作為有效字符輸入。

  10.輸入輸出的數據類(lèi)型與所用格式說(shuō)明符不一致。

  11.輸入數據時(shí),企圖規定精度。

  12.switch語(yǔ)句中漏寫(xiě)break語(yǔ)句。

  13.忽視了while和do-while語(yǔ)句在細節上的區別。

  14.定義數組時(shí)誤用變量。

  15.在定義數組時(shí),將定義的“元素個(gè)數”誤認為是可使的最大下標值。

  16.初始化數組時(shí),未使用靜態(tài)存儲。

  17.在不應加地址運算符&的位置加了地址運算符。

  18.同時(shí)定義了形參和函數中的局部變量。

【c語(yǔ)言重點(diǎn)知識點(diǎn)總結】相關(guān)文章:

大學(xué)c語(yǔ)言知識點(diǎn)總結03-15

兒科重點(diǎn)知識點(diǎn)總結08-09

稅法重點(diǎn)知識點(diǎn)總結07-13

c語(yǔ)言學(xué)習總結通用03-03

初識c語(yǔ)言實(shí)驗總結09-30

高考地理重點(diǎn)知識點(diǎn)總結11-08

初中數學(xué)重點(diǎn)知識點(diǎn)總結10-12

春望重點(diǎn)知識點(diǎn)總結12-01

c語(yǔ)言練習試題11-14