混合声明和代码

9
当我使用"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: error: ISO C90 forbids mixed declarations and code"

        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: 错误:‘p1’未声明(在此函数中第一次使用)

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]);
              }

问题是为什么它们之间存在差异。
4个回答

14
在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语句都满足时,才会创建char *p。如果s[i]=='-'并且i==0或者s[i-1]==',',则会分配一个大小为3的char指针p。 - user319824
2
请注意,当您到达匹配的“}”时,作用域中创建的变量将超出范围,在此之后访问它们是错误的。 - dmckee --- ex-moderator kitten
C89编译器是否更加严格?我的意思是,声明是否需要在每个函数块或每个块的开头开始?我的意思是,像foo() { int i; for(i=0; i<n; i++) { int j; for(j=0; j<n; j++) {}}}这样的代码在C89之前的编译器中是否合法? - Z boson
@Zboson 没有头绪。我是在大多数符合ANSI标准的编译器之后学习C语言的。我只是为了好玩写过K&R,并使用某些ANSI编译器的兼容模式。 - dmckee --- ex-moderator kitten

1
问题在于您的标志“-ansi”强制执行ANSI C的规则,其中之一是声明只能出现在块的开头,而不能与其他语句交错出现。
请注意,在您的第一个示例中,if后面的左括号“{”开始了一个新的块,因此在那里声明新变量是合法的。在您的第二个示例中,您在与“char **cmainp”相同的块中声明了“int len”,但是在对“cmainp”进行赋值之后。如果您将赋值放在声明之后,则一切都会很好,因为声明将位于块的开头。

1
使用 "dene.c:10: error: ISO C90 forbids mixed declarations and code" 错误时,您在代码中间定义了 char *p=malloc(sizeof(char)*3)。 ANSI C 要求声明仅出现在代码块的开头,而不是其他任何地方。如果您将 char *p 放在代码开头,然后在第 10 行上放置 *p=malloc(sizeof(char)*3),这个 "错误" 将消失。

0

在做任何事情之前,你必须先进行声明。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接