簡體   English   中英

簡單的指針算術問題

[英]Simple pointer arithmetic problems

問題1:

我正在閱讀K&R的書,我對某些事情感到有些困惑。 我對一些簡單的指針運算有點困惑。 如果我說

char (*a)[10];

我知道我剛剛聲明了一個指向10個字符數組的指針。 首先,因為我沒有malloc,所有這些仍然保留在堆棧上嗎? 所以堆棧中有這個指針指向大小為10的char數組的開頭嗎?

現在,如果我想訪問數組中的第二個元素,我還會做*(a + 2 * sizeof(char))嗎? 或者在這種情況下不起作用?

問題2:

如果我有

int* a = malloc(10*sizeof(int));

如果我想從整數數組中獲取第二個字節 ,我會這樣做:

*((char*)((char*)a+2))

這個對嗎?

謝謝。

第一件事

In C/C++, array index starts from 0 instead of 1 因此,如果要訪問第二個元素,則使用索引1,而不是2!

答案1

char (*a)[10];

是的,這是一個指向大小為10的數組的指針。指針本身位於堆棧上。 但它沒有指向任何有效的數組,對於這一行,這意味着它是單元化的。

要初始化指針,

char b[2][10] = {"123456789", "abcdefghi"};
// initialize pointer "a"
char (*a)[10] = b;

要訪問“second”元素,在這種情況下為“2”,您使用,

char (*a)[10] = b;
// access the element at 1st row, 2nd column
printf("%c\n", a[0][1]);

答案2

您想要訪問第二個字節。 但是,元素索引從0開始而不是1,因此對於第2個字節應該使用“+1”而不是“+2”!

*((char*)a+1);

當你聲明指針時,它還沒有指向任何東西。 你需要聲明一個10號字符大小的數組並將其地址分配給(*a)[10]如果你想要它在堆棧上。 至於訪問第二個元素,大多數編譯器可以為下一個元素執行*(a+1) (因此對於4個字節的int,*(a + 1)是第二個元素,而*(a + 4)是第4個元素(不是第4個字節)。

char (*a)[10];
char arrayTest[10];
a=&arrayTest;

在第二個問題中,獲取第二個字節將是*a ,然后只需執行右移:

char Test= ((*a)&0x7FFF)>>8;

問題1:

首先,因為我沒有malloc,所有這些仍然保留在堆棧上嗎?

指針在堆棧上聲明,但它還沒有指向任何東西。 你需要做類似的事情:

char (*a)[10];
char array[10];
a = &array;

否則a不指向任何東西,並且嘗試訪問它將導致問題。

現在,如果我想訪問數組中的第二個元素,我還會做* (a + 2 * sizeof(char))

您不需要說sizeof(char) ,因為編譯器將使用您正在使用的指針或數組的類型計算出添加的大小。 此外,如果你想要第二個元素,你需要加1而不是2(因為數組/指針從零開始索引)。

  • 如果你想要你指向的數組中的第二個元素,你可以做(*a)+1或者(*a)[1]

  • 如果你的指針指向多個數組,並且你想要第二個數組,則*(a+1)a[1]就是你想要的。


問題2:

(最好是下次打開多個問題:)

如果我想從整數數組中獲取第二個字節,我會這樣做: *((char*)((char*)a+2))

首先,當你說:當你說:

int* a = malloc(10*sizeof(int));

你有一個指向內存塊的指針,有足夠的空間容納10個整數 - 這不是一個數組。 如果這令人困惑,請參閱有關指針和數組C-FAQ

現在,如果你想要指向內存塊的第二個字節,你可以說:

char second_byte = *((char*)a+1);

因為強制轉換的優先級高於加法, a在執行加法時將a視為char* 但是,為了盡量減少閱讀代碼時誤解的可能性,我可能會寫:

char second_byte = *(((char*)a)+1);

或更好:

char second_byte = ((char*)a)[1];

代替。 請注意,原始示例中的額外強制轉換是不必要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM