我错过了指针吗?

ale*_*lex 3 c

对不好的双关语抱歉:P

编写HAL => IBMC中的旧技巧.我刚读完了K&R中的前几页,我认为这对他们来说是一个很好的第一次播放.

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

我的问题是,我有两个变量递增,i并且ptr,有些东西告诉我其中一个是多余的(也许我仍然没有想到 C足够好).

我使用的唯一原因i是确定我们是否已读到字符串的末尾.有没有办法检查指针,看它是否已到达字符串的末尾?

更新

对不起任何实际问题的混淆.通过我错过了我基本上意味着什么,当我需要一个递增索引来检查长度时,为什么我会使用指针.我可以使用该索引从数组中下标右边的char.

teu*_*kam 11

你也可以写

for (char *ptr = evil; *ptr != '\0' ; ++ptr)
Run Code Online (Sandbox Code Playgroud)

  • 在C99中,记住是件好事.某些编译器需要额外的开关来启用C99模式. (3认同)
  • 我个人更喜欢'0`.在C中,字符文字是整数,因此在技术上甚至不比较字符.更糟糕的是:'\ 0'表示的是"整数值为0的字符的整数值".根据我的口味,这是一个圆形的房子.但是,我通常也使用"0"而不是"NULL".就标准而言,它们都是空指针常量,我需要的只是一个空指针常量.如果有人不知道我正在比较的变量是int/pointer/char它们是我的帮助,他们需要检查定义;-) (3认同)
  • `*ptr!='\ 0'`更正确.NUL和NULL是非常不同的野兽虽然NULL退化为int,如果需要,其值为0,NUL(它只是一个值为0的char)在需要时被提升为int.这种比较是偶然的,这就是为什么我更喜欢更明确的''\ 0'. (2认同)

ale*_*lex 6

我输入了问题,重新阅读,然后意识到我忽略了一些非常明显的事情!

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

这似乎成功了.

  • 你可以通过初始化ptr来使for循环更清晰:`for(ptr = evil;*ptr!='\ 0'; ptr ++)`.但要小心.一个错误的字符串(没有空终止符)将使您的程序愉快地在堆栈中踩踏. (2认同)

Dim*_*ima 5

您已经找到了正确的实现,但我仍然想对您的原始代码提出一点意见,这可能会让您以不同的方式思考这些问题.

您的原始解决方案可能比您想象的更糟糕,因为它的复杂性实际上是O(n ^ 2),其中n是字符串的长度. strlen()具有O(n)的复杂度,因为它必须迭代字符串中的所有字符,直到找到它为止'\0'.所以你有一个执行n次迭代的循环,strlen()每次都调用,导致O(n ^ 2)的复杂性.

至少你应该strlen()在循环之前调用一次,并缓存字符串的长度.当然,你有正确的解决方案,根本不打电话strlen().