繁体   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