c语言指针的地址存放,c语言 - *指针 和 地址
最近在研究oc的底層,全是c/c++的代碼,雖然以前學(xué)過也寫過,其實(shí)不怎么用都忘得差不多了。
首先我們來了解一下 * 和 &這兩個(gè)符號(hào)
通俗點(diǎn)兒理解其實(shí)&地址就是就是一個(gè)存放地址的變量存儲(chǔ)空間,當(dāng)p指針指向某個(gè)變量,這時(shí)這個(gè)p指針里就存放了那個(gè)變量的地址。這就是我們常說的指針指向一個(gè)地址,意思是通過它能找到以它為地址的內(nèi)存單元。利用指針我們可以直接獲取變量中的值用,要是在指針前加 * 就是取其真值了(也就是被指向的變量的值)
//寫一串代碼
int arr[5] = {1,2,3,4,5};
int * p = &arr[0];
首先初始化了在32位RAM處理器中的arr數(shù)組占20個(gè)字節(jié)(int 占用4個(gè)字節(jié),32比特),然后我們定義了 一個(gè)int 類型的指針變量p,指針p指向了&arr[0] 也就是 arr數(shù)組的第一個(gè)元素地址。
聲明中: * 表示指針,例如: int p,p是指針,指向整型量。p表示指針指向的整型量的值。
語句中,p表示指針指向的地址。如果p是指針,沒有 &p 形式。二、 x指令:
聲明中:a是整型量。&a是整型量a的地址,不是指針。
語句中:a是整型量a的值。&另一用途是按位運(yùn)算符,按位* 是乘號(hào)。
此時(shí)此刻,你是不是對(duì)指針變量和地址有了一定的認(rèn)知了。指針也不過如此嘛?
在此之前我們先看下下列問題
int arr[5] = {1,3,5,7,9};
arr = ?
arr[0] = ?
&arr = ?
&arr[0] = ?
&arr+1 = ?
&(arr + 1) = ?
lldb打印內(nèi)容:
(lldb) po arr[0]
1
(lldb) po arr
(lldb) po &arr
0x00007ffeefbff4c0
(lldb) po &arr[0]
0x00007ffeefbff4c0
(lldb) po &arr + 1
0x00007ffeefbff4d4
(lldb) po &arr[1]
0x00007ffeefbff4c4
(lldb) po (arr + 1)
0x00007ffeefbff4c4
(lldb) po *(arr + 1)
3
先打印了 arr[0] 等于1。
再打印了 arr 什么也沒打印出來
再打印了 &arr arr數(shù)組的首地址
再打印了 &arr[0] arr數(shù)組首元素地址
再打印了&arr + 1未知地址
再打印了&arr[1] arr數(shù)組第二個(gè)元素的地址
再打印了 arr + 1 arr數(shù)組第二個(gè)元素的地址
在打印了 *(arr + 1) arr數(shù)組第二個(gè)元素
此時(shí)此刻 其實(shí)我們只有一個(gè)疑問 arr 到底是什么?
arr 是數(shù)組名稱, &arr表示數(shù)組首地址,arr表示數(shù)組首元素地址
這個(gè)結(jié)論是怎么來的呢?
由arr + 1 和 &arr + 1的結(jié)果不同
說明一下 地址 + int
后面的int所代表的字節(jié)是根據(jù)當(dāng)前地址類型來
假如前面的地址所代表的是元素類型地址那么所加的 元素字節(jié)為int * 單個(gè)元素的字節(jié)
假如前面的地址所代表的是數(shù)組類型地址那么所加的 元素字節(jié)為int * 數(shù)組的字節(jié)
然后再根據(jù)元素字節(jié)獲取當(dāng)前地址
arr + 1 是arr數(shù)組第二個(gè)元素的地址,所以arr表示數(shù)組首元素地址,&arr + 1未知地址 說明此時(shí)的地址已經(jīng)越過了當(dāng)前數(shù)組內(nèi)的地址
int arr[5] = {1,3,5,7,9};
int * p = (int*)(&arr+1);
printf("%d\n",*(p-2));
打印7
此時(shí)此刻 p 指向&arr + 1的地址 ,也就是超越了數(shù)組界限的下一個(gè)地址。 我們用p-2往上走了8個(gè)字節(jié),也就到了數(shù)組的倒數(shù)的第二個(gè)元素的地址。由此看來 &arr表示數(shù)組首地址。
那么猜想一下&arr +2的地址呢?
小試牛刀:
1.請(qǐng)寫出以下代碼輸出
int a[5] = {1,3,5,7,9};
int *ptr = (int*)(&a+1);
printf("%d, %d", *(a + 1), *(ptr - 1));
解析:
&a : 代指 數(shù)組的整體 的地址,這里的 a是數(shù)組整體
a+1: 代指 數(shù)組的第一個(gè)成員,這里的 a是數(shù)組首地址
2.寫一個(gè)標(biāo)準(zhǔn)宏Max,并給出以下代碼的輸出
int array[5] = {1, 2, 3, 4, 5};
int *p = &array[0];
int max = Max(*p++, 1);
printf("%d %d", max, *p);
參考答案: 1,2
#define Max(X, Y) ((X) > (Y) ? (X) : (Y))
當(dāng)看到宏時(shí),就會(huì)想到宏定義所帶來的副作用。對(duì)于++、–,在宏當(dāng)中使用是最容易產(chǎn)生副作用的,因此要慎用。
分析:
p指針指向了數(shù)組array的首地址,也就是第一個(gè)元素對(duì)應(yīng)的地址,其值為1.
宏定義時(shí)一定要注意每個(gè)地方要加上圓括號(hào)
*p++相當(dāng)于*p, p++,所以Max(*p++, 1)相當(dāng)于:
(*p++) > (1) ? (*p++) : (1)
=>
(1) > (1) ? (*p++) : (1)
=>
第一個(gè)*p++的結(jié)果是,p所指向的值變成了2,但是1 > 1為値,所以最終max的值就是1。而后面的(*p++)也就不會(huì)執(zhí)行,因此p所指向的地址對(duì)應(yīng)的值就是2,而不是3.
擴(kuò)展:如果上面的*p++改成*(++p)如何?
(*++p) > (1) ? (*++p) : (1)
=>
(2) > (1) ? (*++p) : (1)
=>
max = *++p;
=>
*p = 3,max = 3;
3.請(qǐng)寫出c語言整型和字符型數(shù)組的所有定義方法,并根據(jù)該文章寫出打印出的相對(duì)應(yīng)的地址代表什么
4.鏈表和數(shù)組的區(qū)別
5.單向鏈表和雙向鏈表的區(qū)別
6.請(qǐng)寫出以下代碼的輸出
int i[] = {10, 20, 30, 40, 50};
int *pa[] = {i, i+2, i+1, i+4, i+3};
int **p = pa;
printf("Initial **p = %d\n", **p);//10
p++;
printf("After p++, the **p = %d\n", **p);//30
++*p;
printf("After ++*p, the **p = %d\n", **p);//40
**p++;
printf("After **p++, the **p = %d\n", **p);//20
++**p;
printf("After ++**p, the **p = %d\n", **p);//21
Initial **p = 10
After p++, the **p = 30
After ++*p, the **p = 40
After **p++, the **p = 20
After ++**p, the **p = 21
定義分析 : (右結(jié)合性)
int i[] = {10, 20, 30, 40, 50}; //定義一個(gè)一維整型數(shù)組
int *pa[] = {i, i+2, i+1, i+4, i+3};//定義一個(gè)指針數(shù)組pa,pa[0],pa[1]分別執(zhí)行I數(shù)組的某一個(gè)元素的地址
int **p = pa;//定一個(gè)二重指針(指向指針的指針)p 指向的是pa的地址既&pa(既指針數(shù)組pa的首地址的地址),
printf("Initial **p = %d\n", **p);//10
p++;//p++ 運(yùn)行后表示p指向針數(shù)組pa的首地址的下一個(gè)地址
printf("After p++, the **p = %d\n", **p);//30
++*p;//右結(jié)合性 相當(dāng)于++(*p),*p表示指針數(shù)組pa的第二個(gè)元素的值既整型數(shù)組i的第3個(gè)地址,++后*p指向整型數(shù)組i的第4個(gè)地址,p指向指針數(shù)組pa的第二個(gè)元素的地址
printf("After ++*p, the **p = %d\n", **p);//40
**p++;//右結(jié)合性 相當(dāng)于**(p++),此時(shí)p指向指針數(shù)組pa的第二個(gè)元素的地址,++后p指向指針數(shù)組pa的第三個(gè)元素的地址
printf("After **p++, the **p = %d\n", **p);//20
++**p;//右結(jié)合性 相當(dāng)于++(**p),此時(shí)p指向指針數(shù)組pa的第三個(gè)元素的地址,**p則為整型數(shù)組的第二個(gè)元素的值,++后 **p = 21
printf("After ++**p, the **p = %d\n", **p);//21
總結(jié)
以上是生活随笔為你收集整理的c语言指针的地址存放,c语言 - *指针 和 地址的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: java jdk最新版本是多少_Linu
- 下一篇: EOS