gcc编译c问题

1Linux C语言编程错误解决之warning:the `gets' function is dangerous and should not be used.

问题出在程序中使用了gets Linux 下gcc编译器不支持这个函数,解决办法是使用 fgets

fgets()函数的基本用法为:fgets(char * s,int size,FILE * stream);

/*   代码实现     */

 

#include <stdio.h>

int main ( ) {

 

  char crack8[20];

 

  printf("\n 输入任意字符 : ");

 

  fgets(crack8, 20, stdin);//stdin 意思是键盘输入

 

  fputs(crack8, stdout); //stdout 输出

 

  return 0;

}

2、逻辑错误与语法错误

在编程时,出现的错误可能有逻辑错误和语法错误两种。这两种错误的发生原因和处理方法是不同的。本节将讲述这两种错误的处理方法。
   逻辑错误指的是程序的设计思路发生了错误。这种错误在程序中是致命的,程序可能正常编译通过,但是结果是错误的。当程序正常运行而结果错误时,一般都是编程的思路错误。这时,需要重新考虑程序的运算方法与数据处理流程是否正确。
    语法错误:语法错误指的是程序的思路正确,但是在书写语句时,发生了语句错误。
   这种错误一般是编程时不小心或是对语句的错误理解造成的。在发生语句错误时,程序一般不能正常编译通过。这时会提示错误的类型和错误的位置,按照这些提示改正程序的语法错误即可完成错误的修改。

3 C 程序中的错误与异常

C 程序中的错误,根据严重程序的不同,可以分为异常与警误两类。在编译程序时,这两种情况对编译的影响是不同的,对错误与异常的处理方式是不同的。
1.什么是异常
异常指的是代码中轻微的错误,这些错误一般不会影响程序的正常运行,但是不完全符合编程的规范。在编译程序时,会产生一个“警告”,但是程序会继续编译。下面的程序会使
程序发生异常,在编译时产生一个警告错误。
? 在除法中,0 作除数。
? 在开方运算时,对负数开平方。
? 程序的主函数没有声明类型。
? 程序的主函数没有返回值。
? 程序中定义了一个变量,但是没有使用这个变量。
? 变量的存储发生了溢出。
2.什么是错误
   错误指的是程序的语法出现问题,程序编译不能正常完成,产生一个错误信息。这时会显示错误的类型与位置。根据这些信息可以对程序进行修改。

4、编译中的警告提示

在编译程序时,如果发生了不严重的异常,会输出一个错告错误,然后完成程序的编译。
例如下面的内容是一个程序在编译时产生的警告。
5.1.c: In function 'main':
5.1.c:16: 警告:‘main’ 的返回类型不是‘int’
5.1.c:18: 警告:被零除
这些的含义如下所示。
(1)“In function 'main':”表示发生的异常在main 函数内。

(2)“5.1.c:16:”表示发生异常的文件是5.1.c,位置是第16 行。
(3)下面的信息是第16 行的异常,表明程序的返回类型不正确。
‘main’ 的返回类型不是 ‘int’
(4)下面的警告信息表明程序的第18 行有除数为0 的错误。
5.1.c:18: 警告:被零除
1.8.4 找不到包含文件的错误
程序中的包含文件在系统或工程中一定要存在,否则程序编译时会发生致命错误。例如
下面的语句包含了一个不正确的头文件。
#include <stdio1.h>
编译程序时,会发生错误,错误信息如下所示。
5.1.c:2:20: 错误:stdio2.h:没有那个文件或目录
1.8.5 错误地使用逗号
程序中逗号的含义是并列几个内容,形成某种算法或结构。程序中如果错误地使用逗号,会
使程序在编译时发生致命错误。例如下面的代码,是程序中的if 语句后面有一个错误的逗号。
int max(int i,int j )
{
if(i>j),
{
return(i);
}
else
{
return(j);
}
}
程序编译时输出的错误信息如下所示。表明max 函数中逗号前面的表达式有错误,实际上的错误是多一个逗号。
5.1.c: In function ‘max’:
5.1.c:4: 错误:expected expression before ‘,’ token
5.1.c: In function ‘max’:
1.8.6 括号不匹配错误
程序中的引号、单引号、小括号、中括号、大括号等符号必须成对出现。这方面的错误
会使程序发生符号不匹配的错误。发生这种错误后,编译程序往往不能理解代码的含义,也
不能准确显示错误的位置,而是显示表达式错误。例如下面的代码,在最后一行上了一个花
括号。
int max(int i,int j )

{
if(i>j)
{
return(i);
}
else
{
return(j);
}
编译程序时,会显示下面的错误信息。
5.1.c:22: 错误:expected declaration or statement at end ofinput
1.8.7 小括号不匹配错误
程序中的小括号一般在一行内成对出现并且相匹配。小括号不匹配时,程序发生致命错误。例如下面的代码,第一行多了一个右半边括号。
if(i>j))
{
return(i);
}
else
{
return(j);
}
编程程序时,会发生下面的错误。显示括号前面有错误,并且导致下面的else 语句也有
错误。
5.1.c:4: 错误:expected statement before ‘)’ token
5.1.c:8: 错误:expected expression before ‘else’
1.8.8 变量类型或结构体声明错误
程序中的变量或结构体的名称必须正确,否则程序会发生未声明的错误。例如下面的代码,用一个不存在的类型来声明一个变量。
ch a;
程序在运行时,会显示出这个变量错误,并且会显示有其他的错误。
5.1.c:17: 错误:‘ch’ 未声明 (在此函数内第一次使用)
5.1.c:17: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其
5.1.c:17: 错误:所在的函数内只报告一次。)
5.1.c:17: 错误:expected ‘;’ before ‘a’
1.8.9 使用不存在的函数的错误
如果程序引用了一个不存在的函数,会使用程序发生严重的错误。例如下面的代码,引
用了一个不存在的函数add。

k=add(i,j);
程序显示的错误信息如下所示,表明在main 函数中的add 函数没有定义。
/tmp/ccYQfDJy.o: In function `main':
5.1.c:(.text+0x61): undefined reference to `add'
collect2: ld 返回 1
5.8.10 大小写错误
C 程序对代码的大小写是敏感的,不同的大小写代表不同的内容。例如下面的代码,将
小写的“int”错误的写成了“Int”。
Int t;
程序显示的错误信息如下所示,表明“Int”类型不存在或未声明。发生这个错误时,会
输出多行错误提示。
5.1.c:16: 错误:‘Int’ 未声明 (在此函数内第一次使用)
5.1.c:16: 错误:(即使在一个函数内多次出现,每个未声明的标识符在其
5.1.c:16: 错误:所在的函数内只报告一次。)
5.1.c:16: 错误:expected ‘;’ before ‘t’
1.8.11 数据类型的错误
程序中的某些运算,必须针对相应的数据类型,否则这个运算会发生数据类型错误。例
如下面的代码,错误地将两个整型数进行求余运算。
float a,b;
a= a %b ;
程序编译时,输出下面的错误,表明“%”运算符的操作数无效。
5.1.c:19: 错误:双目运算符 % 操作数无效
1.8.12 赋值类型错误
任何一个变量,在赋值时必须使用相同的数据类型。例如下面的代码,错误地将一个字符串赋值给一个字符。
char c;
c="a";
程序编译时的结果如下所示,表明赋值时数据类型错误。
5.1.c:19: 警告:赋值时将指针赋给整数,未作类型转换
1.8.13 循环或判断语句中多加分号
分号在程序中的作用是表示一个语句结束。在程序的语句中用一个单独的分号表示一个
空语句。但是在循环或判断结构的后面,一个分号会导致程序的逻辑发生错误。关于这些结
构的使用方法,后面的章节将会详细讲到。下面的程序,在for 语句的后面,错误的添加了一个分号,导致程序不能正常地进行循环。
#include <stdio.h>
main()
{
int sum, j;
sum=0;
for(j=0;j<11;j++);
{
sum=sum+j;
}
printf(“%d”,sum);
}
这个程序的本意是要求出10 以内的整数和。但是在for 语句的后面,错误地使用了一个分号。这时,程序不能正确地进行循环,而是把分号作为一个语句进行循环,所以程序输出的结果为“11”。

静态库的代码在编译时就已链接到开发人员的应用程序中。静态库的后缀名是。a共享库是在程序开始运行时被加载。共享库后缀由。so和版本号组成

如数学共享库库名是libm。so。5    ,这里的标识字符为m,版本号为5

libm。a则是静态数学库.

 

-I<dir>      指定头文件搜索路径(注意是大写英文字母)

如  gcc   hello.c  -I/root/gcc/  -o   hello

-L<dir>        指定库文件搜索路径

如   gcc  hello.c  -L/root/gcc/lib    -o   hello

上面2个都是指定路径,而不是文件。

 

使用链接库     -l  (小写)

指定具体的库文件,由于linux中库函数都是以lib开头的,这里的库文件只需填写lib之后的内容就可以

如有静态库文件libm。a  ,则在调用是只需要填写-lm

若是共享库libm。so     也只是需填写-lm

 

在调试阶段尽量不进行优化。

 

嵌入式linux调试器GDB的使用

1.进入GDB       如      gdb   tets

  2查看文件 ,键入“l”或者“list”   

3.设置断点    b    行号      如   b   6     在第6行加入断点

4.  查看断点处情况   info  b

5运行代码     r

6.  查看变量  p  变量名   

如(gdb)p  n

    $1 = 0

    (gdb) p i 

    $2 = 134518440

GDB在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量的引用标记,若要再次引用可用“$N”代替变量名

7.观察变量     watch  变量名

8.单步运行     n    

9.程序继续运行     c   

10  退出GDB       q

                                                    常用GDB命令

break + 设置断点的行号    

tbreak + 行号或函数名      设置临时断点,到达后被自动删除 

break + filename +行号         用于指定文件的对应行设置断点

break  + 行号 + if +条件

 clear + 要清除断点行号

delete + 要清除的断点编号

disable  +断点编号        使断点失效

enable + 断点编号           使能断点

print或p + 变量或表达式

finish           一直运行到函数返回

 

 

make工程管理

vi  Makefile 或者 vi  makefile 

目标体target      依赖文件dependency_file         运行的命令command

#后面表示注释

格式

target :dependency_file

          command

注意每一个command前必须有“tab”符,否则会出错

例子:

#The simplest  example

edit : main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o
        gcc -o edit main.o kbd.o command.o display.o \
         insert.o search.o files.o utils.o

main.o : main.c defs.h
        gcc -c main.c -o  main
kbd.o : kbd.c defs.h command.h
        gcc -c kbd.c  -o   kbd.o
command.o : command.c defs.h command.h
        gcc -c command.c    -o   command.o
display.o : display.c defs.h buffer.h
          gcc -c display.c     -o  display.o
insert.o : insert.c defs.h buffer.h
         gcc -c insert.c       -o  insert.o
search.o : search.c defs.h buffer.h
         gcc -c search.c     -o  search.o 
files.o : files.c defs.h buffer.h command.h
          gcc -c files.c        -o file.o
utils.o : utils.c defs.h  
         gcc -c utils.c    -o utils.o 
clean :
         rm edit main.o kbd.o command.o display.o \
         insert.o search.o files.o utils.o

Makefile变量

VAR = var

使用变量格式:$(VAR)

例子:

OBJS =main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(OBJS)

      gcc -o edit $(OBJS)
main.o : main.c defs.h
       gcc -c main.c
kbd.o : kbd.c defs.h command.h
       gcc -c kbd.c
command.o : command.c defs.h command.h
        gcc -c command.c
display.o : display.c defs.h buffer.h
         gcc -c display.c
insert.o : insert.c defs.h buffer.h
          gcc -c insert.c
search.o : search.c defs.h buffer.h
         gcc -c search.c
files.o : files.c defs.h buffer.h command.h
         gcc -c files.c
utils.o : utils.c defs.h
        gcc -c utils.c
clean :
         rm edit  $(OBJS)

 

makefile中常见自动变量

$@            目标文件的完整名称

$^               所有不重复依赖文件,以空格分开

例子:

OBJS =main.o kbd.o command.o display.o \
insert.o search.o files.o utils.o

edit : $(OBJS)

      gcc $^  -o  $@

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值