一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 2209|回复: 0
收起左侧

GCC 参数

[复制链接]
发表于 2017-1-13 17:21 | 显示全部楼层 |阅读模式
[介绍] ; }% W9 N. R" O4 a4 Y
gcc and g++分别是gnu的c & c++编译器 gcc/g++在执行编译工作的时候,总共需要4步
9 W# j9 _7 Z: I& G3 A8 d8 C* C! T5 z
1.预处理,生成.i的文件[预处理器cpp]
  T# c* ?) R1 w2 v3 W7 e2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs] 1 W* M, N+ |" \4 i/ G- L5 ~
3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]   [# n( g8 t/ D* E$ o7 x
4.连接目标代码,生成可执行程序[链接器ld]
' K* Y8 Q+ ~, ?/ V# |[参数详解]
4 i6 S) M( w3 B+ r+ {-x language filename
2 I) D0 _! v, S+ F; C  设定文件所使用的语言,使后缀名无效,对以后的多个有效.也就是根据约定C语言的后
4 ~5 S" _0 k# r+ Y) J. K6 `/ y缀名称是.c的,而C++的后缀名是.C或者.cpp,如果你很个性,决定你的C代码文件的后缀
, e& T8 x2 x/ V7 N  E+ Q$ T! G名是.pig 哈哈,那你就要用这个参数,这个参数对他后面的文件名都起作用,除非到了
" C9 `4 D! `" Q" |下一个参数的使用。 # j" d/ d( o+ b5 U; A
  可以使用的参数吗有下面的这些
8 J5 [9 a) r6 ^( N" ~  `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', and `a
3 s$ g9 @3 v2 h) s5 {4 W* Bssembler-with-cpp'.
' D$ \; }8 {) Q1 Y7 U5 Z  看到英文,应该可以理解的。
' K. w0 J$ H( m# r) n  例子用法:
8 n9 w% z3 T) a# m6 `0 v  gcc -x c hello.pig 0 v1 }$ h2 R3 E1 o6 q
  
. f6 z3 W/ t! u% [9 B9 w9 k$ T-x none filename
5 z4 l# [8 i7 _) _  关掉上一个选项,也就是让gcc根据文件名后缀,自动识别文件类型 . P* s- P+ j: H6 b% e' y
  例子用法: , m( h5 l# t" W9 n4 J
  gcc -x c hello.pig -x none hello2.c
5 R" ]7 J: [1 S   - z7 i' \/ l" y1 Q, J* z5 x- H
-c % Y& q! n! U' J$ w6 g. q
  只激活预处理,编译,和汇编,也就是他只把程序做成obj文件
. U9 k  ]' w1 @! H* o, K# w  例子用法: / f$ |+ H, T1 ^
  gcc -c hello.c 6 d6 R- J9 o4 E. T. F+ [: c4 n
  他将生成.o的obj文件 1 S& w- |, ^( ~; l
-S
9 r6 @. x' N" r$ U, ~  只激活预处理和编译,就是指把文件编译成为汇编代码。   v# J& |5 R* B! m! D) J0 E! O
  例子用法 ! H. c6 Z; w; Q. n7 b
  gcc -S hello.c 5 L" q2 `% w7 X  ?1 N* Y3 q
  他将生成.s的汇编代码,你可以用文本编辑器察看 6 z, w' [. S* l
-E
; ^/ b; ^, @" i  只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面. " K- d1 Y6 n( v/ f5 r! G1 B
  例子用法:
4 i% U# [  v2 g  gcc -E hello.c > pianoapan.txt 3 y6 H4 t: V9 ]9 @, B, u1 a9 q: N
  gcc -E hello.c | more
/ V( }1 G( N" R/ }7 ]# Z. X$ v6 \  慢慢看吧,一个hello word 也要与处理成800行的代码
9 A& i+ ^3 K9 e-o
4 h) E: S. K$ Y  p0 x6 \4 v  }- h  制定目标名称,缺省的时候,gcc 编译出来的文件是a.out,很难听,如果你和我有同感 $ h; B5 H) d. y5 s7 X1 i
,改掉它,哈哈
- E. g! j3 `* S3 U' x3 u  例子用法
. m' K" J* ^# A& ?" H) {* w  gcc -o hello.exe hello.c (哦,windows用习惯了)
. f% s8 F7 T' b1 W9 r5 _* T5 m  gcc -o hello.asm -S hello.c : B& d/ T, r' U5 @! X- A% p+ q
-pipe , P8 J& L% K6 o+ \) R( r; N
  使用管道代替编译中临时文件,在使用非gnu汇编工具的时候,可能有些问题 6 A* B9 b* ]5 R" R% R
  gcc -pipe -o hello.exe hello.c 0 e) h+ d, X1 |, I, @
-ansi + C" [" }7 Q. T2 W3 S. D
  关闭gnu c中与ansi c不兼容的特性,激活ansi c的专有特性(包括禁止一些asm inl - r- S% \/ Z3 @+ e1 c. J+ \: O( d) @7 V
ine typeof关键字,以及UNIX,vax等预处理宏,
5 k; S+ o# ^, `-fno-asm + J. {( p0 e, X" x9 f3 p# ~
  此选项实现ansi选项的功能的一部分,它禁止将asm,inline和typeof用作关键字。
% S8 Y) ~; r- R. x( }# N     4 K. o( F/ U3 ?; t5 A
-fno-strict-prototype   `5 A& U2 U% i& }9 H& n) W
  只对g++起作用,使用这个选项,g++将对不带参数的函数,都认为是没有显式的对参数   b1 k5 E! d7 i5 v/ B
的个数和类型说明,而不是没有参数. 5 }! q9 B; Y( d: n" v
  而gcc无论是否使用这个参数,都将对没有带参数的函数,认为城没有显式说明的类型
, \% m  L3 I# W% R2 H
5 R8 t2 G& U/ ~# D   ( o+ v: Q. \- y% ^( `. B7 l
-fthis-is-varialble
& s& V0 \' |/ ^: H  就是向传统c++看齐,可以使用this当一般变量使用. : z  @, y) ~# `- L# ]
  
) b% T7 G8 G6 }+ o5 q/ ~-fcond-mismatch & V3 R% @/ N7 g4 w. A
  允许条件表达式的第二和第三参数类型不匹配,表达式的值将为void类型 + b9 E" Z% S0 [9 u
   * U( Y7 l7 W" j/ z, s5 c
-funsigned-char 4 K. M4 a& h: o! _5 c9 h: w
-fno-signed-char
" w2 m7 _; v) k4 f: {1 P: V-fsigned-char 1 i+ a! y! B' `, ^4 `$ b4 R
-fno-unsigned-char 9 a' R6 k  {# |% Z& \
  这四个参数是对char类型进行设置,决定将char类型设置成unsigned char(前两个参
# b3 a* ~2 U4 S( O( I% f, F9 U数)或者 signed char(后两个参数)
# f" }4 l, I$ V+ S/ I$ r+ _/ T   # z$ y7 H9 T/ m' p; b
-include file 7 s8 ]& P2 k" {, G7 m6 U4 k
  包含某个代码,简单来说,就是便以某个文件,需要另一个文件的时候,就可以用它设 5 _3 c8 I$ S, s( j3 X+ o  x% ?, G
定,功能就相当于在代码中使用#include<filename> 4 K; b# P: S# f, [" f
  例子用法:
9 R5 S7 h7 q) E/ O# w' E  gcc hello.c -include /root/pianopan.h ( ?/ ]3 }4 k& h8 k3 Q
   ( F9 U* q/ T, F5 O" e/ a' g( f  g
-imacros file
8 }/ W1 O; j; O  将file文件的宏,扩展到gcc/g++的输入文件,宏定义本身并不出现在输入文件中
3 m7 [- W5 U9 d) f1 z) B  
2 w3 N' s- [/ B$ W-Dmacro # p" c% H9 p  \$ Z( ]! d* c" f& G
  相当于C语言中的#define macro
; H" E4 A7 q3 w; x   * P8 u3 k) t! o& \+ |% [- L# |
-Dmacro=defn
. T  R  D; b3 m$ I  相当于C语言中的#define macro=defn
1 ~- A+ t$ B# T* W   9 o6 k3 l5 t; o( }
-Umacro
6 q( p. t* M5 w& G  相当于C语言中的#undef macro ) `! a7 L8 C# D! q+ ?* R
-undef
* J; o% ^7 y, V  取消对任何非标准宏的定义 ( i2 K8 B* L4 e; O6 }5 d
   2 E# }. l$ O( }9 |5 w% [
-Idir , ?+ y$ k$ y9 Y3 Q
  在你是用#include"file"的时候,gcc/g++会先在当前目录查找你所制定的头文件,如
7 O$ h. o* v# O+ J+ c' O果没有找到,他回到缺省的头文件目录找,如果使用-I制定了目录,他 0 m5 \' L$ [8 `" Z( W/ o( b# }( [
  回先在你所制定的目录查找,然后再按常规的顺序去找.
6 A0 P5 T. j: o7 H: g  对于#include<file>,gcc/g++会到-I制定的目录查找,查找不到,然后将到系统的缺 6 @! I1 b/ ]+ Q/ t
省的头文件目录查找 5 Z" x9 X7 E' }" L2 L
   6 L/ S$ J6 |: M0 s
-I- - }4 h8 K4 g" Q% q* ?( O
  就是取消前一个参数的功能,所以一般在-Idir之后使用 6 @* _7 I  J$ J4 X# D
  
# T0 e5 C& u8 n$ x1 j5 w; D" R-idirafter dir
9 V5 I7 U0 ^( n3 x, b. ?  在-I的目录里面查找失败,讲到这个目录里面查找. : `( s7 _: l5 ?$ A# V/ i* e! W
  
. Q8 A2 z8 j( p5 D  m2 z- V-iprefix prefix
6 I: v+ G" ]" S, l* a. b. G-iwithprefix dir & u# s3 T" k2 |" H% W$ N6 l6 _
  一般一起使用,当-I的目录查找失败,会到prefix+dir下查找
8 U6 K$ n, b6 R0 S* h& I7 X9 Q   ) S; v  O) \0 Z( O$ A9 }
-nostdinc
$ m1 {- C, X/ N; A  使编译器不再系统缺省的头文件目录里面找头文件,一般和-I联合使用,明确限定头 4 J* r7 o" C- n/ J) ^1 k' e
文件的位置
( w: C: \* C  K1 j/ ]& U9 y   # N2 r4 k9 N2 O2 u
-nostdin C++ " s, z2 t, a  e4 }9 ?7 L
  规定不在g++指定的标准路经中搜索,但仍在其他路径中搜索,.此选项在创libg++库
5 D* u! w) ?' n9 I% y6 X$ c使用 & D- _# H  X- H1 e
   . F5 ~6 |3 P4 [; ]/ h0 `8 e/ L
-C
% w: I6 ?5 w# E  在预处理的时候,不删除注释信息,一般和-E使用,有时候分析程序,用这个很方便的
6 S! l; B9 R8 u' P: A7 w  G8 @
- q1 P1 K* W8 k$ l  L3 v   4 W- {# {5 Y2 G* o: y1 Q4 ^
-M 8 M: I2 z1 ^" B
  生成文件关联的信息。包含目标文件所依赖的所有源代码你可以用gcc -M hello.c 2 M8 U  F# `6 B! W
来测试一下,很简单。 6 Q/ ^# R  l; v; Z; v8 x
  
# s- [2 L7 _" l% d7 g- g-MM
  S; v& j& d* ?7 D& Z6 S% T- A  和上面的那个一样,但是它将忽略由#include<file>造成的依赖关系。 5 ^& w9 q: {" Y. H7 f; c: t
  
0 B3 h5 M, F* U-MD / O$ ]. s/ _, b$ P) Q7 }
  和-M相同,但是输出将导入到.d的文件里面
7 ]: R8 `+ Y6 J5 o  h, A- ?8 Q  
' E* s  f2 }' w-MMD
9 w% p8 I4 ^" B  和-MM相同,但是输出将导入到.d的文件里面 $ R( n, m) _5 Q; ?  B
  
* A1 d" m5 b* y8 l/ n/ }- M( j-Wa,option # r: A  t) }3 D# \. I$ Y
  此选项传递option给汇编程序;如果option中间有逗号,就将option分成多个选项,然 ! C, x5 G8 u: }/ ], ?$ t
后传递给会汇编程序
- U  N* {0 @8 X  
# T7 }% A4 h5 Q4 Y; W" |, v-Wl.option
$ {, D$ E  A6 Z; D% X$ x) J0 Y# d6 q  此选项传递option给连接程序;如果option中间有逗号,就将option分成多个选项,然 % Z; ?7 N0 s9 D  y' f+ |
后传递给会连接程序.
9 S. p" ]$ ~2 |; S- b   ) F: `% ?$ W' F6 s4 c0 i
-llibrary
' M& d" W5 f; Y7 ~8 C8 s  制定编译的时候使用的库
/ ^& s( w; J# M7 ?  例子用法
9 n% X- P" G6 S- T& X; ]  gcc -lcurses hello.c
" [# ^- @$ g6 V0 C5 t  使用ncurses库编译程序
) a- q  n8 D, G4 {/ F$ k  
3 j9 V# Y% w+ c+ V" K-Ldir
. M# I% ]) t0 D# E  r. B$ C6 @  制定编译的时候,搜索库的路径。比如你自己的库,可以用它制定目录,不然
# u6 D0 k( Z3 B7 L% {- ]% |0 H  编译器将只在标准库的目录找。这个dir就是目录的名称。
. X+ f! q7 ^+ }7 v  
! l: E: I, A5 B-O0 $ o: g6 c9 |# E2 P4 M
-O1
+ [1 i/ A' U) M, q* A' |; |-O2
, ^* s3 ?. k5 H% _-O3
& ~0 A, Q' [3 y. a. X; l5 c  编译器的优化选项的4个级别,-O0表示没有优化,-O1为缺省值,-O3优化级别最高 
' Y. z4 @5 F7 Q% `$ X9 ~    
( W1 n( B5 d9 F8 m+ ?-g   n  a: A) h3 o# A1 {3 {
  只是编译器,在编译的时候,产生调试信息。 4 g; k) Y% ^/ V1 f! g0 `% M4 v
  
3 w6 ]; b) R. W6 D2 i- @5 n; p$ H-gstabs   f( y, y  Z- b# t  J$ e
  此选项以stabs格式声称调试信息,但是不包括gdb调试信息. : v/ x5 L8 w* l4 Q8 C
   ; {% V& A9 `( v' a  ^; K& s
-gstabs+ . f5 _- f: J7 _2 U3 s6 f
  此选项以stabs格式声称调试信息,并且包含仅供gdb使用的额外调试信息.
0 E- C6 o1 d: s0 h  D   # U: F) F* P' P4 Q2 @
-ggdb
% N3 R" p) D) {6 H% [  此选项将尽可能的生成gdb的可以使用的调试信息. 0 D9 O/ ~$ j1 _3 d0 V
-static
0 O4 n5 B$ P+ D6 v* X3 S  此选项将禁止使用动态库,所以,编译出来的东西,一般都很大,也不需要什么 # ]/ O/ m$ W: m, G! t' v1 A
动态连接库,就可以运行. $ m4 A( r9 i. A+ y: j- b
-share
: ?* a* y+ ]! M. G3 `  此选项将尽量使用动态库,所以生成文件比较小,但是需要系统由动态库. - h) _! c% W& ]/ ]
-traditional 2 e! `$ s2 p' `9 e- p- P
  试图让编译器支持传统的C语言特性
6 X! z: P7 R. Q4 }, b2 k+ G1 B[参考资料]
( `3 v. p8 f" a7 ]0 m-Linux/UNIX高级编程 8 K# i6 A5 Z- ]( U& k8 Q0 M2 W7 D
  中科红旗软件技术有限公司编著.清华大学出版社出版 8 a! W: ]! L, L$ h( `) t
-Gcc man page
5 X% z. i& r! @+ v3 B9 x   - S  R8 n* u3 q+ N4 G
[ChangeLog] / `4 \+ k% T; P
-2002-08-10 ! K' ~+ t- N3 [
  ver 0.1 发布最初的文档 - x9 n, v" ]& y- x
-2002-08-11 4 \0 R# ~8 g7 p0 v( @
  ver 0.11 修改文档格式 6 z) J: _5 W6 o0 m
-2002-08-12
) j/ O" q' l* S/ s$ R7 y  ver 0.12 加入了对静态库,动态库的参数 0 q9 m; O' e6 O- C. B# V4 T. O% d
-2002-08-16 ) F1 S/ {) I4 m+ P
  ver 0.16 增加了gcc编译的4个阶段的命令
% J% W* y5 |6 y1 I/ Q" E" m; V运行 gcc/egcs
' ]7 |+ A! B. L0 B**********运行 gcc/egcs***********************
, M. M- G8 M' k; Z9 d+ i  GCC 是 GNU 的 C 和 C++ 编译器。实际上,GCC 能够编译三种语言:C、C++ 和 O + I( P" T# g8 B6 J
bject C(C 语言的一种面向对象扩展)。利用 gcc 命令可同时编译并连接 C 和 C++
+ [2 ]" y2 Y3 |+ X5 u+ T- u源程序
7 x2 u3 y% R5 s; O( z1 M  如果你有两个或少数几个 C 源文件,也可以方便地利用 GCC 编译、连接并生成可 9 d* m& F$ t8 ]) L6 [) ]
执行文件。例如,假设你有两个源文件 main.c 和 factorial.c 两个源文件,现在要编 / A$ c8 f8 Q* }1 I9 T  ~8 o( o
译生成一个计算阶乘的程序。 + i) m" L- R! p6 C  f
代码: ( c. z, ~* n; K$ ?4 j9 f
-----------------------
3 g5 R: k# [$ I0 _: I" }清单 factorial.c
5 T- `6 K; s8 m( v1 o-----------------------
" B( D' _5 t  M% J2 ]7 ^- `* Mint factorial (int n)
% o# v/ {1 P# s; Q2 @3 O/ k{
3 W. D6 M9 n& F3 G5 o  if (n <= 1) 3 q4 U: q7 j; C: w  h) p% z
   return 1;
& }, W- i. N2 O; @4 X* C  else
' `1 Y* G. m- c4 L+ E   return factorial (n - 1) * n;
) d, t% k1 i' h" h( V1 ~}
/ [1 J8 `( z9 l4 ]  w-----------------------
/ a6 m4 }7 s! u* e6 Z4 a( m, N清单 main.c & O/ J1 Q/ i, z# A
-----------------------
5 Q! M" I  I7 x0 H#include <stdio.h> 5 U: y# @2 G: {& w  i6 A* D
#include <unistd.h>
. k6 u/ a9 D! b( ~+ b3 @, ~" |int factorial (int n);
1 i5 d, g, m$ Fint main (int argc, char **argv)
; O! z' x. l- n, x{ . x" F- u7 f" j
  int n;
' B6 r5 z0 ^+ d  \  if (argc < 2) 1 Q+ S& D: H/ O; n. k! r
  { ; l6 _9 J9 ^( ]) R5 r6 \  u
    printf ("Usage: %s n\n", argv [0]); / J- [  [$ y, @5 H8 i) U% |
    return -1;
) p% O$ [# J4 y4 W  }
8 \3 n2 R" |4 v  else % E$ B! |( w# y, u) z4 l
  {
# [- _4 u0 q, P/ G   n = atoi (argv[1]);
' X: |6 c! a* @; M- l/ ?& T   printf ("Factorial of %d is %d.\n", n, factorial (n)); % H% c$ n$ w' p* z+ {# L/ [6 w
   }
& ]( c/ S; K. ]  return 0;
9 H2 J2 c* }1 N# I- g5 i/ o6 P}
; [9 B* C4 v* U" m$ |1 G0 T-----------------------
" n5 w" e* e0 z" r3 ^# i" ?. q利用如下的命令可编译生成可执行文件,并执行程序:
" V! N& v# p0 ~/ z" ~5 a. L$ gcc -o factorial main.c factorial.c 8 K# [& n' k, h
$ ./factorial 5
, n& Y4 X: W9 @) k4 JFactorial of 5 is 120.
' F' `% P! C2 Y- ~  GCC 可同时用来编译 C 程序和 C++ 程序。一般来说,C 编译器通过源文件的后缀
3 v+ V6 A* n- {4 l, S名来判断是 C 程序还是 C++ 程序。在 Linux 中,C 源文件的后缀名为 .c,而 C++ 源 # e: W/ S/ L' E) e7 x8 [. U
文件的后缀名为 .C 或 .cpp。但是,gcc 命令只能编译 C++ 源文件,而不能自动和 C ! U. J, l) q, }- x2 ?
++ 程序使用的库连接。因此,通常使用 g++ 命令来完成 C++ 程序的编译和连接,该程 6 a4 I$ }" o: ^1 G8 z0 w
序会自动调用 gcc 实现编译。假设我们有一个如下的 C++ 源文件(hello.C):
6 \. A' w( j* D8 K) _4 \: [#include <iostream> ' L9 w& j; `. ~+ `  T
void main (void) ; a9 L4 }: ^% b. k5 Y1 O
{ / J6 e( e2 P, Q% N
  cout << "Hello, world!" << endl; 7 `5 H* x: D8 ]7 O0 `' `
}
1 `' k: h& L8 k! N6 `( x' k则可以如下调用 g++ 命令编译、连接并生成可执行文件: 5 F5 w( M( f$ f) Q9 o; |
$ g++ -o hello hello.C 1 R, G6 H- _& `0 m) y7 m' B
$ ./hello ' _; ]0 Y9 E, E5 X
Hello, world!
6 a! |2 @0 [' j# t5 D" Y**********************gcc/egcs 的主要选项*********
  b/ W4 W' c# w  b. @1 wgcc 命令的常用选项
  W7 G6 U, Y+ {8 k( p选项 解释
" s. p- N8 N9 l0 l) h-ansi 只支持 ANSI 标准的 C 语法。这一选项将禁止 GNU C 的某些特色,
) i6 |2 ^+ o- X3 @" z例如 asm 或 typeof 关键词。 1 B* m/ q7 X" g' z) Q
-c 只编译并生成目标文件。 % A, S0 U$ D& p8 l- y! L* W" X
-DMACRO 以字符串“1”定义 MACRO 宏。 0 l9 z' v3 g: }; b6 G+ l
-DMACRO=DEFN 以字符串“DEFN”定义 MACRO 宏。
4 `# q! g7 B+ M-E 只运行 C 预编译器。
9 E6 a, e, N& n  s9 Y1 S) r1 `-g 生成调试信息。GNU 调试器可利用该信息。
/ }3 K6 N$ {  X3 \" a-IDIRECTORY 指定额外的头文件搜索路径DIRECTORY。 0 {* b7 G$ F0 Z% m
-LDIRECTORY 指定额外的函数库搜索路径DIRECTORY。 2 b) ?; ^% X3 ]& _9 }% I2 C' e
-lLIBRARY 连接时搜索指定的函数库LIBRARY。 2 c0 j+ M5 U4 o7 V) I+ A' `! U
-m486 针对 486 进行代码优化。
; ?" S, K3 W0 f' L% h* n9 S-o FILE 生成指定的输出文件。用在生成可执行文件时。 : H) q; {0 o8 `
-O0 不进行优化处理。 " x+ i, T7 U1 I. I# i- A
-O 或 -O1 优化生成代码。 5 o1 a" x) \. B5 d' R  F. m$ J6 F3 ]5 l
-O2 进一步优化。
! U; N8 p* \( j5 c# Q5 {$ g8 ^-O3 比 -O2 更进一步优化,包括 inline 函数。 $ R6 q( x! [; |9 p2 E3 J) k
-shared 生成共享目标文件。通常用在建立共享库时。 ( V6 G. N% P3 B
-static 禁止使用共享连接。
4 s5 m/ d+ L, J' b5 s; O-UMACRO 取消对 MACRO 宏的定义。 5 ~: ~/ u9 |8 _  V' o7 z, m
-w 不生成任何警告信息。 " e$ j+ H5 S. j  a. `; C
-Wall 生成所有警告信息。
% ~' _/ T) n% X( q( U5 m

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-5-16 03:56 , Processed in 0.051586 second(s), 23 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表