C程序行为与主要风格的区别

时间:2014-04-15 14:15:37

标签: c

我有这个简单的程序,它可以正常工作。

#include<stdio.h>

int main(int argc, char *argv[]) {
    int mystrlen(char *s);
    char s[6] = "ABCDEF";
    printf("%d", mystrlen(s)); // print 6
}

int mystrlen(char *s) {
    char *p=s; /*Assigning the starting value to p */
    while(*s != '\0') {
        s = s + 1;
    }
    return s-p;
}

我将做的唯一更改是int main(int argc, char *argv[])而不是int main(void),我将使用#include<stdio.h> int main(void) { int mystrlen(char *s); char s[6]="ABCDEF"; printf("%d",mystrlen(s)); // prints 8 !! } int mystrlen(char *s) { char *p=s; /*Assigning the starting value to p */ while(*s != '\0') { s = s + 1; } return s-p; } ,我不会发送任何命令行参数。

现在,同样的程序对我来说完全行为不端!

{{1}}

任何人都可以解释为什么会这样吗?这是我期望在程序中出错的最后一件事。这是编译器依赖的行为吗? FWIW,我正在使用gcc

3 个答案:

答案 0 :(得分:6)

未定义的行为:您没有为null终止符分配空间。您应该在编译器中启用警告,这应该记住这一点。

答案 1 :(得分:3)

您的问题在于char s[6]="ABCDEF";声明。 null终结符没有空间,这是所有标准库字符串函数(以及函数mystrlen)所需要的。

请改用char s[]="ABCDEF";。在这样做时,会自动为您添加空终止符 - 这就是引用文字的工作方式:将结束引用视为包含隐式\0。此外,C将为您计算数组的大小,因此无需指定。

正式程序的行为目前未定义。它不仅依赖于编译器,而且依赖于任何东西。

答案 2 :(得分:2)

这将是一个未定义的行为,因为您的源数组s没有足够的空间来终止null,即\0。启用编译器警告。

您可以像

一样更改数组
char s[7]="ABCDEF";

来自C99标准

  

字符类型数组可以由字符串初始化   文字,可选择括在括号中。连续的人物   字符串文字(包括终止空字符if)   有空间或者如果数组的大小未知)初始化   数组的元素