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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针

發布時間:2023/11/28 生活经验 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 什么是指針變量?

指針變量是專門有一個變量來存放指針。

int main(int argc, char *argv[])
{int a = 10;int *p = &a;    //通過取地址符號 & 把 a 變量的地址傳給指針變量 pstd::cout << "p is " << p << std::endl;     // p is 0x7fffe740301cstd::cout << "&a is " << &a << std::endl;   //&a is 0x7fffe740301cstd::cout << "*p=" << *p << std::endl;      // *p=10return 0;
}

通過符號 *p 獲取指針變量 p 指向的地址的存放的值。我們可以理解為通過變量 p 我們拿到抽屜的鑰匙(地址)打開抽屜取出數據。

int main()
{int i = 3;int *iptr = &i;int **iptrptr = &iptr;  //iptr 也是變量,也能夠獲取它的地址cout << "iptr=" << iptr <<endl;  //輸出 iptr 存儲的內容,即 i 在內存中的地址cout << "*iptr=" << *iptr <<endl;    //輸出 iptr 所指向的變量cout << "iptrptr=" << iptrptr <<endl;    //輸出 iptr 在內存中的地址cout << "*iptrptr=" << *iptrptr <<endl;  //輸出 iptrptr 所指向的變量,即 iptr*iptr = 2 + *iptr;  //*iptr 可以作左值cout << "*iptr=" << *iptr <<endl;return 0;
}

輸出結果:

iptr=0x7ffd0e00e2b4
*iptr=3
iptrptr=0x7ffd0e00e2b8
*iptrptr=0x7ffd0e00e2b4
*iptr=5

2. 數組和指針

int main(int argc, char *argv[])
{int a[3] = {1,2,3};int *p = a;std::cout << "p is " << p << std::endl;    std::cout << "&a is " << &a << std::endl;   std::cout << "a is " << a << std::endl;    std::cout << "&a[0] is " << &a[0] << std::endl;     std::cout << "*p=" << *p << std::endl;      std::cout << "*(p+1)=" << *(p+1) << std::endl;     std::cout << "a[1]=" << a[1] << std::endl;  return 0;
}

執行輸出結果:

p is 0x7fff7b96be40
&a is 0x7fff7b96be40
a is 0x7fff7b96be40
&a[0] is 0x7fff7b96be40
*p=1
*(p+1)=2
a[1]=2

a 的值就是數組 a 第一個元素的地址,與 &a[0]&a 等價。

而 p+1 表示的是數組 a 的第二個元素的地址,以此類推。

獲取數組的第二個元素可以是 a[1],也可以是 *(p+1)。

3. 指針數組

表示數組內存放的是指針類型的數據。

定義方式

int *p[]

示例:

int main(int argc, char *argv[])
{int a[3] = {1,2,3};int *p[3] = {a,a+1,a+2};std::cout << "a= " << a << std::endl;     std::cout << "a+1= " << a+1 << std::endl;   std::cout << "a+2= " << a+2 << std::endl;  std::cout << "*p=" << *p << std::endl;      std::cout << "*(p+1)=" << *(p+1) << std::endl;   std::cout << "p[1]=" << p[1] << std::endl;    std::cout << "**p=" << **p<< std::endl;  std::cout << "**(p+1)=" << **(p+1) << std::endl;  return 0;
}

輸出:

a= 0x7ffd747a1b70
a+1= 0x7ffd747a1b74
a+2= 0x7ffd747a1b78
*p=0x7ffd747a1b70
*(p+1)=0x7ffd747a1b74
p[1]=0x7ffd747a1b74
**p=1
**(p+1)=2

aa+1a+2 分別表示數組 a 第一個、第二個、第三個元素的地址。

p+1 指的是指針數組 p 的第二個元素的地址,而 *(p+1)(等價于 p[1])指的就是第二個元素地址存放的值,也就是 a+1

a+1*(p+1) 值是相等的。

4. 數組指針

表示指針是數組類型的,就像 int 類型指針,char 類型指針一樣。
定義方式:

int (*p)[n]

() 優先級高,首先說明 p 是一個指針,指向一個整型的一維數組,這個一維數組的長度是 n,也可以說是 p 的步長。

示例:

int main(int argc, char *argv[])
{int a[3] = {1,2,3};int (*p)[3] = &a;   //定義一個指向長度為 3 的 int 數組的指針std::cout << "a  = " << a << std::endl;     std::cout << "a+1= " << a+1 << std::endl;   std::cout << "p+1= " << p+1 << std::endl; std::cout << "a+2= " << a+2 << std::endl;  std::cout << "&a= " << &a << std::endl; std::cout << " p= " << p << std::endl;  std::cout << "*p= " << *p << std::endl;  return 0;   
}

輸出:

a  = 0x7ffd63226b30
a+1= 0x7ffd63226b34
p+1= 0x7ffd63226b3c
a+2= 0x7ffd63226b38
&a= 0x7ffd63226b30p= 0x7ffd63226b30
*p= 0x7ffd63226b30

&aap 值是相等的,都是指數組 a 的第一個元素的地址。

仔細看兩個值,可以發現 p+1(0x7ffd63226b3c)是 p(0x7ffd63226b30)再加 12,也就是數組 a 所有元素加起來的長度(長度 3*int 類型的 4 個字節),所以數組指針 p 再加 1,這里的 1 指的就是數組 a 所有元素加起來的長度,而不是數組元素的長度。

p*p 兩個值是一樣的。*p 的值是數組 a 第一個元素的地址,而 p 雖然也是數組 a 第一個元素的地址,但是 p 指的是整個數組的地址,只是用了數組 a 的第一個元素地址來替代,而 *p 是指這個數組的地址對應的值,就是數組本身,
也就是 a,而 a 的值也就是數組 a 第一個元素的地址,所以 *p 等于 a

int a[3] = {1,2,3};
int (*p)[3] = &a;
cout<<**p<<endl;
cout<<*(*p+1)<<endl;
cout<<(*p)[1]<<endl;

輸出:

1
2
2

*p 表示數組第一個元素地址,**p 表示數組第一個元素地址存放的值也就是 1;p+1 表示數組第二元素地址,(*p+1) 表示數組第二個元素地址存放的值也就是 2。(*p)[1] 與 *(*p+1) 值一樣,都是表示數組第二個元素值,即 a[1]。

如果改成下面:

int main(int argc, char *argv[])
{int a[3] = {1,2,3};int (*p)[3] = a;   return 0;
}

會編譯報錯:

cannot convert ‘int*’ to ‘int (*)[3]in initialization

因為 a 這里是一維數組,a 代表的是數組 a 首個元素地址,而不是整個數組地址。

假設 a 數組是二維數組,如下定義:

int main(int argc, char *argv[])
{int a[2][3] = {{1,2,3},{4,5,6}};int (*p)[3] = &a; return 0;
}

會編譯報錯:

cannot convert ‘int (*)[2][3]’ to ‘int (*)[3]in initialization

因為這里 a 是二維數組,而 &a 表示整個二維數組的地址,是包含 2*3=6 個元素的數組。那要怎么改才可以呢?

可以改成:

int (*p)[3] = a; // 這里 a 理解為二維數組 a 第一維 a[0][]數組的地址。

或者改為:

int (*p)[2][3] = &a; // 表示2行3列的二維數組地址

完整代碼:

int main(int argc, char *argv[])
{int a[2][3] = {{1,2,3},{4,5,6}};int (*p)[3] = a;   std::cout << "a= " << a << std::endl;     std::cout << "a+1= " << a+1 << std::endl;   std::cout << "a+2= " << a+2 << std::endl;  std::cout << "&a=" << &a << std::endl; std::cout << "p=" << p << std::endl;      std::cout << "*(p+1)=" << *(p+1) << std::endl;   std::cout << "p[1]=" << p[1] << std::endl;    std::cout << "**p=" << **p<< std::endl;  std::cout << "**(p+1)=" << **(p+1) << std::endl;     return 0;
}

輸出結果:

a= 0x7ffe52d671f0
a+1= 0x7ffe52d671fc
a+2= 0x7ffe52d67208
&a=0x7ffe52d671f0
p=0x7ffe52d671f0
*(p+1)=0x7ffe52d671fc
p[1]=0x7ffe52d671fc
**p=1
**(p+1)=4

5. 指針常量與常量指針

int main() 
{int a = 42;const int b = 84;const int *c_a_ptr = &a;    //常量指針int * const a_c_ptr = &a;   //指針常量int *b_ptr = &b;            //錯誤,不能把常量的地址給指針變量const int *c_b_prt = &b;    //把常量的地址給常量指針是允許的*c_a_ptr = 68;              //錯誤,間接引用常量指針不可修改內存中的數據*a_c_ptr = 68;              //間接引用指針常量可以修改內存中的數據c_a_ptr = &b;               //常量指針可以指向其他變量a_c_ptr = &b;               //錯誤,指針常量不能指向別的變量const int * const c_c_a_ptr = &a;   //常量指針常量,既不能間接引用修改數據,也不能指向別的變量或常量*c_c_a_ptr = 68;            //錯誤,不能間接引用修改數據c_c_a_ptr = &b;             //錯誤,不能指向別的常量或變量return 0;
}

總結

以上是生活随笔為你收集整理的C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针的全部內容,希望文章能夠幫你解決所遇到的問題。

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