亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

淺議C語言中數組和指針的互操作

2019-11-17 05:17:07
字體:
來源:轉載
供稿:網友

  曾聽好多朋友說,C是一種懷舊的語言,因為它的歷史很久遠,然而自從各種面向對象的編程語言的相續出現讓它的影響力日減。當然了,這是無可非議的,但是C的高效性是其他語言無妨比擬的,所以我們有必要把握其中的精華與奧妙,也就有必要知道其中的基本的數據結構的比如數組,稍微有點深度的堆棧、列表、結構體等的操作和實現。指針也是C語言中的一個很優秀靈活的結構,對它的了解也是必不可少的。

  我們一般都認為數組是一維的數據存儲結構,因為二位數組或者說矩陣都可以看作是多個一維數組的組合結構,定義在其上的數據存儲訪問方式是一樣的。所以一維數組是其中最基礎的最重要的部分,只有理解了此類數據結構的本質才能觸類旁通了。

  數組(array)是若干同類變量的聚合,答應通過統一的名字飲用其中的變量。所以數組也就是一個同一類型的數據的有限集合。可以通過下表來訪問數組中的某一/些數組元素。在C語言中數組都由連續的內存區域構成(有時候,不一定是這樣),最低地址對應首元素,數組的下標是從0開始的,所以首元素也就是數組下標為0的元素,最高的地址對應最末的元素,即第N-1個元素(假如我們定義的數組為N元)。

  數組的定義方式:

  在C語言中答應在聲明數組的時候同時對其進行初始化,也可以把聲明和定義放在不同的位置,初始化的一般的類似于如下的表達式:

  

  type_specifier array_name[size1]...[sizeN] = {value_list};

  其中vlaue_list是由逗號(,)分隔的常量表,常量表必須和type_specifier兼容。最后由分號與下一個語句分隔。由此可見一維數組的定義方式為:

  

  type_specifier array_name[size] = {value_list};

  如下:char hello[12] = {’H’,’e’,’l’,’l’,’o’,’,’,’ ’,’w’,’o’,’r’,’l’,’d’,’/0’};

  注重:字符數組是一"’/0’"收尾的,這是C標準的一部分。因為在操作字符數組的時候是以’/0’作為結束判定的標志。當然了,假如你定義的是一個字符串那就不用加這個’/0’了。因為有機制幫助你自動添加。上面的例子的串的生命方式為:string hello = "Hello, world";(當然了,具體的實現中你必須把"string.h"頭文件加入到你的文件中),或者你也可以這樣來聲明:

  

  char *hello = "Hello, world";或者char hello[] = "Hello, world"; 切換為字符指針數組,其效果是一樣的);數組初始化的時候還可 以不標明最大小,即

  char hello[] = {’H’,’e’,’l’,’l’,’o’,’,’,’ ’,’w’,’o’,’r’,’l’,’d’,’/0’};,這時候編譯器會根據后邊的賦值情況為數組分配合適的內存空間,這個你不用擔憂,除非機器正處于內存缺狀態。

  數組元素的訪問:

  可以利用循環結構來挨個訪問數組的元素,比如:

  

  [...]

  int i;

  char hello[12] = {’H’,’e’,’l’,’l’,’o’,’,’,’ ’,’w’,’o’,’r’,’l’,’d’,’/0’};

  [...]

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

  

  
  }

  printf("/n");

  [...]

  其中有一點必須注重了,那就是i的值不能取到12,因為我們的下標識從0開始的,即hello[0]是第一個元素,數組的下界,而hello[12]是第一個空元素,數組的上界。其實,數組元素的個數等于定義時的下標,也等于數組的上界(12)減去下界(0)得到的數值,還等于上界地址減去下界地址模sizeof(tyep_specifier)的值(假設數組空間是連續分布的,假如不是這樣那么這種方法也就不成立了)。
  在數組初始化的時候還答應在數組的最后加一個逗號(,),比如:

  

  int month_lengths[] = {’31’,’29’,’31’,’30’,’31’,’30’,’31’,’31’,’30’,’31’,’30’,’31’,};

  因為在分行的情況下,編譯程序是通過逗號作為標志的,所以這是合法的。

  以上結構可以寫為如下的形式:

  

  int month_lengths[] = {’31’,’29’,’31’,’30’,’31’,’30’,’31’,’31’,’30’,’31’,’30’,’31’,};

  還有一點必須注重了,字符和字符串的表達式不一樣的。單引號用于字符表達式,而雙引號則用于字符串表達式的。這是好多人,包括C的老手,最愛犯的錯誤。寫一個換行語句是會

  寫成 :

  

  printf(’/n’); ,而在字符判定操作的時候卻寫成了:

  

  int c;

  [...]

  

  if((c = getchar()) != "/n"){

  

  do something here

  

  }

  [...]

  這種低級的錯誤是很輕易避免的,但是一不小心就出錯了,而且還不少呢,在教科書、參考書、以及一些文獻以及網絡文字里經常出現,只要你細心一點就可以發現。這看似問題不大,但是

  假如在嵌入式系統,尤其是實時系統有可能造成系統崩潰的,所以寫程序時不要報以任何的僥幸心理,必須審慎每一個細節。程序設計不是一門技術,而是一門藝術。

  下面看看指針吧。

  指針是(pointer)是存放內存地址的變量。 從這個定義中我們可以實力一個這樣的概念: 與指針操作相關的最直接的要素是地址,內存地址。這里的地址指內存中另一個變量的位置。

  假如一個變量含有一個變量的地址,則稱一個變量指向第二個變量。

  預備存放指針的變量必須在使用前聲明好。 指針的聲明由一個基類(base type)、一個星號(*)和變量名組成。 一般的形式為:

  

  type * name;

  其中,type是指針的基類類型,可以是任何有效的數據類型,name是指針變量的名稱。當然了 type *name 和 type * name是等效的,一般的編譯器都會在編譯程序的時候忽略中間的空格。

  指針的基類定義了指針可以指向的變量的類型。 技術上,任何指針類型都可以指向內存的任何位置。然而,指針的操作是基于指針的類型的,也就是說指針變量和其指向的地址的變量的類型必須兼容。即如下的操作時錯誤的:

  

  int *p;

  char ch = ’A’;

  

  p = &ch;

  因為類型不匹配,所以這是錯誤的。其實,這句話不完全對。這只是一個標準罷了,具體還需要看你的編譯器的實現了。上面這種方式的操作在好多編譯器上是可以通過的,比如,Win-TC、LCC等(在Win-TC下直接通過,而在LCC下也只有一個警告罷了)。 不過采用這種方式設計的程序的可移植性一定是很糟糕的。還有假如在操作中假如你想把指針地址存給一個數組元素時,假如類型不匹配,那么你只有強制轉換指針地址的數據類型了,直接賦值是不可能的。所以我們提倡還是采用標準的規定來進行操作。還有下面這一種操作也是錯誤的,雖然類型是匹配的:

  

  int *p;

  int i;

  

  p = &i;

  因為i僅被用戶聲明了,但是沒有分配內存,所以這是錯誤的。一個變量只有在被初始化的時候,才有可能分配到內存的(大多數情況是初始化之后,就分配到內存,但是假如在內存不足的情況就不可能滿足這個要求了)。 在指針聲明中還存在一個誤區,那就是錯誤的認為在如是的表達式 int *p,m,n; 中聲明了3個指針變量,其實只有第一個(p)是指針變量,而其他兩個(m,n)只是int型變量罷了。只有這樣才能同時聲明幾個指針變量的: int *p, *m, *n, ...;

  指針也可以像一般變量一樣進行初始化的,但是你不能給一個一個指針直接的賦值哦。 比如:

  

  int *p;

  p = 10; 只是錯誤的。不過你可以把指針賦值為空,即

  

  int *p = 0; 或者

  

  int *p;

  p = NULL;

  因為在許多的C語言的頭文件,如,定義了宏NULL,它是一個空指針常量,所以我們的表達式是合法的,效果和上面的一個相同。

  我們可以把一個數組變量賦予一個指針,因為它們都是一種地址的映射罷了。這才是我們的主題。比如:

  

  char str[100], *pointer;

  

  pointer = str;

  這里,pointer指向數組str的首元素,與str[0]或者訪問變量str的實質是一樣的,操作的都是數組的第1個元素,0位置上的元素。假如要訪問str數組的第10個元素,那么操作如下:

  

  str[9]

  或

  

  *(pointer + 9) 這是等效的。在指針中也有++,--這樣的操作,尤其在指針和數組互操作時,用到的機率最大,因為操作很靈活。比如:

  

  #include

  

  int main(){

  

  char hello[] = "Hello, world !";

  char *p;

  

  p = hello;

  

  do{

  printf("%c", *p);

  p++;

  } while(*p);

  

  printf("/n");

  return ;

  }

  這是一個典型的例子,即用了指針的“自增”操作,還是數組合指針互操作的好例子。你的操作還可以是:

  

  p = &hello[3];

  *p = hello[3];

  

  *&hello[3] = *p;

  printf("%d/n",*&hello[3]);

  hello[3] = *p;

  printf("%d/n",&hello[3]);

  hello[3] = *p;

  printf("%d/n",hello[3]);

  等等,其中 *&hello[3] 和 &hello[3]的值是一樣的,都是讀取hello數組中3號元素(第四個元素)的地址的。而語句 p = &hello[3];是把3號元素的地址賦給指針變量,而hello[3] = *p;

  是把指針p的值賦給hello[3]的。這也是互操作的一種方式。

  注重了: *++P , ++*p 和 *p++ 以及 *--p , --*p 和 *p-- 表示的結果是不同的。因為++、--的優先級高于*的優先級,所以前邊的表達式相當于 *(++p) , *(++p) 和 *(p++) 以及 *(--p) , *(--p) 和 *(p--)。建議牢牢的記住操作符的優先級,因為在這些細節上稍不注重就會產生問題,我們意想不到的。

  數組和指針都可以當作參數來處理,但是才用指針的概率要高一些,因為指針較數組更加靈活。例如,你可以如下傳遞一個數組或指針變量:

  

  #include

  

  int main(){

  

   char hello[] = "Hello, world !/n";

   char *p;

  

   p = hello;

  

   printf(hello);

   printf(p);

   printf("%s", p);

   printf("%s", hello);

  

   do{

    printf("%c", *p);

    p++;

   } while(*p);

  

   printf("/n");

   return ;

  }

  在LCC中是完全通過的,其輸出結果是:

  

  Hello, world !

  Hello, world !

  Hello, world !

  Hello, world !

  Hello, world !

  但是在有些編譯器上,語句:

  

  printf(hello);

  printf(p);

  可能只會輸出字符串的第1個元素,因為有些編譯器采取的是對字符串進行“截取”的方式來處理,所以其結果有可能是:

  

  HHHello, world !

  Hello, world !

  Hello, world !

  可能這些東西并不一定有用,但是知道這些知識還是有必要的。假如我的辛勞能對你的學習或者開發有點幫助,那我也就滿足了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩一区二区久久久| 麻豆国产va免费精品高清在线| 亚洲国产毛片完整版| 亚洲小视频在线观看| 国产成人精品一区二区三区| 国产极品jizzhd欧美| 成人在线一区二区| 国内揄拍国内精品少妇国语| 久久久久久久999精品视频| 2019中文字幕在线免费观看| 久久久91精品| 国产精品69精品一区二区三区| 色综合久久88色综合天天看泰| 亚洲区中文字幕| 国产日韩中文字幕| 成人激情视频免费在线| 51久久精品夜色国产麻豆| 最近的2019中文字幕免费一页| 欧美性生活大片免费观看网址| 久久久久久伊人| 在线免费看av不卡| 91精品成人久久| 91免费综合在线| 亚洲免费视频在线观看| 中文欧美日本在线资源| 日韩电影免费观看在线| 欧美超级乱淫片喷水| 欧美电影《睫毛膏》| 欧美成人精品三级在线观看| 国产精品91一区| 精品一区二区三区四区| 精品一区电影国产| 日韩电视剧免费观看网站| 欧美日本高清视频| 亚洲精品一区中文字幕乱码| 欧美日韩一区免费| 日韩av电影手机在线观看| 国产女精品视频网站免费| 一区二区亚洲欧洲国产日韩| 亚洲国产精品99久久| 亚洲男子天堂网| 亚洲视频在线观看| 欧美—级高清免费播放| 亚洲久久久久久久久久久| 国产精品永久免费视频| 欧美孕妇与黑人孕交| 欧美性xxxxxx| 911国产网站尤物在线观看| 国产欧美精品日韩精品| 成人亚洲激情网| 国产精品大陆在线观看| 国产不卡精品视男人的天堂| 亚洲电影免费在线观看| 日韩在线观看视频免费| 丝袜一区二区三区| 亚洲精品久久久一区二区三区| 国产成人极品视频| 亚洲天堂一区二区三区| 日韩精品免费一线在线观看| 亚洲人成自拍网站| 欧美精品18videos性欧| 欧美激情第一页xxx| 精品视频—区二区三区免费| 欧美又大粗又爽又黄大片视频| 亚洲成人久久网| 欧美高清在线观看| 国产精品福利网站| 亚洲人成免费电影| 亚洲区免费影片| 成人黄色短视频在线观看| 久久久亚洲精品视频| 日日噜噜噜夜夜爽亚洲精品| 亚洲精品之草原avav久久| 18久久久久久| 一本一本久久a久久精品综合小说| 亚洲福利在线播放| 亚洲美女黄色片| 国产欧美在线看| 国产剧情日韩欧美| 欧美激情二区三区| 国内久久久精品| 国产欧美精品一区二区三区-老狼| 久久免费视频观看| 欧美成人亚洲成人日韩成人| 色综合久久中文字幕综合网小说| 欧美电影免费观看电视剧大全| 亚洲第一区中文字幕| 亚洲国产美女精品久久久久∴| 亚洲精品国产suv| 久久九九全国免费精品观看| 亚洲欧美制服另类日韩| 色综合视频一区中文字幕| 久久久久久69| 成人www视频在线观看| 国产精品三级在线| 欧美高清不卡在线| 国产成人综合精品在线| 91系列在线观看| 欧美电影在线观看| 亚洲天堂成人在线视频| 久久99热精品| 日本午夜在线亚洲.国产| 国产一区二区三区久久精品| 久久综合色影院| 亚洲第一偷拍网| 欧美在线视频观看| 日本亚洲精品在线观看| 久久久av网站| 欧美激情国产精品| 国产精品91免费在线| 奇门遁甲1982国语版免费观看高清| 国外成人免费在线播放| 日韩免费高清在线观看| 欧美成年人视频网站欧美| 国产亚洲视频在线观看| 欧美大片免费观看在线观看网站推荐| 欧美日韩免费网站| 日韩精品在线播放| 91啪国产在线| 永久免费精品影视网站| 久久免费精品视频| 日韩在线免费视频| 欧美最顶级的aⅴ艳星| 欧美成人sm免费视频| 欧美一区二区大胆人体摄影专业网站| 日韩av电影中文字幕| 国产日韩精品在线播放| 最近的2019中文字幕免费一页| 中文字幕日韩av电影| 国产成人激情视频| 精品国产网站地址| 色综合亚洲精品激情狠狠| 欧美在线一级va免费观看| 久久中文字幕在线视频| 国产a∨精品一区二区三区不卡| 国产精品男人爽免费视频1| 国产精品美女久久| 国产精品欧美日韩一区二区| 国产一区二区欧美日韩| 大荫蒂欧美视频另类xxxx| 国产日韩欧美在线播放| 亚洲男人av在线| 欧美日韩在线免费观看| 热99精品里视频精品| 精品久久久av| 九九九久久久久久| 亚洲区bt下载| 欧美日韩免费一区| 一道本无吗dⅴd在线播放一区| 宅男66日本亚洲欧美视频| 大荫蒂欧美视频另类xxxx| 狠狠躁夜夜躁人人躁婷婷91| xxav国产精品美女主播| 97碰在线观看| 日韩最新av在线| 国产精品大片wwwwww| 成人在线播放av| 91探花福利精品国产自产在线| 久久久久九九九九| 日韩精品视频在线| 亚洲精品免费在线视频| 北条麻妃一区二区在线观看| 精品视频久久久| 日韩激情视频在线|