0

当我使用指向反向函数的指针时,当我尝试调用反向函数时,我得到错误,而不是打印它。指针发送错误信息。所以我试图改变一些代码,但它无能为力。

#include <string.h> 
#include <stdio.h>

char *strrev(char *str)
{
    char *p1, *p2;

    if(!str) {return NULL;}
    printf("%s",__LINE__); //checking
    for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
    {
        *p1 ^= *p2;
        *p2 ^= *p1;
        *p1 ^= *p2;
    }
    printf("%s",str);  //checking
    return str;
}

int main(void)
{
    char *str ;
    printf(" Please enter string \n");
    scanf("%s",&str);
    printf("%s\n", strrev(*str));
    return 0;
}
4

2 回答 2

4
char *str ;
scanf("%s", &str);
  1. 您永远不会为str. 尝试malloc或更好,首先使用数组
  2. 您需要&scanf行中删除
于 2012-05-07T03:21:27.720 回答
2

你那里有很多问题。

1/首先,您不为字符串分配任何存储空间。这可以char str[128];根据您的尺寸要求通过简单的方式解决。这也意味着 NULL 检查是不必要的,您不必担心以后打印(或尝试打印)NULL 指针 - 更改函数合同,以便明确禁止。

2/接下来,永远不要使用scanf("%s")(即,使用无界字符串格式说明符)——这是解决缓冲区溢出问题的简单途径。如果您想要一个带有溢出检查的强大输入功能,请参阅此答案

在任何情况下,%s扫描一个单词而不是一行,因此,如果您输入"Hello Pax"(带空格),它将看到Hello.

3/第三,如果str是 a char*,那么*str是一个字符,而不是一个 C 字符串。您应该传递strstrrev,而不是*str。即使使用上述第 1 点中的修复也是如此。

4/宏扩展为整数类型,因此不会根据格式说明符__LINE__将其视为字符指针。%s您可能想%d改用。

5/根据C11 , ISO 标准保留所有str以小写字母开头的名称供自己使用。7.31.13 Future library directions所以strrev实际上并不是一个好主意。

6/最后,XOR 交换技巧是一种时代错误,在当今的现代环境中没有立足之地。考虑到计算而不是临时变量解决方案的简单移动,这既是不必要的,也可能会更慢。交换到变量的正确方法是:

int t = a;
a = b;
b = t;

帮自己一个忙,放弃这个把戏。它与达夫的设备属于同一个桶:-)


其他一些问题,虽然这比其他任何东西都更具风格(就像我更喜欢这种风格),但基于多年的编程教学。

7/我遇到的大多数人发现理解数组索引比理解指针更容易,因为考虑字符串中的字符而不是任意内存位置更容易。经验丰富的 C 程序员知道没有区别(无论是在功能方面,还是在今天的编译器中,性能方面)。因此,我倾向于使用索引而不是指针,例如:

char *reverseStr (char *str) {
    char tmpchar;
    int front = 0;
    int back = strlen (str) - 1;
    while (front < back) {
        tmpchar = str[front];
        str[front++] = str[back];
        str[back--] = tmpchar;
    }
    return str;
}

8/你还会注意到另一件事,使用更详细的变量,如front,backtmpchar. 编译器不在乎您的标识符有多大(在合理范围内),这使代码更具可读性。

于 2012-05-07T03:50:05.753 回答