最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

5分鐘內(nèi)了解C語言的指針

 更新時(shí)間:2015年01月22日 08:53:20   投稿:junjie  
這篇文章主要介紹了5分鐘內(nèi)了解C語言的指針,本文講解了指針、引用和取值、void指針、NULL指針和未初始化指針、指針和數(shù)組等內(nèi)容,需要的朋友可以參考下

指針、引用和取值

什么是指針?什么是內(nèi)存地址?什么叫做指針的取值?指針是一個存儲計(jì)算機(jī)內(nèi)存地址的變量。在這份教程里“引用”表示計(jì)算機(jī)內(nèi)存地址。從指針指向的內(nèi)存讀取數(shù)據(jù)稱作指針的取值。指針可以指向某些具體類型的變量地址,例如int、long和double。指針也可以是void類型、NULL指針和未初始化指針。本文會對上述所有指針類型進(jìn)行探討。

根據(jù)出現(xiàn)的位置不同,操作符 * 既可以用來聲明一個指針變量,也可以用作指針的取值。當(dāng)用在聲明一個變量時(shí),*表示這里聲明了一個指針。其它情況用到*表示指針的取值。

&是地址操作符,用來引用一個內(nèi)存地址。通過在變量名字前使用&操作符,我們可以得到該變量的內(nèi)存地址。

復(fù)制代碼 代碼如下:

// 聲明一個int指針
int *ptr;
// 聲明一個int值
int val = 1;
// 為指針分配一個int值的引用
ptr = &val;
// 對指針進(jìn)行取值,打印存儲在指針地址中的內(nèi)容
int deref = *ptr;
printf("%d\n", deref);

第2行,我們通過*操作符聲明了一個int指針。接著我們聲明了一個int變量并賦值為1。然后我們用int變量的地址初始化我們的int指針。接下來對int指針取值,用變量的內(nèi)存地址初始化int指針。最終,我們打印輸出變量值,內(nèi)容為1。

第6行的&val是一個引用。在val變量聲明并初始化內(nèi)存之后,通過在變量名之前使用地址操作符&我們可以直接引用變量的內(nèi)存地址。

第8行,我們再一次使用*操作符來對該指針取值,可直接獲得指針指向的內(nèi)存地址中的數(shù)據(jù)。由于指針聲明的類型是int,所以取到的值是指針指向的內(nèi)存地址存儲的int值。

這里可以把指針、引用和值的關(guān)系類比為信封、郵箱地址和房子。一個指針就好像是一個信封,我們可以在上面填寫郵寄地址。一個引用(地址)就像是一個郵件地址,它是實(shí)際的地址。取值就像是地址對應(yīng)的房子。我們可以把信封上的地址擦掉,寫上另外一個我們想要的地址,但這個行為對房子沒有任何影響。

void指針、NULL指針和未初始化指針

一個指針可以被聲明為void類型,比如void *x。一個指針可以被賦值為NULL。一個指針變量聲明之后但沒有被賦值,叫做未初始化指針。

復(fù)制代碼 代碼如下:

int *uninit; // int指針未初始化
int *nullptr = NULL; // 初始化為NULL
void *vptr; // void指針未初始化
int val = 1;
int *iptr;
int *castptr;
 
// void類型可以存儲任意類型的指針或引用
iptr = &val;
vptr = iptr;
printf("iptr=%p, vptr=%p\n", iptr, vptr);
 
// 通過顯示轉(zhuǎn)換,我們可以把一個void指針轉(zhuǎn)成
// int指針并進(jìn)行取值
castptr = (int *)vptr;
printf("*castptr=%d\n", *castptr);
 
// 打印null和未初始化指針
printf("uninit=%p, nullptr=%p\n", uninit, nullptr);
// 不知道你會得到怎樣的返回值,會是隨機(jī)的垃圾地址嗎?
// printf("*nullptr=%d\n", nullptr);
// 這里會產(chǎn)生一個段錯誤
// printf("*nullptr=%d\n", nullptr);

執(zhí)行上面的代碼,你會得到類似下面對應(yīng)不同內(nèi)存地址的輸出。

復(fù)制代碼 代碼如下:

iptr=0x7fff94b89c6c, vptr=0x7fff94b89c6c
*castptr=1
uninit=0x7fff94b89d50, nullptr=(nil)

第1行我們聲明了一個未初始化int指針。所有的指針在賦值為NULL、一個引用(地址)或者另一個指針之前都是未被初始化的。第2行我們聲明了一個NULL指針。第3行聲明了一個void指針。第4行到第6行聲明了一個int值和幾個int指針。

第9行到11行,我們?yōu)閕nt指針賦值為一個引用并把int指針賦值為void指針。void指針可以保存各種其它指針類型。大多數(shù)時(shí)候它們被用來存儲數(shù)據(jù)結(jié)構(gòu)。可以注意到,第11行我們打印了int和void指針的地址。它們現(xiàn)在指向了同樣的內(nèi)存地址。所有的指針都存儲了內(nèi)存地址。它們的類型只在取值時(shí)起作用。

第15到16行,我們把void指針轉(zhuǎn)換為int指針castptr。請注意這里需要顯示轉(zhuǎn)換。雖然C語言并不要求顯示地轉(zhuǎn)換,但這樣會增加代碼的可讀性。接著我們對castptr指針取值,值為1。

第19行非常有意思,在這里打印未初始化指針和NULL指針。值得注意的是,未初始化指針是有內(nèi)存地址的,而且是一個垃圾地址。不知道這個內(nèi)存地址指向的值是什么。這就是為什么不要對未初始化指針取值的原因。最好的情況是你取到的是垃圾地址接下來你需要對程序進(jìn)行調(diào)試,最壞的情況則會導(dǎo)致程序崩潰。

NULL指針被初始化為o。NULL是一個特殊的地址,用NULL賦值的指針指向的地址為0而不是隨機(jī)的地址。只有當(dāng)你準(zhǔn)備使用這個地址時(shí)有效。不要對NULL地址取值,否則會產(chǎn)生段錯誤。

指針和數(shù)組

C語言的數(shù)組表示一段連續(xù)的內(nèi)存空間,用來存儲多個特定類型的對象。與之相反,指針用來存儲單個內(nèi)存地址。數(shù)組和指針不是同一種結(jié)構(gòu)因此不可以互相轉(zhuǎn)換。而數(shù)組變量指向了數(shù)組的第一個元素的內(nèi)存地址。

一個數(shù)組變量是一個常量。即使指針變量指向同樣的地址或者一個不同的數(shù)組,也不能把指針賦值給數(shù)組變量。也不可以將一個數(shù)組變量賦值給另一個數(shù)組。然而,可以把一個數(shù)組變量賦值給指針,這一點(diǎn)似乎讓人感到費(fèi)解。把數(shù)組變量賦值給指針時(shí),實(shí)際上是把指向數(shù)組第一個元素的地址賦給指針。

復(fù)制代碼 代碼如下:

int myarray[4] = {1,2,3,0};
int *ptr = myarray;
printf("*ptr=%d\n", *ptr);
 
// 數(shù)組變量是常量,不能做下面的賦值
// myarray = ptr
// myarray = myarray2
// myarray = &myarray2[0]

第1行初始化了一個int數(shù)組,第2行用數(shù)組變量初始化了一個int指針。由于數(shù)組變量實(shí)際上是第一個元素的地址,因此我們可以把這個地址賦值給指針。這個賦值與int *ptr = &myarray[0]效果相同,顯示地把數(shù)組的第一個元素地址賦值到了ptr引用。這里需要注意的是,這里指針需要和數(shù)組的元素類型保持一致,除非指針類型為void。

指針與結(jié)構(gòu)體

就像數(shù)組一樣,指向結(jié)構(gòu)體的指針存儲了結(jié)構(gòu)體第一個元素的內(nèi)存地址。與數(shù)組指針一樣,結(jié)構(gòu)體的指針必須聲明和結(jié)構(gòu)體類型保持一致,或者聲明為void類型。

復(fù)制代碼 代碼如下:

struct person {
  int age;
  char *name;
};
struct person first;
struct person *ptr;
 
first.age = 21;
char *fullname = "full name";
first.name = fullname;
ptr = &first;
 
printf("age=%d, name=%s\n", first.age, ptr->name);

第1至6行聲明了一個person結(jié)構(gòu)體,一個變量指向了一個person結(jié)構(gòu)體和指向person結(jié)構(gòu)體的指針。第8行為age成員賦了一個int值。第9至10行我們聲明了一個char指針并賦值給一個char數(shù)組并賦值給結(jié)構(gòu)體name成員。第11行我們把一個person結(jié)構(gòu)體引用賦值給結(jié)構(gòu)體變量。

第13行我們打印了結(jié)構(gòu)體實(shí)例的age和name。這里需要注意兩個不同的符號,'.' 和 ‘->' 。結(jié)構(gòu)體實(shí)例可以通過使用 ‘.' 符號訪問age變量。對于結(jié)構(gòu)體實(shí)例的指針,我們可以通過 ‘->' 符號訪問name變量。也可以同樣通過(*ptr).name來訪問name變量。

總結(jié)

希望這份簡短的概述能夠有助于了解不同的指針類型。在后續(xù)的博文中我們會探討其它類型的指針和高級用法,比如函數(shù)指針。

歡迎提出提問并給出評論。

相關(guān)文章

  • C++ float、double判斷是否等于0問題

    C++ float、double判斷是否等于0問題

    這篇文章主要介紹了C++ float、double判斷是否等于0問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • QT實(shí)現(xiàn)多線程兩種方式案例詳解

    QT實(shí)現(xiàn)多線程兩種方式案例詳解

    這篇文章主要介紹了QT實(shí)現(xiàn)多線程兩種方式案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++中explict關(guān)鍵字用法

    C++中explict關(guān)鍵字用法

    這篇文章主要介紹了C++中explict關(guān)鍵字用法的相關(guān)資料,本文介紹的非常詳細(xì),具有參考借鑒價(jià)值,感興趣的朋友一起學(xué)習(xí)吧
    2016-05-05
  • 簡單講解C++的內(nèi)部和外部函數(shù)以及宏的定義

    簡單講解C++的內(nèi)部和外部函數(shù)以及宏的定義

    這篇文章主要介紹了簡單講解C++的內(nèi)部和外部函數(shù)以及宏的定義,是C++入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-09-09
  • C++利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘

    C++利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘

    這篇文章主要為大家詳細(xì)介紹了C++如何利用類實(shí)現(xiàn)矩陣的數(shù)乘,乘法以及點(diǎn)乘,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)C++有一定幫助,需要的可以參考一下
    2022-11-11
  • C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列

    C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)遞歸之斐波那契數(shù)列的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • C++實(shí)現(xiàn)雷霆戰(zhàn)機(jī)可視化小游戲

    C++實(shí)現(xiàn)雷霆戰(zhàn)機(jī)可視化小游戲

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)雷霆戰(zhàn)機(jī)可視化小游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++函數(shù)重載的深入解析

    C++函數(shù)重載的深入解析

    在C++中,我們也能夠把具有相同功能的函數(shù)整合到一個函數(shù)上,而不必去寫好多個函數(shù)名不同的函數(shù),這叫做函數(shù)的重載。以下是對C++中的函數(shù)重載進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下
    2013-07-07
  • C語言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    C語言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語言實(shí)現(xiàn)手機(jī)電話簿管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • 學(xué)習(xí)C和C++的9點(diǎn)經(jīng)驗(yàn)總結(jié)

    學(xué)習(xí)C和C++的9點(diǎn)經(jīng)驗(yàn)總結(jié)

    本文給大家總結(jié)了一下我們在學(xué)習(xí)C和C++的時(shí)候的一些經(jīng)驗(yàn)和需要注意的事項(xiàng),希望能給大家一些幫助,少走些彎路
    2015-12-12

最新評論

华蓥市| 六盘水市| 浦城县| 当涂县| 绥江县| 叶城县| 昌平区| 宁晋县| 交口县| 高碑店市| 甘南县| 九龙坡区| 甘泉县| 武定县| 岐山县| 福泉市| 涪陵区| 龙山县| 定日县| 阆中市| 永定县| 黄骅市| 江安县| 拜泉县| 金昌市| 东乡族自治县| 凌云县| 余庆县| 新巴尔虎右旗| 颍上县| 宜兴市| 哈巴河县| 定结县| 晋江市| 安宁市| 衢州市| 保靖县| 清原| 马鞍山市| 和田县| 台山市|