中文字幕理论片,69视频免费在线观看,亚洲成人app,国产1级毛片,刘涛最大尺度戏视频,欧美亚洲美女视频,2021韩国美女仙女屋vip视频

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C/C 指針詳解之基礎(chǔ)篇

目錄

一.變量的內(nèi)存實質(zhì)到

1.1變量的實質(zhì)

1.2 賦值給變量

1.3 變量在哪里?

二. 指針是個什么東西?

 三. 二級指針(指針的指針)

3.1 定義與初始化

3.2 間接數(shù)據(jù)訪問

3.2.1 .改變一級指針指向

3.2.2 改變 N-1 級指針的指向

3.2.3 二級指針的步長

四. 指針與數(shù)組

4.1 指針與數(shù)組名

4.1.1 通過數(shù)組名訪問數(shù)組元素

4.1.2 通過指針訪問數(shù)組元素

4.1.3 數(shù)組名與指針變量的區(qū)別

4.2 指針數(shù)組( 字符指針數(shù)組 )

4.2.1 定義

 4.2.2 代碼實例

4.3 二級指針與指針數(shù)組 

4.3.1 .指針數(shù)組名賦給二級指針的合理性

4.3.2 完美匹配的前提(小尾巴 NULL)


在風起云涌的編程世界中,C/C++作為編程界的扛把子,以霸主地位而屹立不倒,究其原因,它有其他語言無法相媲美的“底牌”而存在,那就是——指針。指針被稱為是C/C++中的精髓,也有人說由于指針的存在讓C/C++變得更加難學,難懂,難消化。果真是這樣嗎?本篇文章讓我們一起來揭開指針的真正面紗。

一.變量的內(nèi)存實質(zhì)到

1.1變量的實質(zhì)

要理解指針,首先就要理解“變量”的存儲實質(zhì),如果你已經(jīng)深入理解“變量”的存儲實質(zhì),直接跳過本小節(jié)……

首先我們來看一下內(nèi)存空間圖:

如圖所示,內(nèi)存只不過是一個存放數(shù)據(jù)的空間,可以理解為裝雞蛋的籃子,裝水果的箱子,或是裝RMB的錢包,隨便啦,反正就是這么一個很隨意的玩意……現(xiàn)在我們把它想象成電影院的座位,電影院中的每個座位都要編號,而我們的內(nèi)存要存放各種各樣的數(shù)據(jù),當然我們要知道我們的這些數(shù)據(jù)存放在什么位置吧!所以內(nèi)存也要象座位一樣進行編號了,這就是我們所說的內(nèi)存編址(為內(nèi)存進行地址編碼)。座位可以是遵循“一個座位對應(yīng)一個號碼”的原則,從“第 1 號”開始編號。而內(nèi)存則是按一個字節(jié)接著一個字節(jié)的次序進行編址,如上圖所示。每個字節(jié)都有個編號,我們稱之為內(nèi)存地址。

內(nèi)存編址:

當我們在程序中寫下了這樣的語言聲明:

int i;
char a;

時,它其實是內(nèi)存中申請了一個名為 i 的整型變量寬度空間(DOS 下的 16 位編程中其寬度為 2 個字節(jié)),和一個名為 a 的字符型變量寬度的空間(占 1 個字節(jié))。

內(nèi)存中的映象如下圖所示:

圖中可看出,i 在內(nèi)存起始地址為 6 上申請了兩個字節(jié)的空間(我這里假設(shè)
了 int 的寬度為 16 位,不同系統(tǒng)中 int 的寬度可能是不一樣的,最常用的win32環(huán)境下為4個字節(jié)),并命名為 i。
a 在內(nèi)存地址為 8 上申請了一字節(jié)的空間,并命名為 a。阿歐……這樣我們就有兩個不同類型的變量了。變量有了接下來我們考慮的就是如何給變量進行賦啦。

1.2 賦值給變量

再看下面賦值:
i = 30;
a = ’t’;
你當然知道個兩個語句是將 30 存入 i 變量的內(nèi)存空間中,將“t”字符存入 a 變量的內(nèi)存空間中。我們可以利用這樣來形象理解:

我們將30存在了以地址6(真正的地址可不是這樣子哦,真正的地址如:0016FD14)為起始地址的兩個字節(jié)空間里,a 在內(nèi)存地址為 8 上申請了一字節(jié)的空間存入了't’,那么變量i和a在哪呢???

1.3 變量在哪里?

接下來我們來看看&i 是什么意思?是取 i 變量所在的地址編號嘛!我們可以這樣大聲讀出來:返回 i 變量的地址編號。你記住了嗎?如果沒有,在讀一遍:返回 i 變量的地址編號。

以一小段簡單代碼來弱弱看下:

#include <iostream> #include <stdlib.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int i = 30; std::cout << '&i = '<< &i << std::endl; std::cout << 'i = ' << i << std::endl; system('pause'); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

輸出結(jié)果為:

輸出的 &i 的值 0016FD14就是我們圖示中內(nèi)存空間編碼為6的內(nèi)存地址。接下來就進入我們真正的主題——指針。

二. 指針是個什么東西?

指針,想說弄懂你不容易啊!我常常在思索它,為什么呢?其實生活中處處都有指針,我們也處處在使用它。有了它
我們的生活才更加方便了。沒有指針,那生活才不方便。不信?你看下面的例子。

比如有天你說你要學習C++,要借我的這本 C++ Primer Plus,我把書給你送過去發(fā)現(xiàn)你已經(jīng)跑出去打籃球了,于是我把書放在了你桌子上書架的第三層四號的位置。并寫了一張紙條:你要的書在第 三 層 四號的書架上。貼在你門上。當你回來時,看到這張紙條,你就知道了我借與你的書放在哪了。你想想看,這張紙條的作用,紙條本身不是書,它上面也沒有放著書。那么你又如何知道書的位置呢?因為紙條上寫著書的位置嘛!聰明?。?!其實這張紙條就是一個指針了。它上面的內(nèi)容不是書本身,而是
書的地址,你通過紙條這個指針找到了我借給你的這本書。

那么我們 C/C++中的指針又戴上了啥面具呢?讓我們拭目以待。下面看一條聲明一個指向整型變量的指針的語句:
int *pi;

pi 是一個指針,當然我們知道啦,但是這樣說,你就以為 pi 一定是個多么特別的東西了。其實,它也只過是一個變量而已。與上一篇中說的變量并沒有實質(zhì)的區(qū)別。好了,這就是指針。僅此而已,就這么簡單。不信你看下圖:

(說明:這里我假設(shè)了指針只占 2 個字節(jié)寬度,實際上在 32 位系統(tǒng)中,指針的寬度是 4 個字節(jié)寬的,即 32 位。)
由圖示中可以看出,我們使用“int *pi”聲明指針變量 —— 其實是在內(nèi)存的某處聲明一個一定寬度的內(nèi)存空間,并把它命名為 pi。你能在圖中看出pi 與前面的 i、a 變量有什么本質(zhì)區(qū)別嗎?沒有,當然沒有!肯定沒有?。≌娴臎]有?。?!pi 也只不過是一個變量而已嘛!那么它又為什么會被稱為“指針”?關(guān)鍵是我們要讓這個變量所存儲的內(nèi)容是什么。現(xiàn)在我要讓 pi 成為具有真正“指針”意義的變量。請接著看下面語句:
pi = &i;
你應(yīng)該知道 &i 是什么意思吧!剛剛大聲讀的那句話,如果忘了,回頭去在大聲讀,記住了?。?!那這句代碼怎么讀呢?這樣大聲讀:把 i 地址的編號賦值給 pi。并記下來。也就是你在 pi 里面寫上 i 的地址編號。結(jié)果如下圖所示:

你看,執(zhí)行完 pi=&i 后,在圖示中的內(nèi)存中,pi 的值是 6。這個 6 就是i 變量的地址編號,這樣 pi 就指向了變量 i 了。你看,pi 與那張紙條有什么區(qū)別?pi 不就是那張紙條嘛!上面寫著 i 的地址,而 i 就是那本厚書C++ Primer Plus。你現(xiàn)在看懂了嗎?因此,我們就把 pi 稱為指針。所以你要牢牢記?。?strong>指針變量所存的內(nèi)容就是內(nèi)存的地址編號 ! 本篇文章看完啥都可以沒記住,這18個紅字切記,切記,切記要牢牢刻在腦子里,也許可能或許大概在將來某個面試中人家問你指針是啥?這18個字足以得滿分。也會隨著你不斷的學習對這句話會理解的越來越深。切記記住這18個紅字??!好了廢話太多了,現(xiàn)在我們就可以通過這個指針 pi 來訪問到 i 這個變量了,請看代碼:

#include <iostream>
#include <stdlib.h>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
int i = 30;
 
std::cout << '&i = '<< &i << std::endl;
std::cout << 'i =  ' << i << std::endl;
 
int *pi = &i;
std::cout << '*pi = ' << *pi << std::endl;
 
system('pause');
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

輸出結(jié)果如下:

那么程序中*pi 什么意思呢?你只要這樣大聲讀它:pi 內(nèi)容所指的地址的內(nèi)容(讀上去好像在繞口令了),就是 pi 這張“紙條”上所寫的位置上的那本 “書”—— i 。你看,Pi 的內(nèi)容是 6,也就是說 pi 指向內(nèi)存編號為 6 的地址。*pi嘛,就是它所指地址的內(nèi)容,即地址編號 6 上的內(nèi)容了,當然就是 30 這個“值”了。所以這條語句會在屏幕上顯示 30。請結(jié)合上圖好好體會吧!由于本人水平有限,對“指針是個什么東西?”的理解僅限于此,有問題我們在隨時探討嘍。真想說:指針是個什么東西,這么難理解,腦仁疼疼的。
到此為止,你已經(jīng)能大聲讀出類似&i、*pi 寫法的含義了。也知道了具體的相關(guān)操作??偨Y(jié)一句話:我們的紙條就是我們的指針,同樣我們的 pi 也就是我們的紙條!剩下的就是我們?nèi)绾螒?yīng)用這張紙條了。如何用?大聲讀出下面的代碼并正確理解含義。

char a,*pa; a = 10; pa = &a; *pa = 20;
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

假設(shè)你已經(jīng)完全掌握在此之前的所有內(nèi)容,我們接著看看“指針的指針”它是個什么東西?即對int **ppa;中 ppa 的理解。

 三. 二級指針(指針的指針)

二級指針,是一種指向指針的指針。我們可以通過它實現(xiàn)間接訪問數(shù)據(jù),和改變一級指針的指向問題。

3.1 定義與初始化

以一張簡圖說明問題:(看不懂看第二節(jié))

例子代碼:

#include <iostream>
#include <stdlib.h>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
int i = 30;
 
std::cout << '&i = '<< &i << std::endl;
std::cout << 'i =  ' << i << std::endl;
 
int *pi = &i;
std::cout << '*pi = ' << *pi << std::endl;
 
int **ppi = &pi;
std::cout << '**ppi = ' << **ppi << std::endl;
 
system('pause');
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

輸出結(jié)果:

 思考:**pi 怎么讀?代表的含義是什么?

3.2 間接數(shù)據(jù)訪問

3.2.1 .改變一級指針指向

例子代碼:

#include <iostream> #include <stdlib.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { int i = 30; int *pi = &i; std::cout << '一級指針*pi = ' << *pi << std::endl; //一級指針 int **ppi = &pi; std::cout << '二級指針**ppi = ' << **ppi << std::endl; //二級指針 *pi = 20; std::cout << '改變一級指針內(nèi)容: *pi = ' << *pi << std::endl; //改變一級指針值 std::cout << '一級指針*pi = ' << *pi << std::endl; //二級指針 int b = 10; *ppi = &b; std::cout << '改變一級指針指向*pi = ' << *pi << std::endl; //改變一級指針的指向 std::cout << '二級指針**ppi = ' << **ppi << std::endl; system('pause'); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

輸出結(jié)果:

3.2.2 改變 N-1 級指針的指向

  • 可以通過一級指針,修改 0  級指針(變量)的內(nèi)容。
  • 可以通過二級指針,修改一級指針的指向。
  • 可以通過三級指針,修改二級指針的指向。
  •  ·····
  • 可以通過 n  級指針,修改 n-1 

3.2.3 二級指針的步長

所有類型的二級指針,由于均指向一級指針類型,一級指針類型大小是 4,所以二級指針的步長也是 4,這個信息很重要

四. 指針與數(shù)組

4.1 指針與數(shù)組名

4.1.1 通過數(shù)組名訪問數(shù)組元素

看下面代碼:

int i, a[] = {3,4,5,6,7,3,7,4,4,6};
for (i = 0; i <= 9; i++)
{
    std::cout << a[i] std::endl;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

很顯然,它是顯示 a 數(shù)組的各元素值。
我們還可以這樣訪問元素,如下:

int i, a[] = {3,4,5,6,7,3,7,4,4,6}; for (i = 0; i <= 9; i++) { std::cout << *(a+i) << std<<endl;; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

它的結(jié)果和作用完全一樣。

4.1.2 通過指針訪問數(shù)組元素

int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a; /*請注意數(shù)組名 a 直接賦值給指針 pa*/
for (i = 0; i <= 9; i++)

{
 std::cout <<  pa[i] << std::endl;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

很顯然,它也是顯示 a 數(shù)組的各元素值。

另外與數(shù)組名一樣也可如下:

int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6}; pa = a; for (i = 0; i <= 9; i++) { std::cout << *(pa+i) << std::endl; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

4.1.3 數(shù)組名與指針變量的區(qū)別

請看下面的代碼:

int i, *pa, a[] = {3,4,5,6,7,3,7,4,4,6};
pa = a;
for (i = 0; i <= 9; i++)
{
printf('%d\n', *pa);
pa++; /*注意這里,指針值被修改*/
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

可以看出,這段代碼也是將數(shù)組各元素值輸出。不過,你把循環(huán)體{}中的 pa改成 a 試試。你會發(fā)現(xiàn)程序編譯出錯,不能成功??磥碇羔樅蛿?shù)組名還是不同的。其實上面的指針是指針變量,而 數(shù)組名只是一個指針常量。

4.2 指針數(shù)組( 字符指針數(shù)組 )

4.2.1 定義

指針數(shù)組的本質(zhì)是數(shù)組,數(shù)組中每一個成員是一個指針。定義形式如下:
char * pArray[10];
語法解析:pArray 先與“[ ]”結(jié)合,構(gòu)成一個數(shù)組的定義,char *修飾的是數(shù)組的內(nèi)容,即數(shù)組的每個元素。

圖示:

 4.2.2 代碼實例

#include <iostream> #include <stdlib.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char * pArray[] ={'apple','pear','banana','orange','pineApple'}; for(int i=0; i<sizeof(pArray)/sizeof(*pArray); i++) { std::cout << pArray[i] << std::endl; } system('pause'); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

輸出結(jié)果:

4.3 二級指針與指針數(shù)組 

4.3.1 .指針數(shù)組名賦給二級指針的合理性

<p>二級指針與指針數(shù)組名等價的原因:<br>
char **p 是二級指針;<br>
char* array[N]; array = &array[0]; array[0] 本身是 char*型;<br>
char **p = array;</p>
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

例子代碼:

#include <iostream> #include <stdlib.h> using namespace std; int _tmain(int argc, _TCHAR* argv[]) { char * pArray[] ={'apple','pear','banana','orange','pineApple'}; std::cout << '**********pArray[i]************' << std::endl; for(int i=0; i<sizeof(pArray)/ sizeof(*pArray); i++) { std::cout << pArray[i] << std::endl; } char **pArr = pArray; std::cout << '**********pArr[i]************' << std::endl; for(int i=0; i<sizeof(pArray)/ sizeof(*pArray); i++) { std::cout << pArr[i] << std::endl; } system('pause'); return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

輸出結(jié)果:

4.3.2 完美匹配的前提(小尾巴 NULL)

數(shù)組名,賦給指針以后,就少了維度這個概念,所以用二級指針訪問指針數(shù)組,需要維度,當然了,也可以不用需要。

實例代碼:

#include <iostream>
#include <stdlib.h>
 
using namespace std;
 
int _tmain(int argc, _TCHAR* argv[])
{
//演繹 1
std::cout << '******演繹 1*****' << std::endl;
int arr[10] = {1};
for(int i=0; i<10; i++)
{
std::cout << arr[i] << std::endl;
}
 
int *parr = arr;
for(int i=0; i<10; i++)
{
std::cout << *parr++ << std::endl;
}
 
 
//演繹 2
std::cout << '*****演繹 2*****'<<std::endl;
char *str = 'china';
while(*str)
{
std::cout << *str++ << std::endl;
}
 
char * pArray[] ={'apple','pear','banana','orange','pineApple',NULL};
char **pa = pArray;
while(*pa != NULL)
{
std::cout << *pa++ << std::endl;
}
system('pause');
return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

輸出結(jié)果:

【下一篇:】C/C++指針詳解之提高篇

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
指針Guide
c++指針經(jīng)典應(yīng)用,多年學習筆記,不看后悔
多維數(shù)組與指針
C++字符串與指針
談C/C++指針精髓
史上最全!一文讓你學完C ,干貨收藏?。?!
更多類似文章 >>
生活服務(wù)
熱點新聞
分享 收藏 導長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服