• GCC编译器入门


      GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器。它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分。GCC原本作为GNU操作系统的官方编译器,现已被大多数类Unix操作系统(如Linux、BSD、Mac OS X等)采纳为标准的编译器,GCC同样适用于微软的Windows。 GCC是自由软件过程发展中的著名例子,由自由软件基金会以GPL协议发布。它处理能够高效的编译C语言以外,还可以编译其他语言。并且,现在的GCC已经不光包括编译器本身,还包含了编译过程中的工具链。

    1 GCC编译流程

    在学习使用GCC编译程序之前,首先要知道编译C程序的基本流程,一般情况下分为下面四步:

    (1) 对C语言进行预处理,生成*.i文件。

    (2) 将上一步生成的*.i文件编译生成汇编语言文件,后缀名为*.s

    (3) 将汇编语言文件*.s经过汇编,生成目标文件,后缀名为*.o

    (4) 将各个模块的*.o文件链接起来,生成最终的可执行文件

    2 GCC常用选项

    GCC的编译选项非常多,现在有上千个,但是我们常用的并不多,下面我们只介绍其中非常实用的几个。

    在这之前,我们先编写下面的几个源文件,以备测试只用。

     1 //main.c
     2 #include <stdio.h>
     3 
     4 extern int add(int a, int b);
     5 extern int mul(int a, int b);
     6 
     7 int main(void)
     8 {
     9     int a = 10, b = 5;
    10     int result;
    11     
    12     result = add(a, mul(a,  b));
    13     printf("result = %d
    ", result);
    14     return 0;
    15 }
    main.c
    1 //test1.c
    2 int add(int a, int b)
    3 {
    4     return a+b;
    5 }
    test1.c
    1 //test2.c
    2 int mul(int a, int b)
    3 {
    4     return a*b;
    5 }
    test2.c

    2.1 -c选项

      该选项(小写c)表示编译、汇编指定的源文件,但是不进行链接。该选项的使用方法如下:

    gcc -c source.c

    也就是在-c选项后面紧跟要编译、汇编的C源文件,最终生成与源文件名称相同,但是后缀为*.o结尾的目标文件。

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  test1.c  test2.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c test1.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  test1.c  test1.o  test2.c

    可以看到,使用-c选项编译之后生成了对应的*.o目标文件。当然,你也可以一次性指定多个C源文件,使用-c选项后,会针对每一个C源文件生成一个相应的*.o目标文件。

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c test2.c main.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  main.o  test1.c  test1.o  test2.c  test2.o

    2.2 -S选项

      该选项(大写S)将C语言源文件编译生成汇编语言文件,但是并不汇编该程序。注意:汇编过程的作用是将汇编语言文件编译成目标文件*.o,而-S选项的作用是得到汇编语言文件*.s。该选项的使用方法为:

    gcc -S source.c

    使用该选项,最终生成与源文件名称相同,但是后缀为*.s结尾的汇编语言文件。

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -S test1.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  test1.c  test1.s  test2.c

    当然,输入的源文件也不止一个,你可以编译当前目录下的所有C语言源文件:

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -S *.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  main.s  test1.c  test1.s  test2.c  test2.s

    我们也可以查看生成的汇编语言代码:

     1     .file    "test1.c"
     2     .text
     3     .globl    add
     4     .type    add, @function
     5 add:
     6 .LFB0:
     7     .cfi_startproc
     8     pushl    %ebp
     9     .cfi_def_cfa_offset 8
    10     .cfi_offset 5, -8
    11     movl    %esp, %ebp
    12     .cfi_def_cfa_register 5
    13     movl    12(%ebp), %eax
    14     movl    8(%ebp), %edx
    15     addl    %edx, %eax
    16     popl    %ebp
    17     .cfi_restore 5
    18     .cfi_def_cfa 4, 4
    19     ret
    20     .cfi_endproc
    21 .LFE0:
    22     .size    add, .-add
    23     .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"
    24     .section    .note.GNU-stack,"",@progbits
    test1.s

    2.3 -E选项

      该选项对C语言源文件进行预处理,但是并不编译该程序。对于一般的预处理问题(比如,宏的展开问题、文件的包含问题等),可以使用这个选项进行查看。另外,如果直接使用此选项,程序会将预处理结果直接输出到终端,不便于查看,因此,一般可以使用重定向将程序输出结果保存到一个文本文件中,格式如下:

    gcc -E source.c > output

    如果我们对main.c执行预编译,得到的output文件内容如下:

      1 # 1 "main.c"
      2 # 1 "<command-line>"
      3 # 1 "/usr/include/stdc-predef.h" 1 3 4
      4 # 1 "<command-line>" 2
      5 # 1 "main.c"
      6 
      7 # 1 "/usr/include/stdio.h" 1 3 4
      8 # 27 "/usr/include/stdio.h" 3 4
      9 # 1 "/usr/include/features.h" 1 3 4
     10 # 374 "/usr/include/features.h" 3 4
     11 # 1 "/usr/include/i386-linux-gnu/sys/cdefs.h" 1 3 4
     12 # 385 "/usr/include/i386-linux-gnu/sys/cdefs.h" 3 4
     13 # 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
     14 # 386 "/usr/include/i386-linux-gnu/sys/cdefs.h" 2 3 4
     15 # 375 "/usr/include/features.h" 2 3 4
     16 # 398 "/usr/include/features.h" 3 4
     17 # 1 "/usr/include/i386-linux-gnu/gnu/stubs.h" 1 3 4
     18 
     19 
     20 
     21 
     22 
     23 
     24 # 1 "/usr/include/i386-linux-gnu/gnu/stubs-32.h" 1 3 4
     25 # 8 "/usr/include/i386-linux-gnu/gnu/stubs.h" 2 3 4
     26 # 399 "/usr/include/features.h" 2 3 4
     27 # 28 "/usr/include/stdio.h" 2 3 4
     28 
     29 
     30 
     31 
     32 
     33 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 1 3 4
     34 # 212 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 3 4
     35 typedef unsigned int size_t;
     36 # 34 "/usr/include/stdio.h" 2 3 4
     37 
     38 # 1 "/usr/include/i386-linux-gnu/bits/types.h" 1 3 4
     39 # 27 "/usr/include/i386-linux-gnu/bits/types.h" 3 4
     40 # 1 "/usr/include/i386-linux-gnu/bits/wordsize.h" 1 3 4
     41 # 28 "/usr/include/i386-linux-gnu/bits/types.h" 2 3 4
     42 
     43 
     44 typedef unsigned char __u_char;
     45 typedef unsigned short int __u_short;
     46 typedef unsigned int __u_int;
     47 typedef unsigned long int __u_long;
     48 
     49 
     50 typedef signed char __int8_t;
     51 typedef unsigned char __uint8_t;
     52 typedef signed short int __int16_t;
     53 typedef unsigned short int __uint16_t;
     54 typedef signed int __int32_t;
     55 typedef unsigned int __uint32_t;
     56 
     57 
     58 
     59 
     60 __extension__ typedef signed long long int __int64_t;
     61 __extension__ typedef unsigned long long int __uint64_t;
     62 
     63 
     64 
     65 
     66 
     67 
     68 
     69 __extension__ typedef long long int __quad_t;
     70 __extension__ typedef unsigned long long int __u_quad_t;
     71 # 121 "/usr/include/i386-linux-gnu/bits/types.h" 3 4
     72 # 1 "/usr/include/i386-linux-gnu/bits/typesizes.h" 1 3 4
     73 # 122 "/usr/include/i386-linux-gnu/bits/types.h" 2 3 4
     74 
     75 
     76 __extension__ typedef __u_quad_t __dev_t;
     77 __extension__ typedef unsigned int __uid_t;
     78 __extension__ typedef unsigned int __gid_t;
     79 __extension__ typedef unsigned long int __ino_t;
     80 __extension__ typedef __u_quad_t __ino64_t;
     81 __extension__ typedef unsigned int __mode_t;
     82 __extension__ typedef unsigned int __nlink_t;
     83 __extension__ typedef long int __off_t;
     84 __extension__ typedef __quad_t __off64_t;
     85 __extension__ typedef int __pid_t;
     86 __extension__ typedef struct { int __val[2]; } __fsid_t;
     87 __extension__ typedef long int __clock_t;
     88 __extension__ typedef unsigned long int __rlim_t;
     89 __extension__ typedef __u_quad_t __rlim64_t;
     90 __extension__ typedef unsigned int __id_t;
     91 __extension__ typedef long int __time_t;
     92 __extension__ typedef unsigned int __useconds_t;
     93 __extension__ typedef long int __suseconds_t;
     94 
     95 __extension__ typedef int __daddr_t;
     96 __extension__ typedef int __key_t;
     97 
     98 
     99 __extension__ typedef int __clockid_t;
    100 
    101 
    102 __extension__ typedef void * __timer_t;
    103 
    104 
    105 __extension__ typedef long int __blksize_t;
    106 
    107 
    108 
    109 
    110 __extension__ typedef long int __blkcnt_t;
    111 __extension__ typedef __quad_t __blkcnt64_t;
    112 
    113 
    114 __extension__ typedef unsigned long int __fsblkcnt_t;
    115 __extension__ typedef __u_quad_t __fsblkcnt64_t;
    116 
    117 
    118 __extension__ typedef unsigned long int __fsfilcnt_t;
    119 __extension__ typedef __u_quad_t __fsfilcnt64_t;
    120 
    121 
    122 __extension__ typedef int __fsword_t;
    123 
    124 __extension__ typedef int __ssize_t;
    125 
    126 
    127 __extension__ typedef long int __syscall_slong_t;
    128 
    129 __extension__ typedef unsigned long int __syscall_ulong_t;
    130 
    131 
    132 
    133 typedef __off64_t __loff_t;
    134 typedef __quad_t *__qaddr_t;
    135 typedef char *__caddr_t;
    136 
    137 
    138 __extension__ typedef int __intptr_t;
    139 
    140 
    141 __extension__ typedef unsigned int __socklen_t;
    142 # 36 "/usr/include/stdio.h" 2 3 4
    143 # 44 "/usr/include/stdio.h" 3 4
    144 struct _IO_FILE;
    145 
    146 
    147 
    148 typedef struct _IO_FILE FILE;
    149 
    150 
    151 
    152 
    153 
    154 # 64 "/usr/include/stdio.h" 3 4
    155 typedef struct _IO_FILE __FILE;
    156 # 74 "/usr/include/stdio.h" 3 4
    157 # 1 "/usr/include/libio.h" 1 3 4
    158 # 31 "/usr/include/libio.h" 3 4
    159 # 1 "/usr/include/_G_config.h" 1 3 4
    160 # 15 "/usr/include/_G_config.h" 3 4
    161 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stddef.h" 1 3 4
    162 # 16 "/usr/include/_G_config.h" 2 3 4
    163 
    164 
    165 
    166 
    167 # 1 "/usr/include/wchar.h" 1 3 4
    168 # 82 "/usr/include/wchar.h" 3 4
    169 typedef struct
    170 {
    171   int __count;
    172   union
    173   {
    174 
    175     unsigned int __wch;
    176 
    177 
    178 
    179     char __wchb[4];
    180   } __value;
    181 } __mbstate_t;
    182 # 21 "/usr/include/_G_config.h" 2 3 4
    183 typedef struct
    184 {
    185   __off_t __pos;
    186   __mbstate_t __state;
    187 } _G_fpos_t;
    188 typedef struct
    189 {
    190   __off64_t __pos;
    191   __mbstate_t __state;
    192 } _G_fpos64_t;
    193 # 32 "/usr/include/libio.h" 2 3 4
    194 # 49 "/usr/include/libio.h" 3 4
    195 # 1 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h" 1 3 4
    196 # 40 "/usr/lib/gcc/i686-linux-gnu/4.8/include/stdarg.h" 3 4
    197 typedef __builtin_va_list __gnuc_va_list;
    198 # 50 "/usr/include/libio.h" 2 3 4
    199 # 144 "/usr/include/libio.h" 3 4
    200 struct _IO_jump_t; struct _IO_FILE;
    201 # 154 "/usr/include/libio.h" 3 4
    202 typedef void _IO_lock_t;
    203 
    204 
    205 
    206 
    207 
    208 struct _IO_marker {
    209   struct _IO_marker *_next;
    210   struct _IO_FILE *_sbuf;
    211 
    212 
    213 
    214   int _pos;
    215 # 177 "/usr/include/libio.h" 3 4
    216 };
    217 
    218 
    219 enum __codecvt_result
    220 {
    221   __codecvt_ok,
    222   __codecvt_partial,
    223   __codecvt_error,
    224   __codecvt_noconv
    225 };
    226 # 245 "/usr/include/libio.h" 3 4
    227 struct _IO_FILE {
    228   int _flags;
    229 
    230 
    231 
    232 
    233   char* _IO_read_ptr;
    234   char* _IO_read_end;
    235   char* _IO_read_base;
    236   char* _IO_write_base;
    237   char* _IO_write_ptr;
    238   char* _IO_write_end;
    239   char* _IO_buf_base;
    240   char* _IO_buf_end;
    241 
    242   char *_IO_save_base;
    243   char *_IO_backup_base;
    244   char *_IO_save_end;
    245 
    246   struct _IO_marker *_markers;
    247 
    248   struct _IO_FILE *_chain;
    249 
    250   int _fileno;
    251 
    252 
    253 
    254   int _flags2;
    255 
    256   __off_t _old_offset;
    257 
    258 
    259 
    260   unsigned short _cur_column;
    261   signed char _vtable_offset;
    262   char _shortbuf[1];
    263 
    264 
    265 
    266   _IO_lock_t *_lock;
    267 # 293 "/usr/include/libio.h" 3 4
    268   __off64_t _offset;
    269 # 302 "/usr/include/libio.h" 3 4
    270   void *__pad1;
    271   void *__pad2;
    272   void *__pad3;
    273   void *__pad4;
    274   size_t __pad5;
    275 
    276   int _mode;
    277 
    278   char _unused2[15 * sizeof (int) - 4 * sizeof (void *) - sizeof (size_t)];
    279 
    280 };
    281 
    282 
    283 typedef struct _IO_FILE _IO_FILE;
    284 
    285 
    286 struct _IO_FILE_plus;
    287 
    288 extern struct _IO_FILE_plus _IO_2_1_stdin_;
    289 extern struct _IO_FILE_plus _IO_2_1_stdout_;
    290 extern struct _IO_FILE_plus _IO_2_1_stderr_;
    291 # 338 "/usr/include/libio.h" 3 4
    292 typedef __ssize_t __io_read_fn (void *__cookie, char *__buf, size_t __nbytes);
    293 
    294 
    295 
    296 
    297 
    298 
    299 
    300 typedef __ssize_t __io_write_fn (void *__cookie, const char *__buf,
    301      size_t __n);
    302 
    303 
    304 
    305 
    306 
    307 
    308 
    309 typedef int __io_seek_fn (void *__cookie, __off64_t *__pos, int __w);
    310 
    311 
    312 typedef int __io_close_fn (void *__cookie);
    313 # 390 "/usr/include/libio.h" 3 4
    314 extern int __underflow (_IO_FILE *);
    315 extern int __uflow (_IO_FILE *);
    316 extern int __overflow (_IO_FILE *, int);
    317 # 434 "/usr/include/libio.h" 3 4
    318 extern int _IO_getc (_IO_FILE *__fp);
    319 extern int _IO_putc (int __c, _IO_FILE *__fp);
    320 extern int _IO_feof (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
    321 extern int _IO_ferror (_IO_FILE *__fp) __attribute__ ((__nothrow__ , __leaf__));
    322 
    323 extern int _IO_peekc_locked (_IO_FILE *__fp);
    324 
    325 
    326 
    327 
    328 
    329 extern void _IO_flockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
    330 extern void _IO_funlockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
    331 extern int _IO_ftrylockfile (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
    332 # 464 "/usr/include/libio.h" 3 4
    333 extern int _IO_vfscanf (_IO_FILE * __restrict, const char * __restrict,
    334    __gnuc_va_list, int *__restrict);
    335 extern int _IO_vfprintf (_IO_FILE *__restrict, const char *__restrict,
    336     __gnuc_va_list);
    337 extern __ssize_t _IO_padn (_IO_FILE *, int, __ssize_t);
    338 extern size_t _IO_sgetn (_IO_FILE *, void *, size_t);
    339 
    340 extern __off64_t _IO_seekoff (_IO_FILE *, __off64_t, int, int);
    341 extern __off64_t _IO_seekpos (_IO_FILE *, __off64_t, int);
    342 
    343 extern void _IO_free_backup_area (_IO_FILE *) __attribute__ ((__nothrow__ , __leaf__));
    344 # 75 "/usr/include/stdio.h" 2 3 4
    345 
    346 
    347 
    348 
    349 typedef __gnuc_va_list va_list;
    350 # 90 "/usr/include/stdio.h" 3 4
    351 typedef __off_t off_t;
    352 # 102 "/usr/include/stdio.h" 3 4
    353 typedef __ssize_t ssize_t;
    354 
    355 
    356 
    357 
    358 
    359 
    360 
    361 typedef _G_fpos_t fpos_t;
    362 
    363 
    364 
    365 
    366 # 164 "/usr/include/stdio.h" 3 4
    367 # 1 "/usr/include/i386-linux-gnu/bits/stdio_lim.h" 1 3 4
    368 # 165 "/usr/include/stdio.h" 2 3 4
    369 
    370 
    371 
    372 extern struct _IO_FILE *stdin;
    373 extern struct _IO_FILE *stdout;
    374 extern struct _IO_FILE *stderr;
    375 
    376 
    377 
    378 
    379 
    380 
    381 
    382 extern int remove (const char *__filename) __attribute__ ((__nothrow__ , __leaf__));
    383 
    384 extern int rename (const char *__old, const char *__new) __attribute__ ((__nothrow__ , __leaf__));
    385 
    386 
    387 
    388 
    389 extern int renameat (int __oldfd, const char *__old, int __newfd,
    390        const char *__new) __attribute__ ((__nothrow__ , __leaf__));
    391 
    392 
    393 
    394 
    395 
    396 
    397 
    398 
    399 extern FILE *tmpfile (void) ;
    400 # 209 "/usr/include/stdio.h" 3 4
    401 extern char *tmpnam (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
    402 
    403 
    404 
    405 
    406 
    407 extern char *tmpnam_r (char *__s) __attribute__ ((__nothrow__ , __leaf__)) ;
    408 # 227 "/usr/include/stdio.h" 3 4
    409 extern char *tempnam (const char *__dir, const char *__pfx)
    410      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__malloc__)) ;
    411 
    412 
    413 
    414 
    415 
    416 
    417 
    418 
    419 extern int fclose (FILE *__stream);
    420 
    421 
    422 
    423 
    424 extern int fflush (FILE *__stream);
    425 
    426 # 252 "/usr/include/stdio.h" 3 4
    427 extern int fflush_unlocked (FILE *__stream);
    428 # 266 "/usr/include/stdio.h" 3 4
    429 
    430 
    431 
    432 
    433 
    434 
    435 extern FILE *fopen (const char *__restrict __filename,
    436       const char *__restrict __modes) ;
    437 
    438 
    439 
    440 
    441 extern FILE *freopen (const char *__restrict __filename,
    442         const char *__restrict __modes,
    443         FILE *__restrict __stream) ;
    444 # 295 "/usr/include/stdio.h" 3 4
    445 
    446 # 306 "/usr/include/stdio.h" 3 4
    447 extern FILE *fdopen (int __fd, const char *__modes) __attribute__ ((__nothrow__ , __leaf__)) ;
    448 # 319 "/usr/include/stdio.h" 3 4
    449 extern FILE *fmemopen (void *__s, size_t __len, const char *__modes)
    450   __attribute__ ((__nothrow__ , __leaf__)) ;
    451 
    452 
    453 
    454 
    455 extern FILE *open_memstream (char **__bufloc, size_t *__sizeloc) __attribute__ ((__nothrow__ , __leaf__)) ;
    456 
    457 
    458 
    459 
    460 
    461 
    462 extern void setbuf (FILE *__restrict __stream, char *__restrict __buf) __attribute__ ((__nothrow__ , __leaf__));
    463 
    464 
    465 
    466 extern int setvbuf (FILE *__restrict __stream, char *__restrict __buf,
    467       int __modes, size_t __n) __attribute__ ((__nothrow__ , __leaf__));
    468 
    469 
    470 
    471 
    472 
    473 extern void setbuffer (FILE *__restrict __stream, char *__restrict __buf,
    474          size_t __size) __attribute__ ((__nothrow__ , __leaf__));
    475 
    476 
    477 extern void setlinebuf (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    478 
    479 
    480 
    481 
    482 
    483 
    484 
    485 
    486 extern int fprintf (FILE *__restrict __stream,
    487       const char *__restrict __format, ...);
    488 
    489 
    490 
    491 
    492 extern int printf (const char *__restrict __format, ...);
    493 
    494 extern int sprintf (char *__restrict __s,
    495       const char *__restrict __format, ...) __attribute__ ((__nothrow__));
    496 
    497 
    498 
    499 
    500 
    501 extern int vfprintf (FILE *__restrict __s, const char *__restrict __format,
    502        __gnuc_va_list __arg);
    503 
    504 
    505 
    506 
    507 extern int vprintf (const char *__restrict __format, __gnuc_va_list __arg);
    508 
    509 extern int vsprintf (char *__restrict __s, const char *__restrict __format,
    510        __gnuc_va_list __arg) __attribute__ ((__nothrow__));
    511 
    512 
    513 
    514 
    515 
    516 extern int snprintf (char *__restrict __s, size_t __maxlen,
    517        const char *__restrict __format, ...)
    518      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 4)));
    519 
    520 extern int vsnprintf (char *__restrict __s, size_t __maxlen,
    521         const char *__restrict __format, __gnuc_va_list __arg)
    522      __attribute__ ((__nothrow__)) __attribute__ ((__format__ (__printf__, 3, 0)));
    523 
    524 # 412 "/usr/include/stdio.h" 3 4
    525 extern int vdprintf (int __fd, const char *__restrict __fmt,
    526        __gnuc_va_list __arg)
    527      __attribute__ ((__format__ (__printf__, 2, 0)));
    528 extern int dprintf (int __fd, const char *__restrict __fmt, ...)
    529      __attribute__ ((__format__ (__printf__, 2, 3)));
    530 
    531 
    532 
    533 
    534 
    535 
    536 
    537 
    538 extern int fscanf (FILE *__restrict __stream,
    539      const char *__restrict __format, ...) ;
    540 
    541 
    542 
    543 
    544 extern int scanf (const char *__restrict __format, ...) ;
    545 
    546 extern int sscanf (const char *__restrict __s,
    547      const char *__restrict __format, ...) __attribute__ ((__nothrow__ , __leaf__));
    548 # 443 "/usr/include/stdio.h" 3 4
    549 extern int fscanf (FILE *__restrict __stream, const char *__restrict __format, ...) __asm__ ("" "__isoc99_fscanf")
    550 
    551                                ;
    552 extern int scanf (const char *__restrict __format, ...) __asm__ ("" "__isoc99_scanf")
    553                               ;
    554 extern int sscanf (const char *__restrict __s, const char *__restrict __format, ...) __asm__ ("" "__isoc99_sscanf") __attribute__ ((__nothrow__ , __leaf__))
    555 
    556                       ;
    557 # 463 "/usr/include/stdio.h" 3 4
    558 
    559 
    560 
    561 
    562 
    563 
    564 
    565 
    566 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format,
    567       __gnuc_va_list __arg)
    568      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
    569 
    570 
    571 
    572 
    573 
    574 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg)
    575      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
    576 
    577 
    578 extern int vsscanf (const char *__restrict __s,
    579       const char *__restrict __format, __gnuc_va_list __arg)
    580      __attribute__ ((__nothrow__ , __leaf__)) __attribute__ ((__format__ (__scanf__, 2, 0)));
    581 # 494 "/usr/include/stdio.h" 3 4
    582 extern int vfscanf (FILE *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vfscanf")
    583 
    584 
    585 
    586      __attribute__ ((__format__ (__scanf__, 2, 0))) ;
    587 extern int vscanf (const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vscanf")
    588 
    589      __attribute__ ((__format__ (__scanf__, 1, 0))) ;
    590 extern int vsscanf (const char *__restrict __s, const char *__restrict __format, __gnuc_va_list __arg) __asm__ ("" "__isoc99_vsscanf") __attribute__ ((__nothrow__ , __leaf__))
    591 
    592 
    593 
    594      __attribute__ ((__format__ (__scanf__, 2, 0)));
    595 # 522 "/usr/include/stdio.h" 3 4
    596 
    597 
    598 
    599 
    600 
    601 
    602 
    603 
    604 
    605 extern int fgetc (FILE *__stream);
    606 extern int getc (FILE *__stream);
    607 
    608 
    609 
    610 
    611 
    612 extern int getchar (void);
    613 
    614 # 550 "/usr/include/stdio.h" 3 4
    615 extern int getc_unlocked (FILE *__stream);
    616 extern int getchar_unlocked (void);
    617 # 561 "/usr/include/stdio.h" 3 4
    618 extern int fgetc_unlocked (FILE *__stream);
    619 
    620 
    621 
    622 
    623 
    624 
    625 
    626 
    627 
    628 
    629 
    630 extern int fputc (int __c, FILE *__stream);
    631 extern int putc (int __c, FILE *__stream);
    632 
    633 
    634 
    635 
    636 
    637 extern int putchar (int __c);
    638 
    639 # 594 "/usr/include/stdio.h" 3 4
    640 extern int fputc_unlocked (int __c, FILE *__stream);
    641 
    642 
    643 
    644 
    645 
    646 
    647 
    648 extern int putc_unlocked (int __c, FILE *__stream);
    649 extern int putchar_unlocked (int __c);
    650 
    651 
    652 
    653 
    654 
    655 
    656 extern int getw (FILE *__stream);
    657 
    658 
    659 extern int putw (int __w, FILE *__stream);
    660 
    661 
    662 
    663 
    664 
    665 
    666 
    667 
    668 extern char *fgets (char *__restrict __s, int __n, FILE *__restrict __stream)
    669      ;
    670 # 638 "/usr/include/stdio.h" 3 4
    671 extern char *gets (char *__s) __attribute__ ((__deprecated__));
    672 
    673 
    674 # 665 "/usr/include/stdio.h" 3 4
    675 extern __ssize_t __getdelim (char **__restrict __lineptr,
    676           size_t *__restrict __n, int __delimiter,
    677           FILE *__restrict __stream) ;
    678 extern __ssize_t getdelim (char **__restrict __lineptr,
    679         size_t *__restrict __n, int __delimiter,
    680         FILE *__restrict __stream) ;
    681 
    682 
    683 
    684 
    685 
    686 
    687 
    688 extern __ssize_t getline (char **__restrict __lineptr,
    689        size_t *__restrict __n,
    690        FILE *__restrict __stream) ;
    691 
    692 
    693 
    694 
    695 
    696 
    697 
    698 
    699 extern int fputs (const char *__restrict __s, FILE *__restrict __stream);
    700 
    701 
    702 
    703 
    704 
    705 extern int puts (const char *__s);
    706 
    707 
    708 
    709 
    710 
    711 
    712 extern int ungetc (int __c, FILE *__stream);
    713 
    714 
    715 
    716 
    717 
    718 
    719 extern size_t fread (void *__restrict __ptr, size_t __size,
    720        size_t __n, FILE *__restrict __stream) ;
    721 
    722 
    723 
    724 
    725 extern size_t fwrite (const void *__restrict __ptr, size_t __size,
    726         size_t __n, FILE *__restrict __s);
    727 
    728 # 737 "/usr/include/stdio.h" 3 4
    729 extern size_t fread_unlocked (void *__restrict __ptr, size_t __size,
    730          size_t __n, FILE *__restrict __stream) ;
    731 extern size_t fwrite_unlocked (const void *__restrict __ptr, size_t __size,
    732           size_t __n, FILE *__restrict __stream);
    733 
    734 
    735 
    736 
    737 
    738 
    739 
    740 
    741 extern int fseek (FILE *__stream, long int __off, int __whence);
    742 
    743 
    744 
    745 
    746 extern long int ftell (FILE *__stream) ;
    747 
    748 
    749 
    750 
    751 extern void rewind (FILE *__stream);
    752 
    753 # 773 "/usr/include/stdio.h" 3 4
    754 extern int fseeko (FILE *__stream, __off_t __off, int __whence);
    755 
    756 
    757 
    758 
    759 extern __off_t ftello (FILE *__stream) ;
    760 # 792 "/usr/include/stdio.h" 3 4
    761 
    762 
    763 
    764 
    765 
    766 
    767 extern int fgetpos (FILE *__restrict __stream, fpos_t *__restrict __pos);
    768 
    769 
    770 
    771 
    772 extern int fsetpos (FILE *__stream, const fpos_t *__pos);
    773 # 815 "/usr/include/stdio.h" 3 4
    774 
    775 # 824 "/usr/include/stdio.h" 3 4
    776 
    777 
    778 extern void clearerr (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    779 
    780 extern int feof (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    781 
    782 extern int ferror (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    783 
    784 
    785 
    786 
    787 extern void clearerr_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    788 extern int feof_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    789 extern int ferror_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    790 
    791 
    792 
    793 
    794 
    795 
    796 
    797 
    798 extern void perror (const char *__s);
    799 
    800 
    801 
    802 
    803 
    804 
    805 # 1 "/usr/include/i386-linux-gnu/bits/sys_errlist.h" 1 3 4
    806 # 26 "/usr/include/i386-linux-gnu/bits/sys_errlist.h" 3 4
    807 extern int sys_nerr;
    808 extern const char *const sys_errlist[];
    809 # 854 "/usr/include/stdio.h" 2 3 4
    810 
    811 
    812 
    813 
    814 extern int fileno (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    815 
    816 
    817 
    818 
    819 extern int fileno_unlocked (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    820 # 873 "/usr/include/stdio.h" 3 4
    821 extern FILE *popen (const char *__command, const char *__modes) ;
    822 
    823 
    824 
    825 
    826 
    827 extern int pclose (FILE *__stream);
    828 
    829 
    830 
    831 
    832 
    833 extern char *ctermid (char *__s) __attribute__ ((__nothrow__ , __leaf__));
    834 # 913 "/usr/include/stdio.h" 3 4
    835 extern void flockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    836 
    837 
    838 
    839 extern int ftrylockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__)) ;
    840 
    841 
    842 extern void funlockfile (FILE *__stream) __attribute__ ((__nothrow__ , __leaf__));
    843 # 943 "/usr/include/stdio.h" 3 4
    844 
    845 # 3 "main.c" 2
    846 
    847 extern int add(int a, int b);
    848 extern int mul(int a, int b);
    849 
    850 int main(void)
    851 {
    852  int a = 10, b = 5;
    853  int result;
    854 
    855  result = add(a, mul(a, b));
    856  printf("result = %d
    ", result);
    857  return 0;
    858 }
    output

    当然,我们也可以使用接下来要介绍的-o命令来指定输出文件名称,格式如下:

    gcc -E source.c -o source.i

    使用该命令对main.c进行预处理,得到的main.i文件内容与之前重定向输出得到的output文件的内容完全相同。

    2.4 -o选项

      该选项(小写O)用于将输入文件编译后输出指定名称的文件。该选项有两种使用方法,第一种是紧跟gcc命令之后:

    gcc -o app source1.c source2.c source3.c

    那么,编译我们的测试程序可以使用下面的方式:

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -o app *.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    app  main.c  test1.c  test2.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 
    result = 60

    还有另外一种方式,即-o选项放置在最后:

    gcc source1.c source2.c source3.c -o app 

    这种方式的逻辑性更强,语义可以理解为编译C语言源文件得到最终的可执行程序app,使用这种方式编译我们的测试程序过程如下:

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ rm app 
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc test1.c test2.c main.c -o app
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    app  main.c  test1.c  test2.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 
    result = 60

    此外,此选项很多时候用作链接多个目标文件的时候,我们可能需要先对不同的源文件进行相应的操作来得到目标文件*.o,然后在最后将这些目标文件链接成一个可执行文件。

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -c *.c
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    main.c  main.o  test1.c  test1.o  test2.c  test2.o
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc main.o test1.o test2.o -o app
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ls
    app  main.c  main.o  test1.c  test1.o  test2.c  test2.o
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ./app 
    result = 60

    2.5 -I选项

      该选项用于指定包含的头文件的目录,这一点对于大型的代码组织来说是很有用的。

    2.6 -g选项

      该选项用来生成可以被gdb调试器使用的调试信息。只有使用了该选项后生成的可执行文件才带有程序中引用的符号表,这是gdb调试程序才能对可执行程序进行调试。

    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc *.c -o app
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ll app
    -rwxrwxr-x 1 xiaomanon xiaomanon 7381 12月 29 15:23 app*
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ gcc -g *.c -o app
    xiaomanon@xiaomanon-machine:~/Documents/c_code$ ll app
    -rwxrwxr-x 1 xiaomanon xiaomanon 8825 12月 29 15:23 app*

    以上命令分别生成了不带调试信息的可执行文件和带有调试信息的可执行文件,并对比了两者的文件大小,可以看出使用的-g选项生成的可执行文件明显要比没有使用-g选项的可执行文件大。

  • 相关阅读:
    ASP.NET 4.0 与 Entity Framework 4第四篇Entity Framework在三层架构中的使用
    ASP.NET 4.0 与 Entity Framework 4第一篇采用ModelFirst 开发方式创建数据库
    ASP.NET 4.0 与 Entity Framework 4第二篇使用Entity Framework 进行CRUD操作
    ASP.NET 4.0 与 Entity Framework 4第三篇使用Entity Framework调用存储过程
    Unity3D4.* NGUI制作动态字库
    Unity3D内存释放
    1112 Stucked Keyboard (20 分)(map)【回顾】
    1116 Come on! Let's C (20 分)(hash散列)
    1108 Finding Average (20 分)(字符串处理)
    1113 Integer Set Partition (25 分)(排序)
  • 原文地址:https://www.cnblogs.com/xiaomanon/p/4191583.html
Copyright © 2020-2023  润新知