【问题标题】:mixed declarations and codes混合声明和代码
【发布时间】:2011-02-23 04:21:51
【问题描述】:

当我使用“gcc -o dene -Wall -ansi -pedantic-errors dene.c”编译函数时 ,gcc 不会发出错误。(你能在 if 循环中看一下以 char .... 开头的行吗,)

        static void remove_negation(char *s,char *s1) 
          {
             char **cmainp=malloc(sizeof(char*)*1);   
                        int len=0;int d=0; int i=0;
            cmainp[0]=malloc(sizeof(char)*300);
            len=strlen(s);
           for(i=0;i<len;++i)
             { if(s[i]=='-')
               if(i==0 || s[i-1]==',')
      /*look*/  {char *p=malloc(sizeof(char)*3); /*look*/

                ++i;    p[0]=s[i];   p[1]='\0'; 

              strcat(s1,","); strcat(s1,p); free(p);
               continue;
             }
            cmainp[0][d]=s[i]; 
               ++d;
               } cmainp[0][d+1]='\0'; 


             strcpy(cmainp[0],s);
             free(cmainp[0]);
              }

但是,当编译上述函数时,使用 gcc 重新格式化 ,gcc 发出该错误;

“dene.c:10: 错误:ISO C90 禁止混合声明和代码”

        static void remove_negation(char *s,char *s1) 
          {
             char **cmainp=malloc(sizeof(char*)*1);    
          /*look*/ cmainp[0]=malloc(sizeof(char)*300); /*look*/
                        int len=0;int d=0; int i=0;

            len=strlen(s);
           for(i=0;i<len;++i)
             { if(s[i]=='-')
               if(i==0 || s[i-1]==',')
        {char *p=malloc(sizeof(char)*3);

                ++i;    p[0]=s[i];   p[1]='\0'; 

              strcat(s1,","); strcat(s1,p); free(p);
               continue;
             }
            cmainp[0][d]=s[i]; 
               ++d;
               } cmainp[0][d+1]='\0'; 


             strcpy(cmainp[0],s);
             free(cmainp[0]);
              }

最后一个,gcc 发出以下错误

dene.c:16: 错误:'char' 之前的预期表达式

dene.c:20: error: ‘p1’ undeclared (第一次在这个函数中使用)

dene.c:20: 错误:(每个未声明的标识符只报告一次

dene.c:20: 错误:对于它出现的每个函数。)

        static void remove_negation(char *s,char *s1) 
          {
             char **cmainp=malloc(sizeof(char*)*1);    

                        int len=0;int d=0; int i=0;
             cmainp[0]=malloc(sizeof(char)*300); 
            len=strlen(s);
           for(i=0;i<len;++i)
             { if(s[i]=='-')
        /*look*/   char *p=malloc(sizeof(char)*3);   /*look*/
               if(i==0 || s[i-1]==',')
              {

                ++i;    p[0]=s[i];   p[1]='\0'; 

              strcat(s1,","); strcat(s1,p); free(p);
               continue;
             }
            cmainp[0][d]=s[i]; 
               ++d;
               } cmainp[0][d+1]='\0'; 


             strcpy(cmainp[0],s);
             free(cmainp[0]);
              }

问题是为什么它们之间存在差异。

【问题讨论】:

    标签: c declaration compiler-warnings c89


    【解决方案1】:

    由于“dene.c:10: 错误:ISO C90 禁止混合声明和代码”错误,您在代码中间定义了 char *p=malloc(sizeof(char)*3)。 ANSI C 要求声明仅出现在代码块的开头,其他任何地方都没有。相反,如果您将 char *p 放在代码的开头,然后将 *p=malloc(sizeof(char)*3) 放在第 10 行,这个“错误”就会消失。

    【讨论】:

      【解决方案2】:

      你必须在做任何事情之前做声明。

      【讨论】:

        【解决方案3】:

        问题在于您的标志“-ansi”强加了 ANSI C 的规则,其中声明可能只出现在块的开头,而不是与其他语句交错的任何其他地方。

        请注意,在您的第一个示例中,if 之后的左大括号 { 开始一个新块,因此在此处声明新变量是合法的。在第二个示例中,您在与“char **cmainp”相同的块中声明“int len”,但在分配给“cmainp”之后。如果将赋值放在声明之后,那么一切都会好起来的,因为声明将位于块的开头。

        【讨论】:

          【解决方案4】:

          在 K&R 和 ANSI c 中,您必须始终将声明放在作用域块的开头。这个要求在 c99 中放宽了。

          那么,什么是作用域块?由{ 和} 分隔的区域。

          所以在你上面的例子中声明

          {
             char *p=malloc(sizeof(char)*3); /* ...
          

          没关系,因为它紧跟在{ 之后,而

          {
            char **cmainp=malloc(sizeof(char*)*1);    
          
            /*look*/ cmainp[0]=malloc(sizeof(char)*300); /*look*/
          
            int len=0;...
          

          失败,因为分配位于 { 和第二个声明 (int len=0;) 之间。

          【讨论】:

          • 我可以这么说吗? { if(s[i]=='-') if(i==0 || s[i-1]==',') {char *p=malloc(sizeof(char)*3); ,在第二个例子中, char *p .. 只有在满足两个 if 语句时才会创建
          • 但是,您可以注意,当您到达匹配的} 时,在作用域中创建的变量会超出作用域,之后访问它们是错误的。
          • C89 之前的编译器是否更严格?我的意思是要求声明从每个功能块或每个块的开头开始?我的意思是 foo() { int i; for(i=0; i&lt;n; i++) { int j; for(j=0; j&lt;n; j++) {}}} 是合法的 pre C89 编译器吗?
          • @Zboson 不知道。我在 ANSI 标准之后学习了 c,编译器大多对此表示不满。我只为 grin 写过 K&R,并使用了一些 ANSI 编译器的兼容模式。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-28
          • 2011-03-02
          • 1970-01-01
          相关资源
          最近更新 更多