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