2013年10月4日 星期五

常見編譯錯誤

怎麼辦?

gcc 和我抱怨了QQ

這時候謂之編譯錯誤 (compilation error)

這裡介紹一下常見的編譯錯誤及其解決方法

在開始之前,要先提一下在Linux & VIM操作篇(1)中提到的,

在 VIM 裡執行 :make 指令,

在遇到以下編譯錯誤時,

按 Enter 回到編輯畫面的時候,

會自動跳到發生編譯錯誤的那行,

是個滿方便的功能喔:D

所以請大家也習慣一下用 VIM 來做 make 囉~

Section 1. Statement related

首先,我們要先用一個題目來說明,

然後列出各種編譯錯誤的解法

Problem: (UVa 10050)


Hashmat is a brave warrior who with his group of young soldiers moves from one place to another to fight against his opponents. Before fighting he just calculates one thing, the difference between his soldier number and the opponent's soldier number. From this difference he decides whether to fight or not. Hashmat's soldier number is never greater than his opponent.
Input

The input contains two integer numbers in every line. These two numbers in each line denotes the number of soldiers in Hashmat's army and his opponent's army or vice versa. The input numbers are not greater than 2^32. Input is terminated by End of File.

Output

For each line of input, print the difference of number of soldiers between Hashmat's army and his opponent's army. Each output should be in seperate line.

Sample Input:
10 12
10 14
100 200

Sample Output:
2
4
100

題目的要求,簡化來講就是

輸入 a, b, 輸出 b-a 的結果

註:以下標題中 "......" 表示它可能是其它文字,

以第一個例子來說,printf 也有可能代換成其它的東西(比如 scanf 之類)

1. error: expected ';' before '......'


code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( "%d %d", &a, &b )
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:7:5: error: expected ';' before 'printf'

solution:

當你看到這個訊息時,表示你有一行忘了加分號了,

而gcc將會跟你顯示哪一行有錯,

此例中為第7行出錯了(sample.c:7:5)

通常出問題的都是前一行(此例中為第6行)

發現我們忘了加上分號了,加上後即解決

2. error: expected '=', ',', ';', 'asm' or '__attribute__' before '......'


code:
#include<stdio.h>

int main()
{
    int a, b
    scanf( "%d %d", &a, &b );
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:6:5: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'scanf'
sample.c:7:21: error: 'b' undeclared (first use in this function)
sample.c:7:21: note: each undeclared identifier is reported only once for each function it appears in

solution:

看到這個,表示你在宣告變數的那句忘了加上分號,

這會導致宣告不正確

並且會提示你變數尚未宣告

只要在宣告變數的那行加上分號即可

3. error: '......' undeclared (first use in this function)


code:
#include<stdio.h>

int main()
{
    int a;
    scanf( "%d %d", &a, &b );
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:7:21: error: 'b' undeclared (first use in this function)
sample.c:7:21: note: each undeclared identifier is reported only once for each function it appears in

solution:

note 這行永遠會和 undeclared 的錯誤一起出現,不需理會它

我們看到 "b" 這個變數尚未宣告

所以我們只要宣告 b 變數即可解決

4. warning: incompatible implicit declaration of built-in function '......' [enabled by default]


code:
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:4:5: warning: incompatible implicit declaration of built-in function 'scanf' [enabled by default]
sample.c:5:5: warning: incompatible implicit declaration of built-in function 'printf' [enabled by default]

solution:


這個原因是因為你忘記加入 stdio.h 了,

printf, scanf 都是放在這裡面的

加入後即可

5. note: expected 'const char *' but argument is of type 'int'

warning: multi-character character constant


code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( '%d %d', &a, &b );
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:6:12: warning: character constant too long for its type [enabled by default]
sample.c:6:5: warning: passing argument 1 of 'scanf' makes pointer from integer without a cast [enabled by default]

In file included from sample.c:1:0:
....../stdio.h:347:37: note: expected 'const char *' but argument is of type 'int'

solution:

這條沒有行號,比較難找

會發生這個錯誤是因為 scanf 中必須用雙引號而非單引號括起來,

所以我們要把單引號改成雙引號(第6行有錯)

6. error: expected ')' before '......'


code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    printf( "%d\n" b-a );

    return 0;
}

compiler message:
sample.c:7:20: error: expected ')' before 'b'
sample.c:7:20: warning: format '%d' expects a matching 'int' argument [-Wformat]

solution:

雖然它說它預期有一個右小括號,

但這問題實際上是因為我們在 printf 的雙引號文字後忘了掛上逗號了

加上去即可

7. error: invalid operands to binary & (have 'int *' and 'int')


code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( "%d %d", &a &b );
    printf( "%d\n", b-a );

    return 0;
}

compiler message:
sample.c:6:24: error: invalid operands to binary & (have 'int *' and 'int')

solution:


scanf 中,每一項都要由逗號分開,所以我們加上逗號即可

8. error: expected expression before '%' token


Code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    printf( %d\n, b-a );

    return 0;
}

Compiler message:
sample.c:7:13: error: expected expression before '%' token
sample.c:7:13: error: stray '\' in program

Solution:

這是因為我們忘記替%d加上大括號了,

加上即可

9.  warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat]


Code:
#include<stdio.h>

int main()
{
    int a, b;
    scanf( "%d %d", a, b );
    printf( "%d\n", b-a );

    return 0;
}

Compiler message:
sample.c:6:5: warning: format '%d' expects argument of type 'int *', but argument 2 has type 'int' [-Wformat]
sample.c:6:5: warning: format '%d' expects argument of type 'int *', but argument 3 has type 'int' [-Wformat]
sample.c:6:10: warning: 'a' is used uninitialized in this function [-Wuninitialized]
sample.c:6:10: warning: 'b' is used uninitialized in this function [-Wuninitialized]

Solution:

這是因為我們在 scanf 裡面忘記放上 & 符號了

加上即可

10. warning: format '%f' expects argument of type 'float *', but argument 3 has type 'int *' [-Wformat]


Code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %f", &a, &b );
    printf( "%d\n", b-a );
    return 0;
}  
Compiler message:
sample.c:5:5: warning: format '%f' expects argument of type 'float *', but argument 3 has type 'int *' [-Wformat]
Solution:

format 不合的時候,

通常是 printf 或 scanf 的變數格式寫錯了,

請檢查是否配對正確,

此例中應將 %f 改為 %d
正確的程式碼:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    printf( "%d\n", b-a );
    return 0;
} 

Section 2. if related

Problem (UVa 11172)

Some operators checks about the relationship between two values and these operators are called relational operators. Given two numerical values your job is just to find out the relationship between them that is (i) First one is greater than the second (ii) First one is less than the second or (iii) First and second one is equal.

Input
Each line contains two integers a and b (|a|,|b|<1000000001).

Output

For each line of input produce one line of output. This line contains any one of the relational operators “>”, “<” or “=”, which indicates the relation that is appropriate for the given two numbers.

Sample Input

10 20
20 10
10 10

就是輸出兩數間的關係啦

1. error: expected ')' before '......'


Code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    if( a < b
        printf( "<\n" );
    else if( a == b )
        printf( "=\n" );
    else
        printf( ">\n" );
    return 0;
}

Compiler message:
sample.c:7:9: error: expected ')' before 'printf'
sample.c:14:1: error: expected expression before '}' token
sample.c:14:1: warning: control reaches end of non-void function [-Wreturn-type]

Solution:

第一個 if 的右括不見了,加上即可

2. error: 'else' without a previous 'if'


Code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    if( a < b )
        printf( "<\n" );
    else ( a == b )
        printf( "=\n" );
    else
        printf( ">\n" );
    return 0;
}

Compiler message:
sample.c:8:10: warning: statement with no effect [-Wunused-value]
sample.c:9:9: error: expected ';' before 'printf'
sample.c:10:5: error: 'else' without a previous 'if'

Solution:

因為 else 一出現,if 的系列就結束了,

所以只有在最後才可以出現 else,

其餘的要用 else if 來表示

故將第一個 else 改成 else if

3. error: expected identifier or '(' before '}' token


Code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    if( a < b )
        printf( "<\n" );
    else if ( a == b )
        printf( "=\n" );
    else
        printf( ">\n" );
    }
    return 0;
}

Compiler message:
sample.c:13:5: error: expected identifier or '(' before 'return'
sample.c:14:1: error: expected identifier or '(' before '}' token
sample.c: In function 'main':
sample.c:12:5: warning: control reaches end of non-void function [-Wreturn-type]

Solution:

當出現多個這種訊息時,

有可能就是你的 if 判斷忘了加上左大括號了,

請檢查是否每個左右大括都有配對正確

4. error: expected declaration or statement at end of input


Code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    if( a < b )
        printf( "<\n" );
    else if ( a == b )
        printf( "=\n" );
    else{
        printf( ">\n" );

    return 0;
}

Compiler message:
sample.c:14:1: error: expected declaration or statement at end of input
sample.c:14:1: warning: control reaches end of non-void function [-Wreturn-type]

Solution:

這個情形是忘了加上右大括號了,加上即可

Correct code:
#include<stdio.h>
int main()
{
    int a, b;
    scanf( "%d %d", &a, &b );
    if( a < b )
        printf( "<\n" );
    else if( a == b )
        printf( "=\n" );
    else
        printf( ">\n" );

    return 0;
}

沒有留言:

張貼留言