亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        淺談C語言中指針的理解及應(yīng)用

        2017-06-06 12:30:10曾凡舒
        廣東教育·職教版 2017年5期
        關(guān)鍵詞:定義

        曾凡舒

        指針是C語言中一種廣泛使用的數(shù)據(jù)類型,也是C語言的重要特性。在C語言中,使用指針能夠編寫出高效、精煉、簡潔的程序代碼。因此,在C語言的學(xué)習(xí)過程中,能否正確理解和使用指針是檢驗(yàn)是否掌握C語言的一個(gè)重要標(biāo)志,但是,指針也是C語言中最為困難的部分之一。指針的學(xué)習(xí)像其他內(nèi)容一樣也必須從理解基本概念開始。

        一、計(jì)算機(jī)基本原理

        半個(gè)多世紀(jì)以來,雖然計(jì)算機(jī)制造技術(shù)發(fā)生了巨大變化,但仍然沿用馮·諾依曼體系結(jié)構(gòu)。在馮·諾依曼計(jì)算機(jī)體系結(jié)構(gòu)理論中,有三個(gè)基本思想:1)計(jì)算機(jī)處理的數(shù)據(jù)和指令采均用二進(jìn)制數(shù)表示;2)計(jì)算機(jī)運(yùn)行過程中,指令和數(shù)據(jù)首先存入主存儲(chǔ)器(內(nèi)存),計(jì)算機(jī)將自動(dòng)地并按順序從主存儲(chǔ)器中取出指令一條一條地執(zhí)行,這一概念稱作順序存儲(chǔ)程序;3)計(jì)算機(jī)硬件由運(yùn)算器、控制器、存儲(chǔ)器、輸入設(shè)備和輸出設(shè)備五大部分組成。

        計(jì)算機(jī)的主存儲(chǔ)器是由一系列連續(xù)編號(hào)或編碼的存儲(chǔ)單元組成,要運(yùn)行的程序指令以及相關(guān)的數(shù)據(jù)都按照一定的順序存儲(chǔ)在內(nèi)存中,如圖1所示。存儲(chǔ)單元中存儲(chǔ)的內(nèi)容有三種:1)指令,如0x03000、0x03001存儲(chǔ)單元,2)直接數(shù)據(jù),如0x05027、0x05028、0x05029、0x05030存儲(chǔ)單元,3)地址數(shù)據(jù),如0x03002、0x03003存儲(chǔ)單元,它們存儲(chǔ)的是存儲(chǔ)單元0x05030、0x05027的地址值。

        二、指針的基本概念

        C語言的設(shè)計(jì)者Brian W.Kernighan在《C程序設(shè)計(jì)語言》一書中給指針的定義是:指針是一種保存變量地址的變量,因此要真確理解指針概念,先要理解幾個(gè)指針相關(guān)的概念,如地址、變量等。

        地址:在計(jì)算機(jī)中,通過尋址機(jī)構(gòu)將物理存儲(chǔ)介質(zhì)映射成一維線性空間,并以字節(jié)為單位進(jìn)行統(tǒng)一編碼,使得每個(gè)字節(jié)都具有唯一的編碼,類似于街道的門牌號(hào)碼,該編碼稱為字節(jié)的地址,也稱內(nèi)存地址。內(nèi)存地址采用無符號(hào)整數(shù)來表示,例如在32位計(jì)算機(jī)中,內(nèi)存地址編碼為0x00000000 ~0xFFFFFFFF,能夠支持最大4GB的內(nèi)存空間,每個(gè)字節(jié)的地址采用32位的無符號(hào)整數(shù)表示。

        存儲(chǔ)單元:在計(jì)算機(jī)系統(tǒng)中,絕大多數(shù)的數(shù)據(jù)往往需要多個(gè)字節(jié)來存儲(chǔ),如Unicode字符、整數(shù)、浮點(diǎn)小數(shù)、字符串等。所以,需要分配一個(gè)或連續(xù)的多個(gè)字節(jié)來存儲(chǔ)這些基本數(shù)據(jù),我們把一個(gè)或連續(xù)的多個(gè)字節(jié)的存儲(chǔ)空間稱為一個(gè)存儲(chǔ)單元,每個(gè)存儲(chǔ)單元的地址用該存儲(chǔ)單元的第一個(gè)字節(jié)的地址來表示。例如,C語言中的short int、long int、char、double等基本數(shù)據(jù)類型在32位計(jì)算機(jī)系統(tǒng)中分別占用2、4、1、8個(gè)字節(jié),如果在內(nèi)存0x0F00地址處依次存儲(chǔ)short int、long int、char、double類型數(shù)據(jù)各一個(gè),那么這四個(gè)存儲(chǔ)單元的地址則分別為0x0F00、0x0F02、0x0F06、0x0F07,而下一個(gè)存儲(chǔ)單元的地址則為0x0F0F,如圖2所示。

        變量:是計(jì)算機(jī)存儲(chǔ)空間或存儲(chǔ)單元的具體化,通過一個(gè)易辨別的字符序列來標(biāo)識(shí)一個(gè)存儲(chǔ)空間或存儲(chǔ)單元,這樣能夠大大提高編程效率和代碼的可讀性。變量具有三個(gè)要素:1)名稱,2)類型,3)值,此外,變量還有一個(gè)隱含屬性,即地址。例如,圖1中的變量s、i三個(gè)變量,它們的要素及屬性如表1所示。

        指針:回頭再看Brian W.Kernighan的指針定義,指針本質(zhì)上也是一個(gè)變量,只不過它存儲(chǔ)的數(shù)據(jù)是一個(gè)表示地址的無符號(hào)整數(shù)。如圖1所示,變量pi、ps就是指針變量,我們把表1加上變量pi、ps后得到表2。

        三、指針定義及運(yùn)算

        在C語言中,表2中各變量的定義如下:

        char s = ‘a(chǎn), *ps; //定義并初始化char類型變量s,定義一個(gè)指向char類型變量的指針

        int i = 56, *pi; //定義并初始化int類型變量i,定義一個(gè)指向int類型變量的指針

        ps = &s; //將變量s的地址保存到ps變量中,則ps將指向s變量

        pi = &i; //將變量i的地址保存到pi變量中,則pi將指向i變量

        或者

        char s = ‘a(chǎn), *ps = &s ; //指針定義與賦值同時(shí)進(jìn)行

        int i = 56, *pi = &i;

        其中,*ps稱為指針,指針變量的定義格式為:

        數(shù)據(jù)類型 *指針變量名;

        在上述代碼中,通過ps = &s賦值后,*ps等價(jià)于s。結(jié)合圖1,對(duì)于0x05027存儲(chǔ)單元中的‘a(chǎn)有兩種訪問方式:1)通過變量s來訪問內(nèi)存地址0x05027的‘a(chǎn),這種訪問方式稱為直接訪問方式;2)指針變量ps中存放的是變量s的地址,通過*ps來訪問0x05027的‘a(chǎn)需要兩個(gè)步驟,首先要從指針變量ps中讀取變量s的地址0x05027,再從地址0x05027中讀出‘a(chǎn),這種通過指針變量存取數(shù)據(jù)的訪問方式稱為間接訪問方式。

        跟指針密切相關(guān)的運(yùn)算符是*和&,它們均為一元運(yùn)算符,且互為逆運(yùn)算。

        &運(yùn)算符:取地址運(yùn)算符。放在普通變量的前面,作用是獲取對(duì)應(yīng)變量的存儲(chǔ)地址,例如變量i的值為56,而表達(dá)式&i的值則為0x05030,可使用以下語句進(jìn)行測試:

        inti = 56;

        printf ("%d, %p", i, &i);

        其運(yùn)行結(jié)果為:56, 0060FF34

        *運(yùn)算符:指針運(yùn)算符,又稱間接訪問運(yùn)算符。放在指針變量的前面,作用是獲取指針變量中的地址所對(duì)應(yīng)的存儲(chǔ)單元中的數(shù)據(jù)??捎孟率龃a進(jìn)行驗(yàn)證。

        inti = 56, *pi; // 第1行

        pi = &i; // 第2行

        printf ("%d, %p, %p, %d", i, &i, pi, *pi); // 第3行

        運(yùn)行結(jié)果為: 56, 0060FF34, 0060FF34, 56

        其中,第1行的*表示定義指針變量,第3行中的*則表示指針運(yùn)算。

        四、指針的應(yīng)用

        學(xué)習(xí)指針的難點(diǎn)除了概念上的理解比較難以外,在應(yīng)用上有以下幾個(gè)比較難理解的地方。

        1.指針的初始化、釋放與NULL指針

        指針在使用中容易出問題的主要環(huán)節(jié)就是指針的初始化和釋放后的處理。指針必須先申明,再賦值,然后才能使用,使用完后,需要用free()函數(shù)釋放所占用的存儲(chǔ)空間,最后還要對(duì)指針變量進(jìn)行置空,否則會(huì)出現(xiàn)意想不到的問題。

        首先,在聲明指針變量后,如果不進(jìn)行初始化,那么該指針就是一個(gè)未初始化的指針,指針變量中的數(shù)據(jù)為內(nèi)存殘存數(shù)據(jù),如果不進(jìn)行初始化,就會(huì)指向一個(gè)未知的地方,得到的是一個(gè)無效數(shù)據(jù)。如下面的程序代碼。

        int *pt;

        printf ("%p, %p, %d\n", &pt, pt, *pt);

        運(yùn)行結(jié)果:0060FF30, 004013A0, -2082109099

        結(jié)果中第一個(gè)數(shù)字0060FF30表示的是指針變量pt本身的地址值;第二個(gè)數(shù)字004013A0是表示指針變量pt中的地址值,由于指針pt沒有初始化,所以指針pt變量中的地址值是原來內(nèi)存中的殘存數(shù)據(jù);第三個(gè)數(shù)字-2082109099則是殘存數(shù)據(jù)作為地址值所指內(nèi)存中的數(shù)據(jù),不是我們想要的數(shù)據(jù),屬于垃圾數(shù)據(jù)。

        其次,在指針使用完畢后,第一,要釋放指針?biāo)嫉膬?nèi)存空間,通過free()函數(shù)完成,第二,需要對(duì)不用的指針變量置空,即設(shè)置不再使用的指針變量的值為NULL,否則釋放空間后,指針中的地址值不會(huì)變,但是指針原來所指的存儲(chǔ)單元將成為未使用空間或分配給其他的變量使用。

        char *pta = (char *) malloc(30); //第1行

        strcpy(pta, "Hello C Language!"); //第2行

        printf ("%p \n", pta); //第3行

        free(pta); //第4行

        printf ("%p \n", pta); //第5行

        //if(pta != NULL); //第6行

        //strcpy(pta, "zfs"); //第7行

        pta = NULL; //第8行

        printf ("%p \n", pta); //第9行

        結(jié)果為:

        009C0DC0

        009C0DC0

        00000000

        第一個(gè)數(shù)字009C0DC0為malloc()函數(shù)申請(qǐng)30個(gè)字符空間的首個(gè)字節(jié)的地址,并將該地址值保存到了指針變量pta中;第二個(gè)數(shù)字009C0DC0是對(duì)指針變量pta進(jìn)行釋放處理后其中的值,可以看出,雖然釋放了pta所指向的存儲(chǔ)空間,但pta中的地址值仍然不變,pta所指向的存儲(chǔ)空間已經(jīng)回收或另作他用,pta指向了不可用內(nèi)存區(qū)域,成了野指針,而且不能使用(pta != NULL)進(jìn)行檢測,所以第6、7行運(yùn)行會(huì)出錯(cuò);第三個(gè)數(shù)字00000000是將pta變量置空后pta中的值,即將NULL賦值給pta指針變量,pta即成為NULL指針(空指針),NULL的定義在C語言標(biāo)準(zhǔn)庫頭文件stddef.h中。宏定義如下:

        #undef NULL

        #if defined(__cplusplus)

        #define NULL 0

        #else

        #define NULL ((void *)0)

        #endif

        2.指針與數(shù)組

        C語言的數(shù)組表示的是一段連續(xù)的內(nèi)存空間,用來存儲(chǔ)多個(gè)指定類型的數(shù)據(jù),每個(gè)數(shù)組成員稱為一個(gè)數(shù)組元素,每個(gè)數(shù)組元素占用的字節(jié)數(shù)相等。數(shù)組和指針不是同一種結(jié)構(gòu),不可以互相轉(zhuǎn)換,但是數(shù)組變量則是指向了數(shù)組的第一個(gè)元素的內(nèi)存地址,如圖3所示。

        short int ai[5]= {27, 36, 51, 110, 97}; //第1行

        short int *ptai; //第2行

        ptai = ai; //第3行

        在C語言中可以把數(shù)組變量直接賦值給指針,但不能把指針變量賦值給數(shù)組。如果把一個(gè)數(shù)組變量值賦給指針,實(shí)際上是把指向數(shù)組第一個(gè)元素的地址賦給指針。第2、3行可以理解為:

        short int *ptai = &ai[0];

        或者

        short int *ptai;

        ptai = &ai[0];

        所以ai[0]與*ptai是等價(jià),由于數(shù)組中的元素是等長的,因此,ai[1]與*(ptai + 1)、ai[2]與*(ptai + 2)也是等價(jià)的,以此類推。但是,要注意的是ptai + 1、ptai + 2中的1、2并不是按字節(jié)計(jì)算的偏移量,而是按short int類型計(jì)算的偏移量。

        五、總結(jié)

        指針雖然比較難以理解和掌握,需要許多計(jì)算機(jī)底層的知識(shí)作支撐,但它卻是C語言的精髓所在,是C語言的重要特性,能夠充分展現(xiàn)C語言的強(qiáng)大魅力。實(shí)際上,我們只要從變量的本質(zhì)、內(nèi)存地址、計(jì)算機(jī)尋址原理等多方面進(jìn)行了解和貫通,指針概念以及指針的相關(guān)應(yīng)用也就不難理解了。而且,通過對(duì)指針的深入了解和學(xué)習(xí),能夠更加高效和靈活地使用數(shù)組、字符串、結(jié)構(gòu)體、各種線性非線性數(shù)據(jù)結(jié)構(gòu)、內(nèi)存的動(dòng)態(tài)分配以及文件的存取等。所以說,學(xué)好了指針,才能夠?qū)W好C語言。

        責(zé)任編輯朱守鋰

        猜你喜歡
        定義
        以愛之名,定義成長
        活用定義巧解統(tǒng)計(jì)概率解答題
        例談橢圓的定義及其應(yīng)用
        題在書外 根在書中——圓錐曲線第三定義在教材和高考中的滲透
        永遠(yuǎn)不要用“起點(diǎn)”定義自己
        海峽姐妹(2020年9期)2021-01-04 01:35:44
        嚴(yán)昊:不定義終點(diǎn) 一直在路上
        定義“風(fēng)格”
        成功的定義
        山東青年(2016年1期)2016-02-28 14:25:25
        有壹手——重新定義快修連鎖
        修辭學(xué)的重大定義
        国产亚洲欧洲AⅤ综合一区| 亚洲成a∨人片在线观看不卡| 久久精品麻豆日日躁夜夜躁| 欧美一级欧美一级在线播放| 国产99精品精品久久免费| 国产一区二区三区免费av| 日本在线 | 中文| 久久精品视频在线看99| 韩国日本亚洲精品视频| 国产精品国产三级国产an不卡| 亚洲日韩精品a∨片无码加勒比| 国产丝袜无码一区二区三区视频| 美女一级毛片免费观看97| 久久国产女同一区二区| 国产女人精品视频国产灰线| 亚洲精品无码久久久久牙蜜区 | 亚洲av无码片一区二区三区| 久久人妻av无码中文专区| 女女同女同一区二区三区| 国产超碰人人做人人爽av大片 | 伊人加勒比在线观看视频| 成人性生交大片免费看96| 日韩精品中文字幕无码专区| 精品蜜桃一区二区三区| 亚洲悠悠色综合中文字幕| 久久国产精品久久久久久| 99久久人妻无码精品系列蜜桃| 亚洲图文一区二区三区四区| 无码国产精成人午夜视频一区二区 | 亚洲女同人妻在线播放| 欧美日本精品一区二区三区| 欧美gv在线观看| 99热在线播放精品6| 亚洲熟女少妇一区二区三区青久久| 欧美猛少妇色xxxxx猛交| 91精品国产综合成人| 亚洲美女主播一区二区| 久久与欧美视频| 精品福利一区二区三区| 亚洲国产成人久久三区| 国产欧美日韩专区|