我試圖理解二維陣列中的一些東西。
int A[2][3] = {{20, 30, 40}, {50, 60, 70}};
printf("%p\n",A); // Output is 0x7ffde7e966d0
printf("%p\n",*A); // Output is 0x7ffde7e966d0
我知道這兩個地址具有不同的范圍并且A 1與地址完全不同*A 1,但我的主要誤解是在使用 derefrence 運算子時它應該產生一個值而不是地址。看起來二維陣列的名稱就像一個指向自身的指標。我試過這段代碼
int *p = &p;
printf("%p\n",p); // Output is 0xfff1c9a94b0
printf("%p\n",*p); // Output is 0x1c9a94b0
編譯器給了我一個警告
initialization of ‘int *’ from incompatible pointer type ‘int **’ [-Wincompatible-pointer-types]
,但代碼運行如上所示。如果我嘗試添加更多 astricsint **p = &p; the compiler warning will be like ``int **’ from incompatible pointer type ‘int ***
并且奇怪的是輸出地址對于從右到左的前 8 位或 7 位數字始終相同。在這種情況下,我們可以呼叫*p一個指向它自身的指標嗎?
uj5u.com熱心網友回復:
如果要生成一個值,請使用適當的格式字串和型別轉換:
int A[2][3] = {{20, 30, 40}, {50, 60, 70}};
A[0][0]=1;
printf("%p\n",A); // Output is 0x7ffde7e966d0
printf("%p\n",*A); // Output is 0x7ffde7e966d0
printf("%d\n",*(int *)A); // Output is 1
如果是:
int *p = &p;
你只是基本上這樣做:
int *p
p=&p;
這不言自明:它是堆疊中 p 的地址
uj5u.com熱心網友回復:
對于陳述句:
printf("%p\n",A); // Output is 0x7ffde7e966d0
printf("%p\n",*A); // Output is 0x7ffde7e966d0
首先要注意的是,這會呼叫未定義的行為,因為%p說明符需要一個 void 指標:
printf("%p\n",(void*)A); // Output is 0x7ffde7e966d0
printf("%p\n",(void*)*A); // Output is 0x7ffde7e966d0
其次,上述陳述句將產生相同的地址,因為 的地址A將是其第一個元素的地址,它A[0]實際上與*(A 0)wich 相同*A,它也是指向陣列第一個元素的指標。
為了 :
int *p = &p;
printf("%p\n",p); // Output is 0xfff1c9a94b0
printf("%p\n",*p); // Output is 0x1c9a94b0
上述代碼片段的行為是未定義的,無論您添加的間接級別如何,您總是會遇到型別不匹配,因為您正在分配相同型別變數的地址。在這種特殊情況下,您獲得的值的解釋可能歸因于int通常為 4 位元組和int*通常為 8 位元組的大小差異,但同樣未定義的行為是未定義的,并且沒有準確的診斷它,結果可以是任何東西。
uj5u.com熱心網友回復:
您的printf呼叫有些不正確:即使在衰減到指向其第一個元素的指標之后,它也不是,%p也不void *是A。*A
考慮這個簡單的例子:
#include <stdio.h>
int main() {
int A[2][3] = {{20, 30, 40}, {50, 60, 70}};
printf("&A=%p &A 1=%p sizeof(*&A)=%zu\n", (void*)(&A), (void*)(&A 1), sizeof(*&A));
printf(" A=%p A 1=%p sizeof( *A)=%zu\n", (void*)( A), (void*)( A 1), sizeof( *A));
printf("*A=%p *A 1=%p sizeof(**A)=%zu\n", (void*)(*A), (void*)(*A 1), sizeof(**A));
return 0;
}
在我的系統上,輸出是:
&A=0x7fff5b9877a0 &A 1=0x7fff5b9877b8 sizeof( A)=24
A=0x7fff5b9877a0 A 1=0x7fff5b9877ac sizeof( *A)=12
*A=0x7fff5b9877a0 *A 1=0x7fff5b9877a4 sizeof(**A)=4
&A為和生成的地址之間的區別&A 1是sizeof(*&A),與sizeof(A)... 相同,接下來的 2 個陳述句也相同。
A是一個由 2 個 3 個整陣列成的陣列。在記憶體中,它被實作為一個 24 位元組的序列,6 個整數中的每一個都有 4 個(在具有 32 位int和 8 位位元組的系統上,這是當今最常見的值)。這 24 個位元組位于記憶體中由定義位置確定的特定地址。陣列A,它的第一個元素A[0](本身就是一個陣列,可以稱為*A,甚至0[A])并且A[0][0]都位于同一個位置,即 first 的第一個位元組的地址int。
uj5u.com熱心網友回復:
首先你應該知道指標只是一個變數,它不是保存一些數字或字符,而是保存另一個變數的地址。當您鍵入時int *p,“*”表示指標,“int”表示將分配給該指標的地址只能是整數型別物件的地址。當您說它int **p創建一個只能保存整數指標物件(指向指標的指標)地址的指標時。所以這意味著即使是指標也有它們的記憶體地址。
像這樣的運算式中的“&”int *p = &p符號意味著指標 p 將保存指標的記憶體地址p。這是無效的,因為指標p只能保存整數的地址,而不是“整數指標”的地址——它們是兩個獨立的東西。
但是有 void pointers( void *p) 可以保存任何型別物件的地址。我認為此頁面將幫助您理解。是的,您可以創建一個指向自身的指標void *p = &p。這是可以實作的,因為p在這種情況下指標不限于特定型別。
uj5u.com熱心網友回復:
根據 C 標準(6.3.2.1 左值、陣列和函式指示符)
3 除非它是 sizeof 運算子或一元 & 運算子的運算元,或者是用于初始化陣列的字串字面量,否則型別為 ''array of type'' 的運算式將轉換為型別為 ''pointer 的運算式鍵入指向陣列物件的初始元素且不是左值的''。如果陣列物件具有暫存器存盤類,則行為未定義。
考慮以下演示程式。
#include <stdio.h>
int main( void )
{
int a[] = { 1, 2, 3, 4, 5 };
printf( "sizeof( a ) = %zu\n", sizeof( a ) );
printf( "sizeof( a 0 ) = %zu\n", sizeof( a 0 ) );
}
它的輸出可能看起來像
sizeof( a ) = 20
sizeof( a 0 ) = 8
在運算式a 0中,陣列指示符a被隱式轉換為指向其第一個元素的指標。那就是運算式有型別int *。
在您的代碼片段中
int A[2][3] = {{20, 30, 40}, {50, 60, 70}};
printf("%p\n",A); // Output is 0x7ffde7e966d0
printf("%p\n",*A); // Output is 0x7ffde7e966d0
*A與 相同的運算式A[0]產生陣列的第一個元素A。它有型別int[3]。但用作函式引數時,這個一維陣列被隱式轉換為指向其第一個元素的 int * 型別的指標。實際上它等價于運算式&A[0][0]。
至于您的問題是否可以通過其地址初始化指標,那么void *可以通過這種方式初始化該型別的指標。
這是一個演示程式。
#include <stdio.h>
int main( void )
{
void *p = &p;
printf( "p = %p\n", p );
printf( "&p = %p\n", &p );
}
程式輸出為
p = 0x7fff3bef8dd8
&p = 0x7fff3bef8dd8
int *對于您需要使用強制轉換的型別的指標
int *p = ( int * )&p;
或者
int *p = ( void * )&p;
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/474695.html
下一篇:按前一個值的百分比排列
