这个例子导致c4028警告,为什么?

时间:2018-05-27 11:27:47

标签: c function pointers visual-studio-2017

我是否犯了任何声明错误?当我调试一次v-s 2017时显示:

(8):警告C4028:形式参数1与声明不同

(8):警告C4028:形式参数2与声明不同

如果我再次调试没有插入代码警告消失,但如果我添加一个空格警告行再次回来

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


char* mygets(char* s, const size_t size); //ok
char *strstr(char *str1, char *str2); //warning appear here at the function prototype  

//this function below are ok
char* mygets(char* s, const size_t size) {
    if (!s) return s; 
    size_t count = size;
    char* sp = s;
    int ch;

    for (; (count > 0) && ((ch = getchar()) != EOF); ) {
        --count; 
        if ((*sp++ = ch) == '\n') break; 
    }
    *sp = '\0'; 
    return s;
}

//function body of the warning
char *strstr(char *str1, char *str2) {
    char *ptr = NULL;
    int count = 0;
    for (int i = 0; str1[i] != '\0'; i++)
    {
        if (str1[i] == str2[0])
        {
            for (int j = 0; str2[j] != '\0'; j++)
            {
                if (str1[i + j] != '\0' && str1[i + j] != str2[j])
                {
                    break;
                }
            }
            if (strlen(str2) == count)
            {
                ptr = str1 + i;
                return ptr;
            }
        }
    }
    return NULL;
}
main() {

    char s[100];
    char s2[100];

    printf("word\n");
    mygets(s, 99);
    printf("sub-word\n");
    mygets(s, 99);

    printf("%s\n", strstr(s, s2));
}

2 个答案:

答案 0 :(得分:0)

strstr()是一个标准函数。它的模板是

char* strstr(const char*, const char*);

这可能是你得到的错误。将您的函数名称更改为strstr1并尝试

答案 1 :(得分:0)

因为你已经包含了string.h

char *strstr(char *str1, char *str2);

仔细查看警告和源代码行,它会告诉您需要知道的所有内容:

warning C4028: formal parameter 1 different from declaration
warning C4028: formal parameter 2 different from declaration

它试图告诉你,参数1和2,即char*char*的类型与声明中预期的类型不同。因为,声明是从您上面包含的标准string.h头文件中引用的。

现在,查看strstr的手册页,您会发现:

char *strstr(const char *haystack, const char *needle);

要消除警告,您应该将您的功能更改为任何其他名称,或者您想要取消string.h include。我建议更改您的函数名称作为一种方法,因为您的代码似乎使用了依赖于标题的strlen等其他函数。

现在关于这个:

  

如果我再次调试没有插入代码警告消失,但如果我添加一个空格警告行再次回来

有一些(哑)IDE在其中控制台显示警告,如果您只是构建(而不是重新构建!)代码而不更改任何内容,则警告消失。然后,只有在源/头文件中更改触发警告的内容时才会出现警告。例如,keil MDK就是这样做的。

此外,代码中有多项改进,例如:

  • main可以有一个标准的返回类型,最好是int main(void)
  • 循环中有一个if (strlen(str2) == count),你应该避免,每次迭代它都是一个函数调用,对吧?您可以随时获取变量,在循环之前获取一次捕获字符串长度。