多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內(nèi)最全IT社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當前位置:首頁 > php開源 > php教程 > c++教程(十三(下):Pointers)

c++教程(十三(下):Pointers)

來源:程序員人生   發(fā)布時間:2016-12-07 08:55:58 閱讀次數(shù):2453次

————————————————————————

該系列教程為翻譯c++官方教程,點擊參考英文原版,水平有限,翻譯不通的地方敬請體諒!

————————————————————————

指針算法

對指針進行算術(shù)操作和整數(shù)類型稍有不同。首先,指針只有加法和減法運算是允許的;其他的對指針來講是沒成心義的。但是,不管是加法和減法對指針,根據(jù)他們指向數(shù)據(jù)類型的大小,都有1個略微不同的表現(xiàn)。

當引入基本數(shù)據(jù)類型,我們看到類型有不同的大小。例如:char大小為1字節(jié),short1般更大,int和long更大;具體大小依賴于系統(tǒng)的精確。例如,讓在1個給定的系統(tǒng)中,假設(shè)char需要1個字節(jié),那末short需要2個字節(jié),而long需要4個字節(jié)。

現(xiàn)在加入我們在編譯器中有3個指針:

char *mychar; short *myshort; long *mylong;

指針的初始地址分別為:1000,2000和3000.
那末如果我們履行下面操作:

++mychar; ++myshort; ++mylong;

那末和我們期待的1樣,mychar將會指向1001地址,但是myshort將會指向2002,而mylong將會指向3004. 雖然他們都只被增加了1次。緣由是,當向指針添加1個時,指針指向同1類型的下1個元素,因此,它所指向的類型的字節(jié)的大小將被添加到指針上。
這里寫圖片描述
當增加和減去任何數(shù)字到1個指針也是適用的。如果我們寫成下面這樣,那末實現(xiàn)的功能和上面將會完全相同:

mychar = mychar + 1; myshort = myshort + 1; mylong = mylong + 1;

關(guān)于自增(+ +)和自減(–)操作,他們都可以被用來作為前綴或后綴的表達,在功能上有輕微的差異:作為1個前綴,表達式在增量產(chǎn)生之前的履行,作為1個后綴,表達式在增量產(chǎn)生后履行。這也適用于表達自增和自減指針,它可以成為更復(fù)雜的表達式,還包括部份援用操作符()。記住運算符優(yōu)先級的規(guī)則,我們可以回想1下,后綴式操作符,如自增和自減,比前綴操作符的優(yōu)先級更高的,如解援用操作符()。因此,下面的表達式:
*p++

等價于 *(p++),它所做的就是增加P值(所以它現(xiàn)在指向下1個元素),但由于++作為后綴,全部表達式被求值后指向原來的指針(它指向的地址遞增)。

從本質(zhì)上講,這些是用的前綴和后綴增量運算符和與解援用操作符的4種可能的組合(一樣適用也減量運算符):

*p++ // same as *(p++): increment pointer, and dereference unincremented address *++p // same as *(++p): increment pointer, and dereference incremented address ++*p // same as ++(*p): dereference pointer, and increment the value it points to (*p)++ // dereference pointer, and post-increment the value it points to

1個典型的-但不是那末簡單的語句是:

*p++ = *q++;

由于++的優(yōu)先級比*更高,p和q是先自增,但由于增量運算符(++)作為后綴而不是前綴,分配到*p值和*Q是自增的。這樣都自增。這大致相當于:

*p = *q; ++p; ++q;

一樣,加括號更能清晰表達以減少混亂。

指針與常量

指針可以被用來訪問1個變量的地址,包括修改指向地址的值。但是也能夠在訪問指向地址指針讀取的時候聲明,這樣就不可以修改它。對這1點,那末所指向的類型就為const指針。例如:

int x; int y = 10; const int * p = &y; x = *p; // ok: reading p *p = x; // error: modifying p, which is const-qualified

這里p指向1個變量,但指出它是const方式,這意味著它是可讀的指針,但不能修改它。注意,這表達&y是int*類型,但這是賦給1個指針類型const int *。這是允許的:1個指向非const可以隱式轉(zhuǎn)換為指向const對象的指針。但不是其他方式!為了安全,指向const指針不可隱式轉(zhuǎn)換為非const指針。

指向const元素的1個指針例子是作為函數(shù)的參數(shù):1個函數(shù)接受1個指向非const參數(shù)作為傳遞參數(shù)的值,而函數(shù)不能接受1個指向const對象的指針作為參數(shù)。

// pointers as arguments: #include <iostream> using namespace std; void increment_all (int* start, int* stop) { int * current = start; while (current != stop) { ++(*current); // increment value pointed ++current; // increment pointer } } void print_all (const int* start, const int* stop) { const int * current = start; while (current != stop) { cout << *current << '\n'; ++current; // increment pointer } } int main () { int numbers[] = {10,20,30}; increment_all (numbers,numbers+3); print_all (numbers,numbers+3); return 0; }

注意,print_all使用指針指向常量元素。這些指針指向常量的內(nèi)容不能修改,但他們不是常量本身:即指針依然可以遞增或分配不同的地址,雖然他們他們指向的內(nèi)容不能修改。

下面是將第2維度添加到指針:指針也能夠是const指針。這是通過添加const指出類型指定(星號后面):

int x; int * p1 = &x; // non-const pointer to non-const int const int * p2 = &x; // non-const pointer to const int int * const p3 = &x; // const pointer to non-const int const int * const p4 = &x; // const pointer to const int

用const與指針的語法是很辣手的,合適的使用常常會需要1些經(jīng)驗。在任何情況下,取得指針常量(援用)的權(quán)限宜早不宜遲,但也不應(yīng)當過分擔心,如果是第1次接觸到const和指針的組合,那末更多例子在后面的章節(jié)中顯示出來。

const指針的語法更混亂的操作是,const限定符可以位于前面或后面,具有的意義相同:

const int * p2a = &x; // non-const pointer to const int int const * p2b = &x; // also non-const pointer to const int

與星號相鄰,在這類情況下,const的順序是1件簡單的風格。本章使用前綴const,由于歷史的緣由,可以擴大很多種,但二者是完全等價的。每種風格的優(yōu)點在互聯(lián)網(wǎng)上仍有劇烈的爭辯。

指針和字符串

前面指出,字符串是包括空終止字符序列的數(shù)組。在前面的章節(jié),字符串被用來直接插入cout來初始化字符串和字符數(shù)組。

但也能夠直接訪問。字符串數(shù)組類型是包括所有字符加終止null字符的數(shù)組,每一個元素的類型是const char(像字面表示的1樣,永久不會被修改)。例如:

const char * foo = "hello";

這里聲明1個“hello”的字符串數(shù)組,然后Foo指針指向其第1個元素。如果我們假定“hello”是存儲在地址1702的內(nèi)存位置,我們可以表示為:

這里寫圖片描述

注意foo是1個值為1702的指針變量,不是‘h’,也不是‘hello’,雖然地址1702是指向這些元素的地址。
Foo是指向這1序列的指針,由于指針與數(shù)組的表示方式是相通的,foo可以1下面兩種方式訪問:

*(foo+4) foo[4]

上面兩種方式都可以得到值‘o’(即數(shù)組的第5個元素)。

指向指針的指針

C++允許定義指向指針的指針,也就是指向了數(shù)據(jù)(或其他指針),所使用的符號就是在指針前面簡單的加上*。

char a; char * b; char ** c; a = 'z'; b = &a; c = &b;

像這里,隨機初始化3個內(nèi)存地址為7230,8092,10502,那末上面就能夠表示為:
這里寫圖片描述

每一個變量的值在其相應(yīng)的單元格中表示的每一個變量,它們在內(nèi)存中的值所表示的值在他們內(nèi)存值上上方。
在這個例子中的c是1個指向指針的指針,可間接用于3個不同的層次,它們中的每個對應(yīng)于1個不同的值:
(1) C是char**類型,值為8092
(2) *c是char*類型,值為7230
(3) **c為char類型,值為‘z’

空指針

空指針是1種特殊的類型,在c++,void代表空類型。因此,void空指針指向的數(shù)據(jù)沒有類型(因此它的長度和相干屬性不肯定)。

這就是的空指針有很大的靈活性,可以指向任何數(shù)據(jù)類型,從1個整型或1個浮點型到1個字符串字符的空指針。一樣相反,他們就有很大的局限性:他們指向的數(shù)據(jù)不能直接援用(這是合乎邏輯的,由于我們不知道類型),由于這個緣由,在1個void指針需要轉(zhuǎn)化為其他1些指針類型時,被援用之前需要指向1個具體的數(shù)據(jù)類型的地址。

下面是1個傳遞函數(shù)參數(shù)的例子:

// increaser #include <iostream> using namespace std; void increase (void* data, int psize) { if ( psize == sizeof(char) ) { char* pchar; pchar=(char*)data; ++(*pchar); } else if (psize == sizeof(int) ) { int* pint; pint=(int*)data; ++(*pint); } } int main () { char a = 'x'; int b = 1602; increase (&a,sizeof(a)); increase (&b,sizeof(b)); cout << a << ", " << b << '\n'; return 0; }

C++中sizeof是1個獲得數(shù)據(jù)類型大小的操作符。對非動態(tài)的數(shù)據(jù),這個值是常量。因此例如sizeof(char)是1,由于char型數(shù)據(jù)占用1個字節(jié)大小。

無效的指針和空指針

在原則上,指針需要指向有效的地址,如變量的地址或數(shù)組中元素的地址。但指針實際上可以指向任何地址,包括沒有任何有效元素的地址。典型的例子是未初始化的指針和指向數(shù)組中不存在的元素:

int * p; // uninitialized pointer (local variable) int myarray[10]; int * q = myarray+20; // element out of bounds

不管p還是q都沒有指向某個已知值的地址,但上述任何語句都不會致使毛病。在C++中,指針是可以指向任何地址值,不管在那個地址是不是有值。甚么會致使毛病對的是援用這樣1個指針(即,訪問他們實際指向的值)。這樣的訪問指針會致使未定義行動,在運行時出現(xiàn)毛病值訪問1些隨機值。
有時,1個指針需要顯式指向無處,而不單單是1個無效的地址。對這類情況,存在1個特殊的值,即任何指針類型都可以采取:null指針值。這個值可以以兩種方式在C++表示:1個整數(shù)為零的值,或nullptr關(guān)鍵字:

int * p = 0; int * q = nullptr;

在這里,P和Q都是空指針,意味著它們不指向任何地方,這里它們實際上是相等的:所有的null指針等于其他的null指針。也很常見的是,在舊的代碼中使用定義的常量 NULL來援用空指針值:

int * r = NULL;

NULL包括在標準庫中,被定義成null常量指針(比如0或nullptr)
不要將null指針與void指針弄混淆了。1個null指針是1個值,任何指針都可以表示它,不指向任何地方,而1個void指針是1個指向沒有特定類型的指針的指針類型。1個是指存儲在指針中的值,另外一個是指向它指向的數(shù)據(jù)類型。

指向函數(shù)的指針

C++允許操作的函數(shù)指針。典型用處是傳遞函數(shù)作為對另外一個函數(shù)的1個參數(shù)。函數(shù)指針與語法與1個普通的函數(shù)相同,除函數(shù)的名字是用括號括起來()和在名字之前插入星號(*)。

// pointer to functions #include <iostream> using namespace std; int addition (int a, int b) { return (a+b); } int subtraction (int a, int b) { return (a-b); } int operation (int x, int y, int (*functocall)(int,int)) { int g; g = (*functocall)(x,y); return (g); } int main () { int m,n; int (*minus)(int,int) = subtraction; m = operation (7, 5, addition); n = operation (20, m, minus); cout <<n; return 0; }

在上面的例子中,minus就是1個有兩個int參數(shù)類型的函數(shù)指針。它直接初始化到函數(shù)subtraction:

int (* minus)(int,int) = subtraction;
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 国产精品成人第一区 | 亚洲人成高清 | 日本欧美成人 | 最近手机中文字幕1 | 国内精品久久久久影院嫩草 | 日本欧美一区二区免费视 | 满18看的毛片 | 亚洲无吗在线视频 | 手机看片午夜 | 在线看黄色网址 | 高清日本一级特黄aa大片 | 日本一二三区在线视频 | www.色老头.com| 国产高清自拍 | 手机在线精品视频每日更新 | 手机午夜看片 | 午夜视频www | 国产成人青草视频 | 欧美成人精品不卡视频在线观看 | 欧美肥老太肥50 60 70 | 欧美一区二区aa大片 | 免费观看欧美成人1314w色 | 日本一区2区 | 国产欧美一区二区精品性色 | 一级做a爱久久久久久久 | 亚洲精品一区二区三区中文字幕 | 色聚网久久综合 | 手机在线看片福利 | 青青青青久久精品国产一百度 | 国产精品久久久久久爽爽爽 | 武则天一级淫片免费放 | 亚洲影院手机版777点击进入影院 | 欧美jjzz| 男女激情视频在线观看 | 一区一区三区产品乱码 | 日本亚州视频在线八a | 亚洲人成在线播放网站 | 狠狠躁夜夜躁人人躁婷婷视频 | 九九福利影院 | 国产成人久久777777 | 国产xx肥老妇视频 |