📄 linux下的c-c++编程 - linuxsir_org.htm
字号:
width="100%" align=center border=0>
<TBODY>
<TR>
<TD class=alt2
style="PADDING-RIGHT: 6px; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; PADDING-TOP: 6px; BACKGROUND-COLOR: #dfebff"
vAlign=top width=160>
<DIV id=postmenu_276597><A class=bigusername
href="http://www.linuxsir.org/bbs/member.php?u=5119">无名小子</A> <!-- vB 中文修改开始: 性别 --><!-- vB 中文修改结束 -->
<SCRIPT
type=text/javascript> vbmenu_register("postmenu_276597", true); </SCRIPT>
</DIV>
<DIV class=smallfont><BR><A
href="http://www.linuxsir.org/bbs/member.php?u=5119"><IMG alt="无名小子 的头像"
src="Linux下的C-C++编程 - LinuxSir_Org.files/Image10.gif" border=0></A> </DIV>
<FIELDSET><LEGEND>资 料:</LEGEND>
<TABLE cellSpacing=5 cellPadding=4 border=0>
<TBODY>
<TR>
<TD>
<DIV class=smallfont>注册会员</DIV>
<DIV class=smallfont>
<DIV>注册日期: Nov 2002</DIV>
<DIV>帖子: 224
<DIV>精华: 6</DIV></DIV></DIV></TD></TR></TBODY></TABLE></FIELDSET> <IMG
height=1 alt="" src="Linux下的C-C++编程 - LinuxSir_Org.files/spacer.gif"
width=160> </TD>
<TD class=alt2
style="PADDING-RIGHT: 6px; PADDING-LEFT: 6px; PADDING-BOTTOM: 6px; PADDING-TOP: 6px; BACKGROUND-COLOR: #eef4ff"
vAlign=top>
<DIV class=normal style="FLOAT: right"> <A
href="http://www.linuxsir.org/bbs/showpost.php?p=276597&postcount=1"
target=new>第 1 帖</A> <!-- 管理小框 --></DIV>
<DIV class=normal><!-- status icon and date --><A
name=post276597>发帖时间:</A> 03-07-05, 00:04
<!-- / status icon and date --></DIV>
<TABLE style="TABLE-LAYOUT: fixed; WORD-WRAP: break-word" height="100%"
cellSpacing=0 cellPadding=3 width="100%" border=0>
<TBODY>
<TR>
<TD class=alt2 style="BACKGROUND-COLOR: #eef4ff" vAlign=top><BR><!-- message, attachments, sig --><!-- icon and title -->
<DIV class=smallfont><STRONG>Linux下的C++编程</STRONG> </DIV>
<HR style="COLOR: #7e92a8" SIZE=1>
<!-- / icon and title --><BR><!-- message -->
<DIV>Linux下的C++编程<BR><BR>ELF和a.out<BR><BR> 在Linux下,有两种可执行文件:ELF和a.out。有可能你的Linux只支持一种,有可能两种都支持。运行一下命令file,如果命令输出包含ELF,则支持ELF,如果包含Linux/i386,则支持a.out。<BR><BR>GCC版本<BR><BR> 使用下面命令,可以知道它的版本:<BR><BR>gcc
-v<BR><BR>GCC安装后目录结构<BR><BR> /usr/lib/gcc-lib/target/version/
(及子目录)
编译器就在这个目录下。<BR><BR> /usr/bin/gcc可以从命令行执行的二进制程序在这个目录下。<BR><BR> /usr/target/(bin|lib|include)/
库和头文件在这个目录下。<BR><BR> /lib/,/usr/lib和其他目录,系统的库在这些目录下。<BR><BR>符号定义<BR><BR> 使用-V开关,就能看到GCC定义的符号。参见下列实例:<BR><BR> $
echo 'main(){printf("hello world");}' | gcc -E -v -<BR><BR>
Reading specs from
/usr/lib/gcc-lib/i486-box-linux/2.7.2/specs<BR><BR> gcc version
2.7.2<BR><BR> /usr/lib/gcc-lib/i486-box-linux/2.7.2/cpp -lang-c -v
-undef<BR><BR> -D__GNUC__=2 -D__GNUC_MINOR__=7 -D__ELF__ -Dunix
-Di386 -Dlinux<BR><BR> -D__ELF__ -D__unix__ -D__i386__ -D__linux__
-D__unix -D__i386<BR><BR> -D__linux -Asystem(unix) -Asystem(posix)
-Acpu(i386)<BR><BR> -Amachine(i386) -D__i486__
-<BR><BR>GCC编译器使用简介<BR><BR> 通常后跟一些选项和文件名来使用 GCC 编译器。gcc
命令的基本用法如下:<BR><BR> gcc [options]
[filenames]<BR><BR> 选项指定编译器怎样进行编译。<BR><BR>GCC选项<BR><BR> GCC
有100个编译选项。这些选项中的许多可能永远都不会用到,但一些主要的选项会经常遇到。很多的
GCC<BR><BR>选项包括一个以上的字符,因此必须为每个选项指定各自的连字符。例如,
下面的两个命令是不同的:<BR><BR> gcc -p -g test.c<BR><BR> gcc -pg
test.c<BR><BR> 第一条命令告诉 GCC 编译 test.c 时为 prof
命令建立剖析(profile)信息并且把调试信息加入到可执行的文件里。 第二条命令只告诉 GCC<BR><BR>为 gprof
命令建立剖析信息。<BR><BR> 没有选项时,GCC 会生成一个名为 a.out 的可执行文件。<BR><BR> 用 -o
编译选项来为将产生的可执行文件用指定的文件名来命名。例如, 将一个叫 count.c 的 C 程序编译为名叫 count
的可执行文件,<BR><BR>要这样输入命令:<BR><BR> gcc -o count count.c<BR><BR> -c
选项告诉 GCC 仅把源代码编译为目标代码。缺省时 GCC 建立的目标代码文件有一个 .o 的扩展名。<BR><BR> -S
编译选项告诉 GCC 在为 C 代码产生了汇编语言文件后停止编译。 GCC 产生的汇编语言文件的缺省扩展名是 .s
。<BR><BR> -E 选项指示编译器仅对输入文件进行预处理。当这个选项被使用时,
预处理器的输出被送到标准输出而不是储存在文件里.<BR><BR> 用 GCC 编译 C 代码时,
它会试着用最少的时间完成编译并且使编译后的代码易于调试。<BR><BR>易于调试意味着编译后的代码没有经过优化。必要时,需要让编译器对代码进行优化。<BR><BR> -O
选项告诉 GCC 对源代码进行基本优化。这些优化在大多数情况下都会使程序执行的更快。 -O2 选项告诉 GCC
产生尽可能小和尽可能快的代码。 -O2<BR><BR>选项将使编译的速度比使用 -O 时慢,
但通常产生的代码执行速度会更快。<BR><BR> GCC 支持数种调试和剖析选项,常用到的是 -g 和 -pg
。<BR><BR> -g 选项告诉 GCC 产生能被 GNU 调试器使用的调试信息以便调试你的程序。GCC 提供了一个很多其他 C
编译器里没有的特性, 在 GCC 里你能使<BR><BR>-g 和 -O (产生优化代码)联用。<BR><BR> -pg 选项告诉
GCC 在编译好的程序里加入额外的代码。运行程序时, 产生 gprof 用的剖析信息以显示你的程序的耗时情况。<BR><BR>用 gdb
调试 GCC 程序<BR><BR> Linux 包含了一个叫 gdb 的 GNU
调试程序。在程序运行时能观察程序的内部结构和内存的使用情况。 以下是 gdb
所提供的一些功能:<BR><BR> 监视程序中变量的值<BR><BR> 设置断点,使程序在指定的代码行上停止执行。<BR><BR> 一行行的执行代码<BR><BR> 为了用GDB调试程序,在编译是必须指定调试选项。在命令行上键入
gdb 并按回车键就可以运行 gdb 了。如果一切正常的话, gdb<BR><BR>将被启动并在屏幕上显示:<BR><BR> GDB
is free software and you are welcome to distribute copies of it
under<BR><BR>certain conditions; type "show copying" to see the
conditions.<BR><BR> There is absolutely no warranty for GDB; type
"show warranty" for details.<BR><BR> GDB 4.14
(i486-slakware-linux), Copyright 1995 Free Software Foundation,
Inc.<BR><BR> (gdb)<BR><BR> 可以在启动GDB时,加入许多选项。也可以在这个命令后面直接指定要调试的程序。<BR><BR>gdb
< fname><BR><BR>gdb 基本命令<BR><BR>gdb
支持很多的命令,这些命令从简单的文件装入到允许检查所调用的堆栈内容的复杂命令。下表列出了你在用 gdb
调试时会用到的一些命令。<BR><BR>命令 描 述<BR><BR>file 装入想要调试的可执行文件<BR><BR>kill
终止正在调试的程序<BR><BR>list 列出产生执行文件的源代码的一部分<BR><BR>next
执行一行源代码但不进入函数内部<BR><BR>step 执行一行源代码而且进入函数内部<BR><BR>run
执行当前被调试的程序<BR><BR>quit 终止 gdb<BR><BR>watch
使你能监视一个变量的值而不管它何时被改变<BR><BR>break 在代码里设置断点,
这将使程序执行到这里时被挂起<BR><BR>make 使你能不退出 gdb 就可以重新产生可执行文件<BR><BR>shell
使你能不离开 gdb 就执行 UNIX shell 命令<BR><BR>gdb
应用举例<BR><BR> 下面列出了将被调试的程序,这个程序被称为 greeting ,显示一个简单的问候,
再用反序将它列出。<BR><BR>#include < stdio.h><BR><BR>main
()<BR><BR>{<BR><BR>char my_string[] = "hello there";<BR><BR>my_print
(my_string);<BR><BR>my_print2 (my_string);<BR><BR>}<BR><BR>void
my_print (char *string)<BR><BR>{<BR><BR>printf ("The string is %s",
string);<BR><BR>}<BR><BR>void my_print2 (char
*string)<BR><BR>{<BR><BR>char *string2;<BR><BR>int size,
i;<BR><BR>size = strlen (string);<BR><BR>string2 = (char *) malloc
(size + 1);<BR><BR>for (i = 0; i < size; i++)<BR><BR>string2[size
- i] = string[i];<BR><BR>string2[size+1] = `0';<BR><BR>printf ("The
string printed backward is %s",
string2);<BR><BR>}<BR><BR> 用下面的命令编译这个程序:<BR><BR> gcc -o -g test
test.c<BR><BR> 运行编译好的程序,显示如下:<BR><BR> The string is hello
there<BR><BR> The string printed backward is<BR><BR> 输出的第一行是正确的,
但第二行打印出的东西并不是我们所期望的。我们所设想的输出应该是:<BR><BR> The string printed
backward is ereht olleh<BR><BR> 由于某些原因, my_print2 函数没有正常工作。用 gdb
看看问题究竟出在哪儿, 先键入如下命令:<BR><BR> gdb
greeting<BR><BR> 如果在输入命令时忘了把要调试的程序作为参数传给 gdb ,可以在 gdb 提示符下用 file
命令来载入它:<BR><BR> (gdb) file greeting<BR><BR> 这个命令载入 greeting
可执行文件,就象在 gdb 命令行里指定启动gdb装入它一样。<BR><BR> 这时就能用 gdb 的 run 命令来运行
greeting 了。 当它在 gdb 里被运行后结果大约会象这样:<BR><BR> (gdb)
run<BR><BR> Starting program: /root/greeting<BR><BR> The string is
hello there<BR><BR> The string printed backward is<BR><BR> Program
exited with code 041<BR><BR> <BR><BR> 这个输出和在 gdb 外面运行的结果一样。问题是,
为什么反序打印没有工作? 为了找出症结所在, 我们可以在 my_print2 函数的 for<BR><BR>语句后设一个断点,
具体的做法是在 gdb 提示符下键入 list 命令三次, 列出源代码:<BR><BR> (gdb)
list<BR><BR> (gdb) list<BR><BR> (gdb) list<BR><BR> 第一次键入 list
命令的输出如下: 1 #include < stdio.h><BR><BR> 2<BR><BR> 3 main
()<BR><BR> 4 {<BR><BR> 5 char my_string[] = "hello
there";<BR><BR> 6<BR><BR> 7 my_print (my_string);<BR><BR> 8
my_print2 (my_string);<BR><BR> 9 }<BR><BR> 10<BR><BR> 如果按下回车, gdb
将再执行一次 list 命令, 给出下列输出:<BR><BR> 11 my_print (char
*string)<BR><BR> 12 {<BR><BR> 13 printf ("The string is %s",
string);<BR><BR> 14 }<BR><BR> 15<BR><BR> 16 my_print2 (char
*string)<BR><BR> 17 {<BR><BR> 18 char *string2;<BR><BR> 19 int
size, i;<BR><BR> 20<BR><BR> 再按一次回车将列出 greeting
程序的剩余部分:<BR><BR> 21 size = strlen (string);<BR><BR> 22 string2 =
(char *) malloc (size + 1);<BR><BR> 23 for (i = 0; i < size;
i++)<BR><BR> 24 string2[size - i] = string[i];<BR><BR> 25
string2[size+1] = `0';<BR><BR> 26 printf ("The string printed
backward is %s", string2);<BR><BR> 27 }<BR><BR> 根据列出的源程序,
你能看到要设断点的地方在第24行, 在 gdb 命令行提示符下键入如下命令设置断点:<BR><BR> (gdb) break
24<BR><BR> 该命令的执行结果如下:<BR><BR> Breakpoint 1 at 0x139: file
greeting.c, line 24<BR><BR> (gdb)<BR><BR> 现在再键入 run 命令,
将产生如下的输出:<BR><BR> Starting program: /root/greeting<BR><BR> The
string is hello there<BR><BR> Breakpoint 1, my_print2 (string =
0xbfffdc4 "hello there") at greeting.c :24<BR><BR>24
string2[size-i]=string[i]<BR><BR> 你能通过设置一个观察 string2[size - i]
变量的值的观察点来看出错误是怎样产生的, 做法是键入:<BR><BR> (gdb) watch string2[size -
i]<BR><BR> 执行结果如下:<BR><BR> Watchpoint 2: string2[size -
i]<BR><BR> 现在可以用 next 命令来一步步的执行 for 循环了:<BR><BR> (gdb)
next<BR><BR> 经过第一次循环后, gdb 告诉我们 string2[size - i] 的值是
`h`。这是执行next命令后的结果:<BR><BR> Watchpoint 2, string2[size -
i]<BR><BR> Old value = 0 `000'<BR><BR> New value = 104
`h'<BR><BR> my_print2(string = 0xbfffdc4 "hello there") at
greeting.c:23<BR><BR> 23 for (i=0; i< size;
i++)<BR><BR> 这个值正是期望的。后来的数次循环的结果都是正确的。当 i=10 时, 表达式 string2[size -
i] 的值等于 `e`, size - i<BR><BR>的值等于 1,
最后一个字符已经拷到新串里了。<BR><BR> 如果再把循环执行下去,会看到已经没有值分配给 string2[0] 了,
而它是新串的第一个字符, 因为 malloc<BR><BR>函数在分配内存时把它们初始化为空(null)字符。所以 string2
的第一个字符是空字符。于是就发现了为什么在打印 string2 时没有任何输出了.<BR><BR> 找出了问题出在哪里后,
修正这个错误是很容易的。把代码里写入 string2 的第一个字符的的偏移量改为 size - 1 而不是
size。这是因为<BR><BR>string2 的大小为 12, 但起始偏移量是 0, 串内的字符从偏移量 0 到 偏移量 10,
偏移量 11 为空字符保留。<BR><BR> 为了使代码正常工作有很多种修改办法. 。一种是另设一个比串的实际大小小 1
的变量,下面是这种办法的程序。<BR><BR>#include < stdio.h><BR><BR>main
()<BR><BR>{<BR><BR>char my_string[] = "hello there";<BR><BR>my_print
(my_string);<BR><BR>my_print2 (my_string);<BR><BR>}<BR><BR>my_print
(char *string)<BR><BR>{<BR><BR>printf ("The string is %s",
string);<BR><BR>}<BR><BR>my_print2 (char
*string)<BR><BR>{<BR><BR>char *string2;<BR><BR>int size, size2,
i;<BR><BR>size = strlen (string);<BR><BR>size2 = size
-1;<BR><BR>string2 = (char *) malloc (size + 1);<BR><BR>for (i = 0;
i < size; i++)<BR><BR>string2[size2 - i] =
string[i];<BR><BR>string2[size] = `0';<BR><BR>printf ("The string
printed backward is %s", string2);<BR><BR>}<BR><BR>二 Linux
SHELL编程<BR><BR> SHELL编程是指写一个包含一系列UNIX命令的程序,这个程序可以在命令行运行。用下面的命令何以执行一个SHELL程序:<BR><BR>方式一<BR><BR>$
sh cmd.file<BR><BR>方式二<BR><BR>$ . cmd.file;<BR><BR>方式三<BR><BR>$
chmod u+x cmd.file<BR><BR>$
cmd.file<BR><BR>怎样创建和运行一个SHELL脚本<BR><BR> 在一个编辑器里,写入一系列UNIX命令,举个例子:<BR><BR> echo
This is a shell program<BR><BR> echo Today I am going
to<BR><BR> echo $1 $2 $3 $4 $5 $6 $7 $8
$9<BR><BR> 保存这个文件,命名为ex1。然后用下列命令“chmod
700<BR><BR>ex1”,将该文件变为可执行文件。做完上述个步骤之后,就好了。如果要看运行这个文件会出现什么结果,可以在命令行状态下键入:ex1
coffee bar
in<BR><BR>hangzhou。<BR><BR> 上述程序中最后一行就是将ex1命令中的单词读入内存,同样将第二个等等。$1代表第一个单词,$2代表第二个。<BR><BR> 可见,SHELL程序的目的是能批量处理命令,从而完成一些比较复杂的工作。<BR><BR> 不同的SHELL有不同的启动文件,比如:<BR><BR> bash:
.profile<BR><BR> sh: .profile<BR><BR> csh: .cshrc<BR><BR> tcsh:
.cshrc<BR><BR> zsh: $ZDOTDIR/.zprofile and/or
$ZDOTDIR/.zshrc<BR><BR> 所有的这些启动文件都要读入.login和.logout文件。<BR><BR>SHELL程序设计<BR><BR>注释<BR><BR>操作符“#"引入注释。<BR><BR>if
操作符<BR><BR>语法<BR><BR>if [ 条件表达式
]<BR><BR>then<BR><BR>命令序列<BR><BR>fi<BR><BR>或<BR><BR>if [ 条件表达式
]<BR><BR>then<BR><BR>命令序列<BR><BR>else<BR><BR>命令序列<BR><BR>fi<BR><BR>数值操作符<BR><BR>=
等于<BR><BR>-n 不等于<BR><BR>-gt 大于<BR><BR>-lt 小于<BR><BR>-le
小于等于<BR><BR>exit 命令<BR><BR>用于结束SHELL脚本。可以带一个返回值。<BR><BR>expr
命令<BR><BR>以数值和算术运算符作为参数,计算结果,将其返回标准输出。<BR><BR>$ expr 4 +
5<BR><BR>9<BR><BR>$<BR><BR>合法算术运算符有+、-、*、/和%。在*和/之前必须冠以反斜线,已防被SHELL先行解释。<BR><BR>for
操作符<BR><BR>循环语句。<BR><BR>语法:<BR><BR>for $环境变量 in
字符串表<BR><BR>do<BR><BR>语句序列<BR><BR>done<BR><BR>while
操作符<BR><BR>循环语句。<BR><BR>语法:<BR><BR>while [ 条件表达式
]<BR><BR>do<BR><BR>语句序列<BR><BR>done<BR><BR>case
操作符<BR><BR>条件控制语句。<BR><BR>语法:<BR><BR>case $环境变量
in<BR><BR>常量1)<BR><BR>语句序列1<BR><BR>;;<BR><BR>常量2)<BR><BR>语句序列2<BR><BR>;;<BR><BR>...
...<BR><BR>常量n)<BR><BR>语句系列n<BR><BR>;;<BR><BR>esac<BR><BR>命令行变元<BR><BR>$#
传入脚本的命令行变元数;<BR><BR>$* 所有命令行变元值;<BR><BR>位置变元<BR><BR>$0
命令本身<BR><BR>$1 第一个命令行变元;<BR><BR>$2
第二个命令行变元<BR><BR>SHELL函数<BR><BR>shell函数由以下形式定义<BR><BR>funcname ()
{<BR><BR>命令序列<BR><BR>}<BR><BR>调用时<BR><BR>funcname arg1 arg2</DIV><!-- / message --><!-- message, attachments, sig --></TD></TR>
<TR>
<TD vAlign=bottom></TD></TR></TBODY></TABLE></TD></TR>
<TR height=20>
<TD class=alt2></TD>
<TD class=alt2 background-color:#EEF4FF>
<DIV style="FLOAT: left; WIDTH: auto"><IMG class=inlineimg alt="无名小子 当前离线"
src="Linux下的C-C++编程 - LinuxSir_Org.files/user_offline.gif" border=0> <A
href="http://www.linuxsir.org/bbs/private.php?do=newpm&u="><IMG
title=发送短消息 src="Linux下的C-C++编程 - LinuxSir_Org.files/pmm.gif"
border=0></A> </DIV>
<DIV
align=right><!-- controls --><!-- vB 中文修改开始: 银行 --><!-- vB 中文修改结束 --><A
href="http://www.linuxsir.org/bbs/newreply.php?do=newreply&p=276597"
rel=nofollow><IMG alt=回复时引用此帖
src="Linux下的C-C++编程 - LinuxSir_Org.files/quote.gif" border=0></A>
</DIV></TD></TR></TBODY></TABLE><!-- post 276597 popup menu -->
<DIV class=vbmenu_popup id=postmenu_276597_menu style="DISPLAY: none">
<TABLE cellSpacing=1 cellPadding=4 border=0>
<TBODY>
<TR>
<TD class=thead>无名小子</TD></TR>
<TR>
<TD class=vbmenu_option><A
href="http://www.linuxsir.org/bbs/member.php?u=5119">查看公开信息</A></TD></TR>
<TR>
<TD class=vbmenu_option><A
href="http://www.linuxsir.org/bbs/private.php?do=newpm&u=5119"
rel=nofollow>发悄悄话给 无名小子</A></TD></TR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -