[英]Is it possible to have the same array of pointers to struct point to different types of struct?
[英]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
我的問題是,我有兩個變量遞增, i
和ptr
,有些東西告訴我其中一個是多余的(也許我還沒有考慮 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.