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 我們拿到抽屜的鑰匙(地址)打開抽屜取出數(shù)據(jù)。
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. 數(shù)組和指針
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;
}
執(zhí)行輸出結果:
p is 0x7fff7b96be40
&a is 0x7fff7b96be40
a is 0x7fff7b96be40
&a[0] is 0x7fff7b96be40
*p=1
*(p+1)=2
a[1]=2
a 的值就是數(shù)組 a 第一個元素的地址,與 &a[0] 和 &a 等價。
而 p+1 表示的是數(shù)組 a 的第二個元素的地址,以此類推。
獲取數(shù)組的第二個元素可以是 a[1],也可以是 *(p+1)。
3. 指針數(shù)組
表示數(shù)組內存放的是指針類型的數(shù)據(jù)。
定義方式
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
a、a+1、a+2 分別表示數(shù)組 a 第一個、第二個、第三個元素的地址。
p+1 指的是指針數(shù)組 p 的第二個元素的地址,而 *(p+1)(等價于 p[1])指的就是第二個元素地址存放的值,也就是 a+1。
a+1 與 *(p+1) 值是相等的。
4. 數(shù)組指針
表示指針是數(shù)組類型的,就像 int 類型指針,char 類型指針一樣。
定義方式:
int (*p)[n]
() 優(yōu)先級高,首先說明 p 是一個指針,指向一個整型的一維數(shù)組,這個一維數(shù)組的長度是 n,也可以說是 p 的步長。
示例:
int main(int argc, char *argv[])
{int a[3] = {1,2,3};int (*p)[3] = &a; //定義一個指向長度為 3 的 int 數(shù)組的指針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
&a 與 a、p 值是相等的,都是指數(shù)組 a 的第一個元素的地址。
仔細看兩個值,可以發(fā)現(xiàn) p+1(0x7ffd63226b3c)是 p(0x7ffd63226b30)再加 12,也就是數(shù)組 a 所有元素加起來的長度(長度 3*int 類型的 4 個字節(jié)),所以數(shù)組指針 p 再加 1,這里的 1 指的就是數(shù)組 a 所有元素加起來的長度,而不是數(shù)組元素的長度。
p 與 *p 兩個值是一樣的。*p 的值是數(shù)組 a 第一個元素的地址,而 p 雖然也是數(shù)組 a 第一個元素的地址,但是 p 指的是整個數(shù)組的地址,只是用了數(shù)組 a 的第一個元素地址來替代,而 *p 是指這個數(shù)組的地址對應的值,就是數(shù)組本身,
也就是 a,而 a 的值也就是數(shù)組 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 表示數(shù)組第一個元素地址,**p 表示數(shù)組第一個元素地址存放的值也就是 1;p+1 表示數(shù)組第二元素地址,(*p+1) 表示數(shù)組第二個元素地址存放的值也就是 2。(*p)[1] 與 *(*p+1) 值一樣,都是表示數(shù)組第二個元素值,即 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 這里是一維數(shù)組,a 代表的是數(shù)組 a 首個元素地址,而不是整個數(shù)組地址。
假設 a 數(shù)組是二維數(shù)組,如下定義:
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 是二維數(shù)組,而 &a 表示整個二維數(shù)組的地址,是包含 2*3=6 個元素的數(shù)組。那要怎么改才可以呢?
可以改成:
int (*p)[3] = a; // 這里 a 理解為二維數(shù)組 a 第一維 a[0][]數(shù)組的地址。
或者改為:
int (*p)[2][3] = &a; // 表示2行3列的二維數(shù)組地址
完整代碼:
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; //錯誤,間接引用常量指針不可修改內存中的數(shù)據(jù)*a_c_ptr = 68; //間接引用指針常量可以修改內存中的數(shù)據(jù)c_a_ptr = &b; //常量指針可以指向其他變量a_c_ptr = &b; //錯誤,指針常量不能指向別的變量const int * const c_c_a_ptr = &a; //常量指針常量,既不能間接引用修改數(shù)據(jù),也不能指向別的變量或常量*c_c_a_ptr = 68; //錯誤,不能間接引用修改數(shù)據(jù)c_c_a_ptr = &b; //錯誤,不能指向別的常量或變量return 0;
}
總結
以上是生活随笔為你收集整理的C++ 笔记(27)— 指针变量、数组和指针、指针数组、数组指针、指针常量与常量指针的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2022-2028年中国氯磺化聚乙烯橡胶
- 下一篇: 2022-2028年中国超韧尼龙行业市场