有人可以解释这个C代码吗?

时间:2014-04-06 11:25:36

标签: c string char

有人可以为我解释这个反向句子代码吗?第一个和第二个循环如何工作?他们每个人的重点是什么?

main(){
    char arr[255], *p;

    printf("Enter string: ");
    gets(arr);

    for(p=arr; *p!='\0'; p++);

    for(p--; p>=arr; p--){
       printf("%c",*p);
    }
}

输入:

I love you

输出:

uoy evol I

4 个答案:

答案 0 :(得分:2)

代码基本上是反向打印输入数组。

for(p=arr; *p!='\0'; p++);

p设置为数组的最后一个(相关)元素(空字符)

  for(p--; p>=arr; p--){
      printf("%c",*p);
    }

从最后一个(非空)字符开始,并将每个字符从最后打印到第一个。

问题:
如果输入数组的长度超过255个字符,会发生什么? (以下回答)

<子> buffer overflow

答案 1 :(得分:2)

假设输入为Hello World。这将作为

存储在缓冲区arr
[H][e][l][l][o][ ][W][o][r][l][d][\0]...

您的指针设置为arr,因此指针指向H

[H][e][l][l][o][ ][W][o][r][l][d][\0]...
 ^
 |
 p

第一个循环前进(p++),直到遇到第一个空字符(\0)。它现在看起来像

[H][e][l][l][o][ ][W][o][r][l][d][\0]...
                                  ^
                                  |
                                  p

现在第二个循环 back p--)直到它再次到达第一个字符(实际上,直到指针等于指向数组开头的指针),打印每个字符因为它符合它。但是,第一个字符\0会被忽略p--

for(p--; p>=arr; p--)
    ^^^

答案 2 :(得分:1)

代码看起来很聪明,但它实际上表现出未定义的行为,这意味着代码可以做任何事情。

问题是第二个循环:

for(p--; p>=arr; p--){
    printf("%c",*p);
}

它打算做的是在字符串的最后一个字符处开始p(不包括终止\0,然后继续递减它,直到字符串的所有字符都以相反的顺序输出

问题是终止条件:在循环的预期结束之后,parr,然后p--减去一个,然后p >= arr为假。

不幸的是,对指针的算术运算可能不会导致指针不再指向对象(或者指向数组的最终对象之后的指针),或者它是未定义的行为。

这就是这里发生的事情:p--导致p离开数组,所有下注都将关闭接下来发生的事情。

这是编写第二个循环的正确方法:

for (int i = (p-arr)-1; i >= 0; i--) {
    printf("%c", p[i]);
}

我可能会使用索引编写整个代码来完全避免指针运算。也许是这样的:

int i = 0;
// Find the terminating \0 byte
while(p[i])i++;
// Iterate backwards through the string, outputting characters along the way.
while(--i >= 0)putc(p[i]);

答案 3 :(得分:0)

在解释代码之前,我必须说两件事 - 首先,main函数的签名应该是以下之一 -

int main(void);
int main(int argc, char *argv[]);

第二,不要使用gets 。这是不安全的使用。请改用fgets。现在,来看代码。

for(p = arr; *p != '\0'; p++) ;

在上面的循环中,为p分配了数组arr的基地址,即数组arr的第一个元素的地址。数组arr包含一个终止空字节,这意味着它是一个字符串。循环体是空语句;,这意味着p递增直到遇到空字节,即,当测试*p != '\0'失败时。在for循环

for(p--; p >= arr; p--) {
   printf("%c",*p);
}
首先递减

p以指向空字节之前的最后一个字符,然后在每次迭代中打印它,直到条件p >= arrtrue,即直到第一个到达数组的元素。您应该将代码更改为 -

#include <stdio.h>

int main(void) {
    char arr[255], *p;

    printf("Enter string:\n");
    fgets(arr, sizeof arr, stdin);
    for(p = arr; *p! = '\0'; p++) 
        ;  // the null statement

    for(p--; p >= arr; p--)
       printf("%c", *p);

    return 0;        
}