Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何有效地排除C中的一个bug?_C_Off By One - Fatal编程技术网

如何有效地排除C中的一个bug?

如何有效地排除C中的一个bug?,c,off-by-one,C,Off By One,我已经编写了一个程序来反转一个字符数组,也反转该数组中的字。程序几乎按预期运行,但我相信这是一个一个错误。我尝试过搞乱涉及循环计数器的数学运算,但没能弄明白这一点。我可以使用什么工具或技术来解决此类问题?我尝试了printf语句,还使用了gdb,并在计数器变量上放置了一个手表 #include <stdio.h> #include <stdlib.h> #include <string.h> void reverse_arr(char *arr, size_

我已经编写了一个程序来反转一个字符数组,也反转该数组中的字。程序几乎按预期运行,但我相信这是一个一个错误。我尝试过搞乱涉及循环计数器的数学运算,但没能弄明白这一点。我可以使用什么工具或技术来解决此类问题?我尝试了printf语句,还使用了gdb,并在计数器变量上放置了一个手表

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

void reverse_arr(char *arr, size_t len);
void print_chars(char *arr, size_t len);
void reverse_words(char *arr, size_t len);
int main(int argc, char **argv)
{
    char phrase[] = {'p','e','r','f','e','c','t',' ',
                    'm','a','k','e','s',' ','p','r',
                    'a','c','t','i','c','e'};

        size_t i;

    reverse_arr(phrase, sizeof(phrase));
    reverse_words(phrase,sizeof(phrase));
    print_chars(phrase, sizeof(phrase));

    return EXIT_SUCCESS;
}

void reverse_arr(char *arr, size_t len)
{
    size_t front, tail;
    tail = len-1;
    char tmp;
    for(front = 0; front < len/2; front++, tail--)
    {
        tmp = arr[front];
        arr[front] = arr[tail];
        arr[tail] = tmp;
    }

    return;
}

// 1. Search for a space
// 2. When space is found, that space is the place to stop and indicates all between the start and it are a word
// 3. Now call reverse_arr on the word and calculate the length of the word by subtracting tail - start
// 
void reverse_words(char *arr, size_t len)
{
    size_t tail, start;
    for(tail = start = 0; tail < len; tail++)
    {
        if(arr[tail] == ' ' || tail == len-1)
        {
            reverse_arr(&arr[start], tail - start);
            start = tail+1;
        }
    }
}

void print_chars(char *arr, size_t len)
{
    size_t i;
    for(i = 0; i < len; i++)
    {
        putchar(arr[i]);
    }
    putchar('\n');

    return;
}
#包括
#包括
#包括
无效反向排列(字符*排列,大小排列);
无效打印字符(字符*arr,大小长度);
无效反向字(字符*arr,大小\u t len);
int main(int argc,字符**argv)
{
字符短语[]={p','e','r','f','e','c','t','',
‘m’、‘a’、‘k’、‘e’、‘s’、‘p’、‘r’,
‘a’、‘c’、‘t’、‘i’、‘c’、‘e’};
尺寸i;
倒装(短语,sizeof(短语));
倒装词(短语,sizeof(短语));
打印字符(短语、大小(短语));
返回退出成功;
}
无效反向排列(字符*排列,大小排列)
{
前、后尺寸;
tail=len-1;
char-tmp;
用于(前部=0;前部<长度/2;前部++,尾部--)
{
tmp=arr[前];
arr[前]=arr[尾];
arr[tail]=tmp;
}
回来
}
// 1. 搜索空间
// 2. 当找到空格时,该空格是停止的位置,表示开始和结束之间的所有空格都是一个单词
// 3. 现在调用单词的reverse_arr并通过减去tail-start来计算单词的长度
// 
无效反向字(字符*arr,大小\u t len)
{
尾的大小,开始;
对于(tail=start=0;tail

此代码返回
practice make-erfectp
。很明显,这是一个一个接一个的错误,但我在这方面花了一些时间,并且在其他程序的C中遇到了类似的错误。

错误在
反向词中。有时
tail
索引单词最后一个字符之后的字符,有时
tail
索引单词本身的最后一个字符

reverse\u words
调用
reverse\u array
是:

reverse_arr(&arr[start], tail - start);
如果
start
索引单词的第一个字符,并且单词中存在
tail-start
字符,则此操作有效。因此
tail
必须在单词的最后一个字符之后索引该字符

条件
arr[tail]=''
与此一致,但结束条件不一致:(1)循环过早退出,(2)测试
tail==len-1
也关闭一次

可以通过再次迭代并在尝试访问
arr[tail]
之前检查结束条件来修复此问题(以避免索引超过结束):

void reverse\u words(字符*arr,大小\u len)
{
尾的大小,开始;

对于(tail=start=0;tail您是否至少在
main
中将其缩小为一个函数调用?(
reverse\u arr
reverse\u words
)这将是第一步,因为它们是完全分开的,您可以打印/使用调试器检查它们之间的
短语
。函数名称表明您的输出应该是
ecitcarp sekam tcefrep
。这确实是您想要得到的吗?@goodstribration:
反转单词
反转每个单词对于“熟能生巧”的预期输出“代码”> ReaveSARR < /代码>?通过测试小的测试用例来清除它们,这种类型可以很容易地用调试器跟踪程序的执行。您不需要大于4个字符的任何东西来覆盖所有的条件。首先从一个空数组开始,先修复这个bug,然后考虑字符串可能是更好的选择。o我有一个问题。在语句
if(tail==len | | arr[tail]=='')中,C是否保证在
arr[tail]之前计算
tail==len
?我试图在C标准中找到这一点,因为我想知道这一点已经有一段时间了。另外,您使用了什么调试方法来解决这个问题?@endian是的,它被称为短路。对于
|
,只有当第一个操作数为false时,才会计算第二个操作数。对于
&
,只有当第二个操作数为false时,才会计算第二个操作数第一个是真的。您可以通过将函数调用放入第二个操作数,并让该函数在调用时打印一些内容来测试它。关于调试,我只是查看了循环,并通过检查发现了问题。
void reverse_words(char *arr, size_t len)
{
    size_t tail, start;
    for (tail = start = 0; tail <= len; tail++)
    {
        if (tail == len || arr[tail] == ' ')
        {
            reverse_arr(&arr[start], tail - start);
            start = tail+1;
        }
    }
}