日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++数组与指针概念

發布時間:2023/12/18 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++数组与指针概念 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

指向數組元素的指針

????? 一個變量有地址,一個數組包含若干元素,每個數組元素都在內存中占用存儲單元,它們都有相應的地址。指針變量既然可以指向變量,當然也可以指向數組元素(把某一元素的地址放到一個指針變量中)。所謂數組元素的指針就是數組元素的地址。
? ? int a[10]; ? //定義一個整型數組a,它有10個元素
? ? int *p; ?//定義一個基類型為整型的指針變量p
? ? p=&a[0]; ?//將元素a[0]的地址賦給指針變量p,使p指向a[0]
在C++中,數組名代表數組中第一個元素(即序號為0的元素)的地址。因此,下面兩個語句等價:
? ? p=&a[0];
? ? p=a;
在定義指針變量時可以給它賦初值:
? ? int *p=&a[0]; ?//p的初值為a[0]的地址
也可以寫成
? ? int *p=a; ?//作用與前一行相同
可以通過指針引用數組元素。假設p已定義為一個基類型為整型的指針變量,并已將一個整型數組元素的地址賦給了它,使它指向某一個數組元素。如果有以下賦值語句:
? ? *p=1; ?//對p當前所指向的數組元素賦予數值1
如果指針變量p已指向數組中的一個元素,則p+1指向同一數組中的下一個元素。

如果p的初值為&a[0],則:
1)?p+i和a+i就是a[i]的地址,或者說,它們指向a數組的第i個元素,見圖6.12。


圖6.12


2) *(p+i)或*(a+i)是p+i或a+i所指向的數組元素,即a[i]。

可以看出,[]實際上是變址運算符。對a[i]的求解過程是: 先按a+i×d計算數組元素的地址,然后找出此地址所指向的單元中的值。

3) 指向數組元素的指針變量也可以帶下標,如p[i]與*(p+i)等價。

根據以上敘述,引用一個數組元素,可用以下方法:

  • 下標法,如a[i]形式;
  • 指針法,如*(a+i)或*(p+i)。其中a是數組名,p是指向數組元素的指針變量。如果已使p的值為a,則*(p+i)就是a[i]。可以通過指向數組元素的指針找到所需的元素。使用指針法能使目標程序質量高。


【例6.5】輸出數組中的全部元素。假設有一個整型數組a,有10個元素。要輸出各元素的值有3種方法:

1) 下標法。

復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • int a[10];
  • int i;
  • for(i=0;i<10;i++)
  • cin>>a[i]; //引用數組元素a[i]
  • cout<<endl;
  • for(i=0;i<10;i++)
  • cout<<a[i]<<" "; //引用數組元素a[i]
  • cout<<endl;
  • return 0;
  • }
  • #include <iostream> using namespace std; int main( ) {int a[10];int i;for(i=0;i<10;i++)cin>>a[i]; //引用數組元素a[i]cout<<endl;for(i=0;i<10;i++)cout<<a[i]<<" "; //引用數組元素a[i]cout<<endl;return 0; }

    運行情況如下:
    9 8 7 6 5 4 3 2 1 0↙??????????? (輸入10個元素的值)
    9 8 7 6 5 4 3 2 1 0????????????? (輸出10個元素的值)

    2) 指針法。
    將上面程序第7行和第10行的“a[i]”改為“*(a+i)”,運行情況與(1)相同。

    3) 用指針變量指向數組元素。

    復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • int a[10];
  • int i,*p=a; //指針變量p指向數組a的首元素a[0]
  • for(i=0;i<10;i++)
  • cin>>*(p+i); //輸入a[0]~a[9]共10個元素
  • cout<<endl;
  • for(p=a;p<(a+10);p++)
  • cout<<*p<<" "; //p先后指向a[0]~a[9]
  • cout<<endl;
  • return 0;
  • }
  • #include <iostream> using namespace std; int main( ) {int a[10];int i,*p=a; //指針變量p指向數組a的首元素a[0]for(i=0;i<10;i++)cin>>*(p+i); //輸入a[0]~a[9]共10個元素cout<<endl;for(p=a;p<(a+10);p++)cout<<*p<<" "; //p先后指向a[0]~a[9]cout<<endl;return 0; }

    運行情況與前相同。請仔細分析p值的變化和*p的值。

    對3種方法的比較:
    方法(1)和(2)的執行效率是相同的。第(3)種方法比方法(1)、(2)快。這種方法能提高執行效率。

    用下標法比較直觀,能直接知道是第幾個元素。用地址法或指針變量的方法都不太直觀,難以很快地判斷出當前處理的是哪一個元素。在用指針變量指向數組元素時要注意: 指針變量p可以指向有效的數組元素,實際上也可以指向數組以后的內存單元。如果有
    ? ?int a[10],?*p=a; ? ?//指針變量p的初值為&a[0]
    ? ?cout<<*(p+10); ? ?//要輸出a[10]的值
    在使用指針變量指向數組元素時,應切實保證指向數組中有效的元素。

    指向數組元素的指針的運算比較靈活,務必小心謹慎。下面舉幾個例子。

    如果先使p指向數組a的首元素(即p=a),則:
    1)?p++(或p+=1)。使p指向下一元素,即a[1]。如果用*p,得到下一個元素a[1]的值。

    2) *p++。由于++和*同優先級,結合方向為自右而左,因此它等價于*(p++)。作用是: 先得到p指向的變量的值(即*p),然后再使p的值加1。例6.5(3)程序中最后一個for語句:
    ? ? for(p=a;p<a+10;p++)
    ? ? cout<<*p;
    可以改寫為
    ? ? for(p=a;p<a+10;)
    ? ? cout<<*p++;

    3) *(p++)與*(++p)作用不同。前者是先取*p值,然后使p加1。后者是先使p加1,再取*p。若p的初值為a(即&a[0]),輸出*(p++)得到a[0]的值,而輸出*(++p)則得到a[1]的值。

    4) (*p)++表示p所指向的元素值加1,即(a[0])++,如果a[0]=3,則(a[0])++的值為4。注意: 是元素值加1,而不是指針值加1。

    5) 如果p當前指向a[i],則
    ? ? *(p--)??? 先對p進行“*”運算,得到a[i],再使p減1,p指向a[i-1]。
    ? ? *(++p)?? 先使p自加1,再作*運算,得到a[i+1]。
    ? ? *(--p)?? 先使p自減1,再作*運算,得到a[i-1]。
    將++和--運算符用于指向數組元素的指針變量十分有效,可以使指針變量自動向前或向后移動,指向下一個或上一個數組元素。例如,想輸出a數組100個元素,可以用以下語句:
    ? ? p=a;
    ? ? while(p<a+100)
    ? ? cout<<*p++;

    ? ? p=a;
    ? ? while(p<a+100)
    ? ? {
    ? ? ? ? cout<<*p;
    ? ? ? ? p++;
    ? ? }
    在用*p++形式的運算時,很容易弄錯,一定要十分小心,弄清楚先取p值還是先使p加1。

    用指針變量作函數參數接收數組地址

    在前面介紹過可以用數組名作函數的參數。前面已經多次強調: 數組名代表數組首元素的地址。用數組名作函數的參數,傳遞的是數組首元素的地址。很容易推想: 用指針變量作函數形參,同樣可以接收從實參傳遞來的數組首元素的地址(此時,實參是數組名)。下面將第5章5.4節中的例5.7程序改寫,用指針變量作函數形參。

    【例6.6】將10個整數按由小到大的順序排列。在例5.7程序的基礎上,將形參改為指針變量。

    復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • void select_sort(int *p,int n); //函數聲明
  • int a[10],i;
  • cout<<"enter the originl array:"<<endl;
  • for(i=0;i<10;i++) //輸入10個數
  • cin>>a[i];
  • cout<<endl;
  • select_sort(a,10); //函數調用,數組名作實參
  • cout<<"the sorted array:"<<endl;
  • for(i=0;i<10;i++) //輸出10個已排好序的數
  • cout<<a[i]<<" ";
  • cout<<endl;
  • return 0;
  • }
  • ?
  • void select_sort(int *p,int n) //用指針變量作形參
  • {
  • int i,j,k,t;
  • for(i=0;i<n-1;i++)
  • {
  • k=i;
  • for(j=i+1;j<n;j++)
  • if(*(p+j)<*(p+k)) k=j; //用指針法訪問數組元素
  • t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;
  • }
  • }
  • #include <iostream> using namespace std; int main( ) {void select_sort(int *p,int n); //函數聲明int a[10],i;cout<<"enter the originl array:"<<endl;for(i=0;i<10;i++) //輸入10個數cin>>a[i];cout<<endl;select_sort(a,10); //函數調用,數組名作實參cout<<"the sorted array:"<<endl;for(i=0;i<10;i++) //輸出10個已排好序的數cout<<a[i]<<" ";cout<<endl;return 0; }void select_sort(int *p,int n) //用指針變量作形參 {int i,j,k,t;for(i=0;i<n-1;i++){k=i;for(j=i+1;j<n;j++) if(*(p+j)<*(p+k)) k=j; //用指針法訪問數組元素t=*(p+k);*(p+k)=*(p+i);*(p+i)=t;} }

    運行情況與例5.7相同。


    圖 6.13


    本例與例5.7在程序的表現形式上雖然有不同,但實際上,兩個程序在編譯以后是完全相同的。C++編譯系統將形參數組名一律作為指針變量來處理。

    實際上在函數調用時并不存在一個占有存儲空間的形參數組,只有指針變量。

    實參與形參的結合,有以下4種形式:
    實? 參 ? ? ? ? ? ? ? ? 形? 參
    數組名 ? ? ? ? ? ? ?數組名?????? (如例5.7)
    數組名 ? ? ? ? ? ?指針變量 ? ? (如例6.6)
    指針變量 ? ? ? ? ?數組名
    指針變量 ? ? ? ?指針變量

    在此基礎上,還要說明一個問題: 實參數組名a代表一個固定的地址,或者說是指針型常量,因此要改變a的值是不可能的。如:
    ? ? a++; ?//語法錯誤,a是常量,不能改變
    而形參數組名是指針變量,并不是一個固定的地址值。它的值是可以改變的。在函數調用開始時,它接收了實參數組首元素的地址,但在函數執行期間,它可以再被賦值。如:

    復制純文本復制
  • f(array[], int n)
  • {
  • cout<<array; //輸出array[0]的值
  • array=array+3; //指針變量array的值改變了,指向array[3]
  • cout<<*arr<<endl; //輸出array[3]的值
  • }
  • f(array[], int n) {cout<<array; //輸出array[0]的值array=array+3; //指針變量array的值改變了,指向array[3]cout<<*arr<<endl; //輸出array[3]的值 }

    多維數組與指針

    用指針變量可以指向一維數組中的元素,也可以指向多維數組中的元素。

    1) 多維數組元素的地址
    設有一個二維數組a,它有3行4列。它的定義為:
    ? ??int a[3][4]={{1,3,5,7},{9,11,13,15},{17,18,21,23}};
    a是一個數組名。a數組包含3行,即3個元素:a[0],a[1],a[2]。而每一元素又是一個一維數組,它包含4圖6.14個元素(即4個列元素),例如,a[0]所代表的一維數組又包含4個元素: a[0][0], a[0][1], a[0][2], a[0][3],見圖6.14。可以認為二維數組是“數組的數組”,即數組a是由3個一維數組所組成的。


    圖6.14


    從二維數組的角度來看,a代表二維數組首元素的地址,現在的首元素不是一個整型變量,而是由4個整型元素所組成的一維數組,因此a代表的是首行的起始地址(即第0行的起始地址,&a[0]),a+1代表a[1]行的首地址,即&a[1]。

    a[0],a[1],a[2]既然是一維數組名,而C++又規定了數組名代表數組首元素地址,因此a[0]代表一維數組a[0]中0列元素的地址,即&a[0][0]。a[1]的值是&a[1][0],a[2]的值是&a[2][0]。


    圖6.15


    0行1列元素的地址可以直接寫為&a[0][1],也可以用指針法表示。a[0]為一維數組名,該一維數組中序號為1的元素顯然可以用a[0]+1來表示,見圖6.16。

    欲得到a[0][1]的值,用地址法怎么表示呢?既然a[0]+1是a[0][1]元素的地址,那么,*(a[0]+1) 就是a[0][1]元素的值。而a[0]又是和*(a+0)無條件等價的,因此也可以用*(*(a+0)+1)表示a[0][1]元素的值。依此類推,*(a[i]+j)或*(*(a+i)+j)是a[i][j]的值。


    圖6.16


    2) 指向多維數組元素的指針變量

    ① 指向數組元素的指針變量
    【例6.7】輸出二維數組各元素的值。這里采用的方法是用基類型為整型的指針變量先后指向各元素,逐個輸出它們的值。

    復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
  • int *p; //p是基類型為整型的指針變量
  • for(p=a[0];p<a[0]+12;p++)
  • cout<<*p<<" ";
  • cout<<endl;
  • return 0;
  • }
  • #include <iostream> using namespace std; int main( ) {int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int *p; //p是基類型為整型的指針變量for(p=a[0];p<a[0]+12;p++)cout<<*p<<" ";cout<<endl;return 0; }

    運行結果如下:
    1 3 5 7 9 11 13 15 17 19 21 23

    關于指向數組元素的指針變量的幾點說明:

    • p是指向整型數據的指針變量,在for語句中對p賦初值a[0],也可以寫成“p=&a[0][0]”。
    • 循環結束的條件是“p<a[0]+12”,只要滿足p<a[0]+12,就繼續執行循環體。
    • 執行“cout<<*p;”輸出p當前所指的列元素的值,然后執行p++,使p指向下一個列元素。


    ②指向由m個元素組成的一維數組的指針變量
    可以定義一個指針變量,它不是指向一個整型元素,而是指向一個包含m個元素的一維數組。這時,如果指針變量p先指向a[0](即p=&a[0]),則p+1不是指向a[0][1],而是指向a[1],p的增值以一維數組的長度為單位,見圖6.17。


    圖6.17


    【例6.8】輸出二維數組任一行任一列元素的值。

    復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
  • int (*p)[4],i,j;
  • cin>>i>>j;
  • p=a;
  • cout<<*(*(p+i)+j)<<endl;
  • return 0;
  • }
  • #include <iostream> using namespace std; int main( ) {int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};int (*p)[4],i,j;cin>>i>>j;p=a;cout<<*(*(p+i)+j)<<endl;return 0; }

    運行情況如下:
    2 3↙
    23

    由于執行了“p=a”,使p指向a[0]。因此p+2是二維數組a中序號為2的行的起始地址(由于p是指向一維數組的指針變量,因此p加1,就指向下一個一維數組),見圖6.18。*(p+2)+3是a數組2行3列元素地址。*(*(p+2)+3)是a[2][3]的值。


    圖6.18


    3) 用指向數組的指針作函數參數
    一維數組名可以作為函數參數傳遞,多維數組名也可作函數參數傳遞。

    【例6.9】輸出二維數組各元素的值。題目與例6.7相同,但本題用一個函數實現輸出,用多維數組名作函數參數。

    復制純文本復制
  • #include <iostream>
  • using namespace std;
  • int main( )
  • {
  • void output(int (*p)[4]); //函數聲明
  • int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};
  • output(a); //多維數組名作函數參數
  • return 0;
  • }
  • ?
  • void output(int (*p)[4]) //形參是指向一維數組的指針變量
  • {
  • int i,j;
  • for(i=0;i<3;i++)
  • for(j=0;j<4;j++)
  • cout<<*(*(p+i)+j)<<" ";
  • cout<<endl;
  • }
  • #include <iostream> using namespace std; int main( ) {void output(int (*p)[4]); //函數聲明 int a[3][4]={1,3,5,7,9,11,13,15,17,19,21,23};output(a); //多維數組名作函數參數return 0; }void output(int (*p)[4]) //形參是指向一維數組的指針變量 {int i,j;for(i=0;i<3;i++)for(j=0;j<4;j++)cout<<*(*(p+i)+j)<<" ";cout<<endl; }

    運行情況如下:
    1 3 5 7 9 11 13 15 17 19 21 23

    總結

    以上是生活随笔為你收集整理的C++数组与指针概念的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。