![](/img/trans.png)
[英]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.