簡體   English   中英

C中的指針,指向字符指針的整數指針

[英]Pointers in C, integer pointer to character pointer

當我運行此代碼時:

int arr[3] = {2,3,4};
char *p;
p = (char*)arr;
printf("%d", *p);
p = p+1;
printf("%d", *p);

輸出為2和0.第二個結果有點令人困惑。 有人可以解釋為什么會這樣嗎?

讓我們打破這個:

int arr[3] = {2,3,4};

創建一個包含3個整數的數組。 假設您的系統是32位小端,這就是它在內存中的外觀:

02 00 00 00 03 00 00 00 04 00 00 00

char *p; p = (char*)arr;

p現在指向arr但是指向char*的指針。 換句話說, p指向02

printf("%d", *p);

您將作為int打印由p引用的位置。 因此,當您取消引用 p (通過寫*p )時,您正在訪問由p引用的char (因為pchar*類型)。 這是02

p = p+1;

p現在指向02之后的00 ,因為pchar* 因此,當您添加1時,它將在內存中移動1 * sizeof(char) = 1 * 1 = 1個字節。

printf("%d", *p);

您將作為int打印由p引用的位置。 因此,當您取消引用 p (通過寫*p )時,您正在訪問由p引用的char (因為pchar*類型)。 這是00

如果要打印3而不是0 ,則必須將指針類型更改為int*而不是char* ,使指針在內存中移動1 * sizeof(int) = 1 * 4 = 4個字節。

獲得的結果取決於實現中int的大小及其endianness。

假設32位整數,8位字符和一個litte-endian環境(比如x86), arr在內存中會是這樣的:

<  arr[0]  > <  arr[1]  > <  arr[2] >
02 00 00 00  03 00 00 00  04 00 00 00
^  ^         ^
p  p+1 ...   p+4

如果您使用char指針指向該內存的開頭,並打印出第一個元素,則應輸出2 如果遞增該指針,則接下來將輸出0。 你需要將它增加幾倍才能“看到”3。

請注意,在具有相同類型大小的大端環境中,您的程序將輸出兩個零,因為布局將是:

<  arr[0]  > <  arr[1]  > <  arr[2] >
00 00 00 02  00 00 00 03  00 00 00 04
^  ^         ^
p  p+1 ...   p+4

這是因為稱為字節序的東西。

當你創建一個類似int arr[3] = {2, 3, 4};的數組時int arr[3] = {2, 3, 4}; 它在內存中創建如下

Big endian:
    0   1   2     3      4   5   6      7     8   9  10     11 
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+
  |   |   |   | ..0010 |   |   |   | ..0011 |   |   |   | ..0100 |
  +---+---+---+--------+---+---+---+--------+---+---+---+--------+

  <--       2       --><--       3        --><--        4      -->

Little endian:
       0     1   2    3    4   5   6      7     8       9  10   11 
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+
  | ..0010 |   |   |   |  ..0011 |   |   |   | ..0100 |   |   |   |
  +--------+---+---+---+---------+---+---+---+--------+---+---+---+

  <--       2       --><--       3        --><--        4      -->

要了解更多信息,您需要按如下方式修改程序:

int main(void)
{

    int arr[3] = {2, 3, 4};
    char *p = (char*) arr;  
    int i;
    int size = (int)sizeof(arr);

    for (i=0; i<size ; i++) {
        printf("%d", *p);
        p++;
    }

    return 0;
}

並且,要檢查硬件的字節順序,可以使用以下功能。

void endian(void)
{
        int i = 1;

        if (*(char *) &i == 1)
                printf("Little endian \n");
        else
                printf("Big endian \n");

        return;
}

這是一個粘貼,可以讓你更好地理解這個問題: http//codepad.org/ClrrwjKY

如您所見,連續整數的值以三個零分隔。 這是因為整數長度為4個字節,而char只有1個字節長。 因此,當int數組轉換為char時,您將逐字節(或char by char)迭代它,而不是四個字節(int by int)。

這里'p'是一個字符指針.. p + 1將p的當前值遞增1.由於數組是整數,為了逐個訪問數組的每個值,你必須增加字符數組由2.如果整數數組的地址是1000,

  arr[0] is at 1000
  arr[1] is at 1002
  arr[2] is at 1004

而arr的值是arr [0]的地址; 所以最初

 p=arr=1000

當p遞增時,p為1001而arr [1]為1002

..因此,為了訪問所有值,您必須每次增加p值兩次..

暫無
暫無

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

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