簡體   English   中英

c將指針轉換為int *的char數組與將char *轉換為int *的結果相同

[英]c casting a pointer to a char array as an int* gives the same result as casting a char* as an int*

考慮下面的C程序:

#include <stdio.h>
#include <stdlib.h>
int main(){
    char c[1] = {'Q'};
    printf("%c ",*(char*)(c));   // line 1
    printf("%c\n",*(char*)(&c));  // line 2
}

輸出是QQ

這是我對應該發生的情況的理解,c是指向char的指針,因此第1行打印的char應該是字母Q,因為指向char的指針被轉換為指向char的指針(因此什么也沒有發生),然后已取消引用。 因為c指向的字符是'Q',所以第1行打印'Q'。 這對我來說似乎很有意義。

但是第2行則沒有。 c的地址被強制轉換為指向char的指針,因此我認為應該發生的事是在取消引用表達式*(char *)(&c)后應簡化為指針c的值,但應將其表示為char。

這些都給出相同的結果,我不認為這是巧合,因為我已經在許多不同的字母上嘗試過。 我想知道為什么會這樣。 謝謝

PS:
我嘗試了這個:

#include <stdio.h>
#include <stdlib.h>
int main(){
    char c[10] = "asdf";
    printf("%c ",*(char*)(c));   // line 1
    printf("%c\n",*(char*)(&c));  // line 2
}

我得到這個: aa

在聲明中

char c[1] = {'Q'};

c是char數組和array namec本身表示該數組的基地址。 如果打印c&c ,則結果相同。

注意: c表示其指向數組第一個元素的指針, &c表示其指向整個數組的指針。

int main(void){
        char c[1] = {'Q'};
        printf("%p %p\n",(void*)c,(void*)&c); /* bot results the same */
        return 0;
}

這就是為什么*(char*)(c)*(char*)(&c)得出相同結果的原因。 例如

char c[10] = "asdf"; /* lets assume base address of c is 0x100 */

看起來像

 --------------------------------------
 |  a   |   s   |   d   |  f   | \0   |
 --------------------------------------
0x100   0x101   0x102 ..
c

接下來如何執行這兩個表達式*(char*)(c)*(char*)(&c)

*(char*)(c)  =>  *(char*)(0x100)  => typecasted as char* means c points to 1 byte memory 
             =>   *(0x100)        => value in the first byte from 0x100 to 0x101 => a

*(char*)(&c)     =>  *(char*)(&(0x100)) => *(char*) (0x100) => c and &c are same 
                 =>   *(0x100)          => value in the first byte from 0x100 to 0x101 => a

如果考慮等式(void*) c == (void*) &c ,您將意識到它在邏輯上是正確的。 以一個靜態分配的整數為例:

int myvar = 2;

打印myvar的值很有意義,因為它是一個整數並且可以“普遍”識別。

現在如何識別數組? 顯然帶有該存儲器的地址。

但是,如何打印呢? 沒有規則。 如果沒有理由這樣做,區分c&c有什么意義呢? 可以推測c可以解釋為數組的第一個元素,但是您可以想象這種選擇的所有缺點。

編譯器的推理實際上是不同的,特別是因為變量不存在,因此它用可以使用的變量替換了它們。

以以下片段為例:

int a = 2;
char c[6] = {'a', 'b', 'c', 'd', 'e', '\0'};

printf("%p\n",  c);
printf("%p\n", (void*) &c);
printf("%d\n", a);
printf("%p\n", (void*) &a);

這是gcc生成的生成的程序集(intel語法):

    mov     DWORD PTR [rbp-4], 2     # int a = 2;
    mov     BYTE PTR [rbp-16], 97    # char c[6] = {'a', 'b', 'c', 'd', 'e', '\0'};
    mov     BYTE PTR [rbp-15], 98
    mov     BYTE PTR [rbp-14], 99
    mov     BYTE PTR [rbp-13], 100
    mov     BYTE PTR [rbp-12], 101
    mov     BYTE PTR [rbp-11], 0
    lea     rax, [rbp-16]            # printf("%p\n",  c);
    mov     rsi, rax
    mov     edi, OFFSET FLAT:.LC0
    mov     eax, 0
    call    printf
    lea     rax, [rbp-16]            # printf("%p\n", (void*) &c);
    mov     rsi, rax
    mov     edi, OFFSET FLAT:.LC0
    mov     eax, 0
    call    printf
    mov     eax, DWORD PTR [rbp-4]   # printf("%d\n", a);
    mov     esi, eax
    mov     edi, OFFSET FLAT:.LC1 [complete object constructor] [complete object constructor]
    mov     eax, 0
    call    printf
    lea     rax, [rbp-4]             # printf("%p\n", (void*) &a);
    mov     rsi, rax
    mov     edi, OFFSET FLAT:.LC0
    mov     eax, 0
    call    printf

編譯器以相同的方式解釋c&c

暫無
暫無

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

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