簡體   English   中英

C 語言。 這是指針比較還是其他?

[英]C language. Is this pointers comparison or something else?

我一直在學習 Python 一段時間,現在我發現自己正在探索一些 C 基礎知識。 在閱讀了有關指針的內容后,我使用了一些相關的語法,並編寫了一個非常簡單的腳本:

#include <stdio.h>

int main(void)
{
    char *k_ptr = "home";
    char *j_ptr = "pen";

    printf("string: %s, address: %p\n", k_ptr, &k_ptr);
    printf("string: %s, address: %p\n", j_ptr, &j_ptr);

    if (k_ptr == j_ptr)
    {
        printf("It's equal.\n");
    }
    else
    {
        printf("It's not equal\n.");
    }
}

我了解到在 C 中,可以使用 strcmp() 進行字符串比較,而數組比較始終為 false。 但是之后:

-當我比較 k_ptr == j_ptr 時,我實際上在比較什么?

- 如果這不是字符串比較,為什么如果兩個字符串相等或不相等,程序會正確返回?

- 為什么這種語法似乎只在我使用字符串時才有效?

你聲明了兩個指針

char *k_ptr = "home";
char *j_ptr = "pen";

指向用作初始值設定項的相應字符串文字的第一個字符。

也就是說,指針k_ptr包含第一個字符串文字的字母'h'的地址,而指針j_ptr包含第二個字符串文字的字母'p'的地址。

字符串字面量占據 memory 的不同范圍。 所以這個比較

if (k_ptr == j_ptr)

總是會產生錯誤。 那就是字符串文字的地址(它們的第一個字符)是不同的。

考慮到即使你會寫例如

char *k_ptr = "Hello";
char *j_ptr = "Hello";

那么沒有必要比較的結果

if (k_ptr == j_ptr)

將產生真實的。 結果取決於編譯器選項。 編譯器可以將相同的字符串文字存儲為一個字符串文字或兩個不同的字符串文字。

來自 C 標准(6.4.5 字符串文字)

7如果這些 arrays 的元素具有適當的值,則不確定它們是否不同。 如果程序試圖修改這樣的數組,則行為未定義。

如果您想比較字符串文字本身而不是它們的地址,那么您需要使用在 header <string.h>中聲明的標准 C 字符串 function strcmp

例如

if ( strcmp( k_ptr, j_ptr ) == 0 )
{
    // string literals are equal
}

至於你的問題

-why this syntax seems to work only if I use strings?

那么字符串文字是未命名的字符 arrays。 在表達式中使用它們隱式轉換(極少數例外)到指向其第一個元素的指針。

實際上,您可以使用與例如 integer arrays 相同的語法

int a[] = { 1, 2, 3 };
int *p = a;

現在指針p指向數組a的第一個元素。

當我比較 k_ptr == j_ptr 我實際上在比較什么?

您正在比較一個整數類型的值,該值表示 memory 中數據的地址。 您在printf語句中顯示的地址是指針本身的地址,而在這里您正在比較指針指向的地址。

如果這不是字符串比較,為什么如果兩個字符串相等或不相等,程序會正確返回?

這是常數值優化。 如果編譯器第二次在代碼中看到相同的字符串常量,它會將其引用到相同的 memory。 雖然它不可靠,所以你根本不應該依賴這種行為。 順便說一句,當您使用is運算符比較字符串時,Python 也會發生同樣的情況。 兩個不同的字符串對象不是同一個 object,所以操作符應該返回False ,但是如果你在這樣一個簡單的程序中嘗試它會返回True 這與在兩個不同的程序(GCC 和 CPython)中實現的優化相同。

為什么這種語法似乎只在我使用字符串時才有效?

因為它們是指向常量值的指針,所以可以進行這種優化。

當我比較 k_ptr == j_ptr 我實際上在比較什么?

k_ptr是一個指針。 j_ptr是一個指針。 k_ptr == j_ptr測試它們是否指向同一個地方。

- 如果這不是字符串比較,為什么如果兩個字符串相等或不相等,程序會正確返回?

如果兩個指針指向同一個地方,那么它們指向的東西當然等於它自己。 如果它們指向不同的地方,它們指向的東西可能相等也可能不相等,因此比較指針與比較它們所指向的東西是不一樣的。

- 為什么這種語法似乎只在我使用字符串時才有效?

這沒用。

-當我比較 k_ptr == j_ptr 時,我實際上在比較什么?

您正在比較指針值本身,而不是它們指向的數據。 有效的指針值是對象的地址。 當且僅當它們指向相同的 object 時,相同類型的兩個有效指針值才相等。

- 如果這不是字符串比較,為什么如果兩個字符串相等或不相等,程序會正確返回?

因為不同的字符串必然有不同的地址。 指針比較判斷兩個指針是否指向同一個object,而不考慮指向對象的值。

請注意,在這個意義上,通過strcmp()比較相等的不同字符串是可能的。 一種比較與另一種無關。

- 為什么這種語法似乎只在我使用字符串時才有效?

目前還不清楚你的意思是什么語法。 您的程序中幾乎沒有特定於字符串的內容,但是您當然不能編寫隨機亂碼並期望 C 編譯器接受它。

當然,您可以對其他類型的指針執行==比較,它的意義與我已經描述的相同。

暫無
暫無

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

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