簡體   English   中英

我錯過了指針嗎?

[英]Have I missed the point of pointers?

對不好的雙關語抱歉:P

我在C中編寫HAL => IBM的舊技巧。我剛讀完了K&R中的前幾頁,我認為這對他們來說是一個很好的第一次。

char evil[] = "HAL";
char *ptr = evil;   
for (int i = 0; i < strlen(evil); ++i, ++ptr) {             
    (*ptr)++;           
}   
printf("%s\n", evil); // IBM

我的問題是,我有兩個變量遞增, iptr ,有些東西告訴我其中一個是多余的(也許我還沒有考慮 C足夠好)。

我使用i的唯一原因是確定我們是否已讀到字符串的末尾。 有沒有辦法檢查指針,看它是否已到達字符串的末尾?

更新

對不起任何實際問題的混淆。 我錯過了我基本上意味着什么,當我需要一個遞增索引來檢查長度時,為什么我會使用指針。 我可以使用該索引從數組中下標右邊的char。

你也可以寫

for (char *ptr = evil; *ptr != '\0' ; ++ptr)

我輸入了問題,重新閱讀,然后意識到我忽略了一些非常明顯的事情!

char evil[] = "HAL" 
char *ptr = evil;   
for (; *ptr != '\0'; ++ptr) {                       
    (*ptr)++;           
}   
printf("%s\n", evil);

這似乎成功了。

您已經找到了正確的實現,但我仍然想對您的原始代碼提出一點意見,這可能會讓您以不同的方式思考這些問題。

您的原始解決方案可能比您想象的更糟糕,因為它的復雜性實際上是O(n ^ 2),其中n是字符串的長度。 strlen()的復雜度為O(n),因為它必須迭代字符串中的所有字符,直到找到'\\0' 所以你有一個執行n次迭代的循環,每次調用strlen() ,導致O(n ^ 2)的復雜性。

至少你應該在循環之前調用strlen()一次,並緩存字符串的長度。 當然,你有正確的解決方案,根本不會調用strlen()

C字符串中以'\\0'結尾。 您可以使用該事實來停止循環。

for (; *ptr != '\0' ; ++ptr) {
    /* ... */
}

指向的字符將是'\\0' 但要小心,錯放NUL字節可能是程序崩潰或安全​​漏洞的來源。

調用strlen(evil)是低效的。 而不是依賴strlen ,使用使strlen停止的相同的東西:null終止符:

for (char *ptr = evil; *ptr; ++ptr) {             
    (*ptr)++;           
}

這樣可以解決問題:

char evil[] = "HAL";
*(int*) evil += 65793;
printf("%s\n", evil);

既然我們在談論邪惡:

#include <stdio.h>

int main()
{
    char evil[] = "HAL";
    char *ptr;

    // Increment the pointer and its content in the same expression
    // Just to be really evil

    for (ptr = evil; *ptr != '\0'; ++*(ptr++)) { }

    printf("%s\n", evil);
}

暫無
暫無

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

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