基于操作系统的编程复习 张玉宏 yhily@126.com
第一章 1 Linux的特性 2. C语言的特点 3.Linux Shell的提示符及磁盘(U盘、光盘,硬盘等)的挂载
1.4.2 Linux Shell Shell有两种提示符:#和$。 图1-30所示的终端提示符是#。以“#”为提示符表明该终端是由root用户打开的,root用户具有系统最高权限,因此可以输入任何可用的命令
1.4.2 Linux Shell Shell有两种提示符:#和$。 一般用户打开的终端的提示符是“$” 比如halt命令只能由root使用,普通用户在“$”提示符下输入halt命令,系统认为是一个无效命令。 提示符的其他部分分别表示[登录用户名@主机名当前目录]。
1.4.2 Linux Shell Shell命令的基本格式是: 命令名 [选项] <参数1> <参数2>…… 命令名 [选项] <参数1> <参数2>…… 其中方括号中的选项对命令来说是可选的,一条命令可以有0个或多个参数。 选项是对命令的特别定义,也可以理解为选项告诉命令具体做什么。 选项通常以“-”开始,后接一个或多个字母,如ls-al,有的选项以“--”开头,后面一般跟着一个单词,比如--number。 很多“--”格式的选项可以用“-”加上第一个字母来替代,如--number可以用-n来替代。
掌握:Linux系统挂载U盘和硬盘光驱的问题 1、插入u盘到计算机,如果目前只插入了一个u盘而且你的硬盘不是scsi的硬盘接口的话,那它的硬件名称为:sda1。 2、在mnt目录下先建立一个usb的目录(如:[root@localhost root]# mkdir /mnt/usb)
Linux系统挂载U盘 4、卸载U盘:umount /mnt/usb 5、删除usb目录:rm -rf /mnt/usb 在实际中操作中,直接加挂一个windows的分区,中文的文件名和目录名会出现乱码,为了避免这种情况可以指定字符集,命令如下: mount -t vfat /dev/sdb1 /mnt/usb -o codepage=936,iocharset=cp936 注意:cp936是指简体中文,cp950是指繁体中文。
2.加挂NTFS文件系统 同样对于中文的文件名和目录名会出现乱码的问题可以指定字符集,不过和加挂vfat分区不同,实际中用以下命令是可行的: mount -t ntfs -o iocharset=cp936 /dev/hda2 /mnt/c -r mount -t ntfs -o iocharset=cp936,rw /dev/hda2 /mnt/c 注意:cp936是指简体中文,cp950是指繁体中文。 卸载删除同上!
三.Linux自动挂载硬盘 打开/etc找到里面的fstab文件进行编辑,如果你是以管理员身份登入的话,可以直接右键--打开方式--gedit,可以直接在后面追加行: /dev/hda6 /mnt/wine vfat codepage=936,iocharset=cp936,defaults,umask=000 /dev/hda5 /mnt/wind vfat codepage=936,iocharset=cp93600
四.Linux挂载光驱: 命令:mount -t iso9660 /dev/hdc /mnt/cdrom 卸载删除同上!
Linux系统中的虚拟终端 Linux的字符界面称为虚拟终端或虚拟控制台,可为用户提供多个互不干扰、独立工作的工作界面。 而第7个则是图形化用户界面,虚拟终端之间可以相互切换
Linux系统中的虚拟终端 在字符界面时Alt+F1-Alt+F7可从字符界面的虚拟终端切换到其他虚拟终端。 如果已经启动了X-Window,则可以使用Ctrl+Alt+F1(F2、F3、F4、F5、F6均可以)进入字符状态,按Ctrl+Alt+F7回到X-Window
虚拟机下Linux的虚拟终端切换 vmware安装的linux9,一按下ctrl+alt,就回到windows平台/Virtual pc安装的linux9,一按下alt,就回到windows平台 在xwindow下输入init 3,进入字符界面,在字符界面输入init 5,回到xwindow init 0关机 init 3字符界面 init 5图形界面 init 6重启 在字符界面 startx命令也可以回到x-window!
Linux常用目录的含义 /bin 存放着使用者最经常使用的命令,例如ls等。 /boot 存放的是启动Linux时使用的一些核心文件。 /dev dev是device(设备)的缩写。这个目录下是所有Linux的外部设备,在Linux中设备和文件是用同种方法访问的。例如:/dev/hda代表第一个物理IDE硬盘。 /etc 这个目录用来存放系统管理所需要的配置文件和子目录。
/home 用户的主目录,比如说有个用户叫wang,那他的 /lib 这个目录里存放着系统最基本的动态链接共享库, 其作用类似于Windows里的.dll文件。几乎所有的应 用程序都须要用到这些共享库。 /mnt 这个目录是空的,系统提供这个目录是让用户临时 挂载别的文件系统。
常用的SHELL命令(重要:牢记) 仅仅列几个… 注销 在字符界面下,注销可使用的方法有两种:输入 “exit”或者使用Ctrl+D快捷键。 重启 当需要重新启动计算机时,输入“reboot”或者“shutdown –r now”命令即可。
常用的SHELL命令… ls 命令 格式:ls [选项] [文件|目录] 功能:用来列出目录的内容。 -a (表示要列出所有的文件) -d (显示目录信息) -t (按照时间顺序显示) -R(递归地显示目录中的文件和子目录信息)
mkdir 命令 功能: 建立目录 。 参数: -p (建立所有不存在父目录的目录) 例1: $ mkdir -p xnd/wll 功能: 建立目录 。 参数: -p (建立所有不存在父目录的目录) 例1: $ mkdir -p xnd/wll 在当前目录下建立xnd和xnd下的wll的目录,也就是连续建立两个目录(xnd和xnd/wll)。 (不带参数只能建一级目录)
rmdir 命令 功能: 删除一个空的目录。 参数: -p (递归删除目录) 例1: $ rmdir -p xnd/wll 功能: 删除一个空的目录。 参数: -p (递归删除目录) 例1: $ rmdir -p xnd/wll 将删除xnd下的wll的目录,若xnd目录为空也删除它。 注:不带参数是只是删除wll
cp 命令 功能: 复制文件或目录 。 参数: -f (强行覆盖) -i (覆盖时询问) -r (拷贝目录) 功能: 复制文件或目录 。 参数: -f (强行覆盖) -i (覆盖时询问) -r (拷贝目录) 例1: $ cp -r /usr/xu/ /usr/liu/ 将/usr/xu目录中的所有文件及其子目录拷贝到目录/usr/liu中。
第二章 1.C语言关键的语法,熟练掌握面试题所涉及到的语法点。 2.掌握如果利用GCC编译一个C语言文件 3.掌握常用的vim命令 4.掌握Makefile的编写 4.掌握GDB调试程序的逻辑错误 (复习原则:看懂课件所所涉及到的例题)
5、请找出下面代码中的所有点错误,并给出修改方案 说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba” 1、#include"string.h" 2、main() 3、{ 4、 char* src="hello,world"; 5、 char* dest=NULL; 6、 int len=strlen(src); 7、 dest=(char*)malloc(len); 8、 char* d=dest; 9、 char* s=src[len]; 10、 while(len--!=0) 11、 d++=s--; 12、 printf("%s",dest); 13、 return 0; 14、}
方法1: int main() { char* src = "hello,world"; int len = strlen(src); char* dest = (char*)malloc(len+1);//要为\0分配一个空间 char* d = dest; char* s = &src[len-1];//指向最后一个字符 while( len-- != 0 ) *d++=*s--; *d = 0;//尾部要加\0 printf("%s\n",dest); free(dest);// 使用完,应当释放空间,以免造成内存汇泄露 return 0; }
vim命令学习-1(仅列举部分) 1.欲进入vim编辑器(从命令行提示符),请输入∶vim 文件名 <回车> 2.光标在屏幕文本中的移动既可以用箭头键,也可以使用 hjkl 字母键。 h (左移) j (下行) k (上行) l (右移) 3. 欲退出vim编辑器,请输入以下命令放弃所有修改∶ <ESC> :q! <回车> 或者输入以下命令保存所有修改∶ <ESC> :wq <回车>
vim命令学习-2 4. 在正常模式下删除光标所在位置的字符,请按∶ x 5. 在正常模式下要在光标所在位置开始插入文本,请按∶ i 输入必要文本 <ESC> 特别提示∶按下 <ESC> 键会带您回到正常模式或者取消一个不期望或者部分完成的命令
vim命令学习-3 1. 欲从当前光标删除至单字/单词末尾,请输入∶dw 2. 欲从当前光标删除至当前行末尾,请输入∶d$ 3. 欲删除整行,请输入∶dd
vim命令学习-4 4. 在正常模式下一个命令的格式是∶ [number] command object 或者 command [number] object 其意是∶ number - 代表的是命令执行的次数 command - 代表要做的事情,比如 d 代表删除.object - 代表要操作的对象,比如 w 代表单字/单词,$ 代表到行末等等。$ (to the end of line), etc.
vim命令学习-4 dnw:删除n个单词 dne:也可,只是删除到单词尾 dnl:向右删除n个字母 dnh:向左删除n个字母 dnj:向下删除n行 dnk:向上删除n行 d$:删除当前光标到改行的行尾的字母 dd:删除一行
vim命令学习-4 5. 欲撤消以前的操作,请输入∶u (小写的u) 欲撤消在一行中所做的改动,请输入∶U (大写的U) 欲撤消以前的撤消命令,恢复以前的操作结果,请输入∶CTRL-R
1.gcc编译器选项 -o选项,表示我们要求输出的可执行文件名. -c选项表示我们只要求编译器输出目标代码,而不必要输出可执行文件.
1.gcc编译器选项 知道了这三个选项,我们就可以编译我们自己所写的简单的源程序了
3.Makefile 的编写 假设我们有下面这样的一个程序,源代码如下: /* main.c */ #include "mytool1.h" int main(int argc,char **argv) { mytool1_print("hello"); mytool2_print("hello"); }
3.Makefile 的编写 /* mytool1.c */ #include "mytool1.h" void mytool1_print(char *print_str) { printf("This is mytool1 print %s\n",print_str); } /* mytool1.h */ #ifndef _MYTOOL_1_H #define _MYTOOL_1_H void mytool1_print(char *print_str); #endif /* mytool2.c */ #include "mytool2.h" void mytool2_print(char *print_str) { printf("This is mytool2 print %s\n",print_str); } /* mytool2.h */ #ifndef _MYTOOL_2_H #define _MYTOOL_2_H void mytool2_print(char *print_str); #endif
3.Makefile 的编写 当然由于这个程序是很短的我们可以这样来编译 gcc -c main.c gcc -c mytool1.c gcc -c mytool2.c gcc -o main main.o mytool1.o mytool2.o 这样的话我们也可以产生main程序,而且也不时很麻烦. 但是如果我们考虑一下 如果有一天我们修改了其中的一个文件(比如说mytool1.c),那么我们还要重新输入上面的命令,非常的麻烦!
3.Makefile 的编写 下面我们学习Makefile是如何编写的. 在Makefile中#开始的行都是注释行. Makefile中最重要的是描述文件的依赖关系的说 明.一般的格式是: target: components TAB rule //第一行表示的是依赖关系. //第二行是规则.
# 注释行,这是原来程序的Makefile文件 main:main. o mytool1. o mytool2. o # 注释行,这是原来程序的Makefile文件 main:main.o mytool1.o mytool2.o gcc -o main main.o mytool1.o mytool2.o main.o:main.c mytool1.h mytool2.h gcc -c main.c mytool1.o:mytool1.c mytool1.h gcc -c mytool1.c mytool2.o:mytool2.c mytool2.h gcc -c mytool2.c $@:目标文件 $^:所有的依赖文件 $<:第一个依赖文件 #这是简化后的Makefile main: main.o mytool1.o mytool2.o gcc -o $@ $^ main.o: main.c mytool1.h mytool2.h gcc -c $< mytool1.o: mytool1.c mytool1.h mytool2.o: mytool2.c mytool2.h
4.程序的调试 我们编写的程序不太可能一次性就会成功的,在我们的程序当中,会出现许许多多我们想不到的错误,这个时候我们就要对我们的程序进行调试了. 最常用的调试软件是gdb. GDB(GNU symbolic debugger)简单地说就是一个调试工具。它是一个受通用公共许可证即GPL保护的自由软件。 记得要在编译的时候加入 -g选项.
使用 GDB ———— 一般来说 GDB 主要调试的是 C/C++ 的程序。要调试 C/C++ 的程序,首先在编译时,我们必须要把调试信息加到可执行文件中。 1.使用编译器( cc/gcc/g++ )的 -g 参数可以做到这一点。如: > cc -g hello.c -o hello > g++ -g hello.cpp -o hello 如果没有 -g ,将看不见程序的函数名、变量名,所代替的全是运行时的内存地址。 当你用 -g 把调试信息加入之后,并成功编译目标代码以后,让我们来看看如何用 gdb 来调试程序。
gdb 基本命令
一个调试示例(掌握!) 14 main() 15 { 16 int i; 17 long result = 0; 18 for(i=1; i<=100; i++) 19 { 20 result += i; 21 } 22 23 printf("result[1-100] = %d \n", result ); 24 printf("result[1-250] = %d \n", func(250) ); 25 } //源程序:tst.c 1 #include <stdio.h> 2 3 int func(int n) 4 { 5 int sum=0,i; 6 for(i=0; i<n; i++) 7 { 8 sum+=i; 9 } 10 return sum; 11 } 12 13
一个调试示例(掌握!) #include <stdio.h> main () { { char my_string[] = "hello there"; my_print (my_string); my_print2 (my_string); } void my_print (char *string) printf ("The string is %s\n", string); void my_print2 (char *string) { char *string2; int size, i; size = strlen (string); string2 = (char *) malloc (size + 1); for (i = 0; i < size; i++) string2[size - i] = string[i]; string2[size+1] = `\0'; printf ("The string backward is %s\n", string2); } 一个调试示例(掌握!)
第三章 进程控制 1.掌握【字符】指针和多维数组的使用(重要!),在此基础上掌握带参main函数的使用 2.掌握进程的几个状态的变迁及原因 3.掌握getpid(),getppid()函数,fork函数,exec函数在C语言的使用 复习原则:看懂例题,编程实践一下
main函数的几个参数 int main ( int argc, char *argv[], char *envp[] ); 表示你在命令行下输入命令的时候,一共有多少个参数。 比方说你的程序编译后,可执行文件是test [root@hostlocal yhily] test 这个时候,argc的值是1 但是如果执行 [root@hostlocal yhily] test myarg1 myarg2 argc的值是3。也就是 命令名 加上两个参数,一共三个参数
例如 [root@hostlocal yhily] cp /home/yhily/123.c /home/456.c argc=3 arg表示 argument: The independent variable of a function.函数的自变数 c表示count
解释 2. char *argv[] 用来取得你所输入的参数 [root@hostlocal yhily] test 这个时候,argc的值是1 这个时候,argc的值是1,argv[0]指向的值是 "test
解释 [root@hostlocal yhily] test myarg1 myarg2 这个时候,argc的值是3,argv[0]指向的值是"test",argv指向的[1]的值是"myarg1",argv [2]指向的的值是"myarg2" argv[0] argv[1] argv[2] argv t e s \0 m y a r g 1 2
思考一下:输入结果会是怎么样的?
exec( ) 为了调用系统程序,我们可以使用系 统调用exec族调用.exec族调用有着5个函数.
范例
第四章 1.什么是文件系统,掌握常见的文件系统。 2.Linux对文件的操作的两种方式 3.掌握这两种方式在Linux C中的使用方法 复习原则:看懂例题
什么是文件系统 操作系统中与管理文件有关的软件和数据称为文件系统。 它负责为用户建立文件,撤消、读写、修改和复制文件,还负责完成对文件的按名存取和进行存取控制。
两类函数 在Linux平台下对文件编程可以使用两类函数: (1)Linux操作系统文件API; (2)C语言I/O库函数。 本章将对这两种方法进行实例讲解。
第一种方式 如果使用了O_CREATE标志,则使用的函数是 int open(const char *pathname,int flags,mode_t mode); 这个时候我们还要指定mode标志,用来表示文件的访问权限。 mode可以是以下情况的组合:
Mode的标志位 除了可以通过上述宏进行“或”逻辑产生标志以外, 也可以自己用数字来表示: Linux总共用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。 1 2 3 4 5 用户ID 组ID 用户权限 组的权限 他人权限
Mode的标志位 除了可以通过上述宏进行“或”逻辑产生标志以外, 也可以自己用数字来表示: Linux总共用5个数字来表示文件的各种权限:第一位表示设置用户ID;第二位表示设置组ID;第三位表示用户自己的权限位;第四位表示组的权限;最后一位表示其他人的权限。 1 2 3 4 5 用户ID 组ID 用户权限 组的权限 他人权限
程序实例
范例程序阅读
范例程序阅读
第二种方式.用C语言库函数对文件操作 C库函数的文件操作实际上是独立于具体的操作系统平台的,不管是在DOS、Windows、Linux还是在VxWorks中都是这些函数,也就是说这写都是国际通用函数:
文件类型FILE 系统给每个打开的文件都在内存中开辟一个区域,用于存放文件的有关信息(如文件名、文件位置等)。
创建和打开文件 FILE * fopen(const char *path, const char * mode); fopen()实现打开指定文件filename,其中的mode为打开模式。 特别要注意的是:mode为字符串,和系统调用的不同 C语言中支持的打开模式如下表:
打开模式
3.1文件的打开与关闭 对文件进行操作之前,必须先打开该文件;使用结束后,应立即关闭,以免数据丢失。 C语言规定了标准输入输出函数库 用fopen( )函数打开一个文件 用fclose( )函数关闭一个文件。
文件的打开fopen()函数 1.原型: FILE * fopen("文件名","操作方式"); FILE * fopen(const char *path, const char *mode); 2.功能:返回一个指向指定文件的指针。 注:对文件操作的库函数,函数原型均在头文件stdio.h中。 其中: (1)“文件名”是指要打开(或创建)的文件名。 (2)“操作方式”如下图所示。 例如:FILE *fp; fp=fopen(“1.txt”,“r”);
一道考研题 下面的程序的作用是从磁盘stu.dat中读取N个学生的姓名、学号、成绩,然后在屏幕输出。请将程序补充完整。
2. ((fp=fopen(“stu.dat”,”rb”))!=NULL) 1 参考答案: 1. stdio.h 2. ((fp=fopen(“stu.dat”,”rb”))!=NULL) 3. fread(stud,sizeof(stuct student),N,fp); 4.fclose(fp);
这里仅仅给出主要大纲,详细内容还要仔细复习课件!
The End Thank your attention!