Linux程序设计复习tiand答案
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
基本知识:
1.1 Linux中C语言的重要性
Linux是一款非常优秀的开放源代码操作系统,在服务器解决方案方面和嵌入式领域有着巨大的优势。
近年来国内大多数大中型企业选择Linux系统作为服务器解决方案。
Linux和C天生有不解之缘。
Linux的操作系统内核就主要是用C写的,另外Linux下的很多软件也是用C写的,特别是一些著名的服务软件,比如MySQL、Apache等。
1.2 C语言开发环境的构成
编辑器:选择VI、VIM
编译器:选择GNU C/C++编译器gcc
调试器:应用广泛的gdb
函数库:glibc
函数头文件:glibc_header
1.3 Linux下C程序开发过程
使用VI等编辑工具编写源程序
保存为*.c
使用gcc编译成二进制可执行文件
执行可执行文件
有问题可以使用gdb进行调试
1.4 编译的概念和理解
在进行C程序开发时,编译就是将编写的C语言代码变成可执行程序的过程。
这一过程序是编译器来完成的。
编译器就是完成程序编译工作的软件。
编译器进行程序编译时完成了一系列复杂的过程。
1.4.1程序编译的过程
在这一操作时,程序完成复杂的过程。
一个程序的编译,需要完成词法分析、语法分析、中间代码生成、代码优化、目标代码生成。
(1)词法分析,指的是对由字符组成的单词进行处理,从左至右逐个字符地对源程序进行扫描,产生一个个的单词符号。
(2)语法分析。
语法分析器以单词符号作为输入,分析单词符号串是否形成符合语法规则的语句。
(3)中间代码生成。
中间代码是源程序的一种内部表示,或称中间语言。
(4)代码优化。
代码优化是指对程序进行多种等价变换,使得从变换后的程序能生成更有效的目标代码。
(5)目标代码生成。
1.4.2 编译器
所谓编译器,是将编写出的程序代码转换成计算机可以运行的程序的软件。
在进行C程序开发时,编写出的代码是源程序的代码,是不能直接运行的。
需要用编译器编译成可以运行的二进制程序。
在不同的操作系统下面有不同的编译器。
C程序是可以跨平台运行的。
但并不是说Windows系统下C 语言编写的程序可以直接在Linux下面运行。
Windows下面C语言编写的程序,被编译成exe文件。
这样的程序只能在Windows系统下运行。
如果需要在Linux系统下运行,需要将这个程序的源代码在Linux系统重新编译。
不同的操作系统下面有不同的编译器。
Linux系统下面编译生成的程序是不能在Windows系统上运行的。
1.5 gcc编译器
Linux系统下的gcc编译器(GNU C Compiler)是一个功能强大、性能优越的编译器。
gcc支持多种平台的编译,是Linux系统自由软件的代表作品。
各种硬件平台对gcc的支持使得其执行效率与一般的编译器相比平均效率要高20%~30%。
gcc编译器能将C、C++源程序、汇程语言和目标程序进行编译连接成可执行文件。
gcc对源程序扩展名的支持
通常来说,源文件的扩展名标识源文件所使用的编程语言。
例如C程序源文件的扩展名一般是“.c”。
在默认情况下,gcc通过文件扩展名来区分源文件的语言类型。
然后根据这种语言类型进行不同的编译。
gcc支持的扩展名
.c为扩展名的文件:C语言源代码文件;
.C、.cc或.cpp为扩展名的文件:C++源代码文件
.h为扩展名的文件:程序所包含的头文件;
.i为扩展名的文件:已经预处理过的C源代码文件,一般为中间代码文件;
.ii为扩展名的文件:已经预处理过的C++源代码文件,一般为中间代码文件;
.o为扩展名的文件:编译后的目标文件;
.s为扩展名的文件:是汇编语言源代码文件;
.S为扩展名的文件:经过预编译的汇编语言源代码文件;
1.8 编译程序常见的错误与问题
在编程时,出现的错误可能有逻辑错误与语法错误两种。
这两种错误的发生原因和处理方法是不同的。
逻辑错误指的是程序的设计思路发生了错误。
这种错误在程序中是致命的,程序可能正常编译通过,
但是结果是错误的。
当程序正常运行而结果错误时,一般都是编程的思路错误。
这时,需要重新考虑程序的运算方法与数据处理流程是否正确。
语法错误指的是程序的思路正确,但是在书写语句时,发生了语句错误。
这种错误一般是编程时不小心或是对语句的错误理解造成的。
在发生语句错误时,程序一般不能正常编译通过。
这时,会提示错误的类型和错误的位置,按照这些提示改正程序的语法错误即可完成错误的修改。
C程序中的错误,根据严重程序的不同,可以分为异常与错误两类。
在编译程序时,这两种情况对编译的影响是不同的,对错误与异常的处理方式是不同的。
1.什么是异常
异常指的是代码中轻微的错误,这些错误一般不会影响程序的正常运行,但是不完全符合编程的规范。
在编译程序时,会产生一个“警告”,但是程序会继续编译。
2.什么是错误
错误指的是程序的语法出现问题,程序编译不能正常完成,产生一个错误信息。
这时会显示错误的类型与位置。
根据这些信息可以对程序进行修改。
2.1 C程序的基本概念
2.1.1 C程序的基本结构
C程序由语句、函数、包含文件等部分组成。
–包含文件:一组#include <*.h>语句。
–用户自定义函数:用户已编写的完成特定功能的模块。
–主函数:程序自动执行的程序体。
–变量定义:定义变量以存储程序中的数据。
–数据运算:程序通过运算完成各种逻辑功能。
这些运算是由各种语句和函数实现的。
–注释:注释写在/* */符号之间,不是程序的必需部分,但是可以增强程序的可读性。
2.1.2 C程序的一般格式
C程序的一般结构如下所示:
程序的包含文件
子函数类型声明
全局变量定义
main主函数()
{
局部变量定义
<程序体>
}
自定义函数1()
{ 局部变量定义
<程序体>
}
自定义函数2()
{ 局部变量定义
<程序体>
}
……
2.2 数据类型
数据类型指的是一类数据的集合,是对数据的抽象描述。
数据类型的不同决定所占存储空间的大小不同。
每个变量在使用之前必须定义其数据类型。
C程序有:
–整型:短整型(short)、整型(int)、长整型(long)
–浮点型:单精度型(float)、双精度型(double)
–字符型(char)
–枚举类型(enum)
–构造类型:数组类型([])、结构体类型(struct)、共用体类型(union)
–指针型(*)
–空类型(void)
printf函数输出变量
printf()函数称为格式输出函数,功能是按用户指定的格式,把指定的数据显示到屏幕上。
printf函数是一个标准库函数,它的函数原型在头文件“stdio.h”中,该函数的使用方法如下所示。
printf(“格式控制字符串”,输出变量列表)
–输出变量列表中给出了各个输出变量。
–格式控制字符串用于指定输出格式,由格式字符串和非格式字符串两种组成。
–格式字符串是以%开头的字符串,在%后面跟有各种格式字符。
不同格式字符串的作用是说明输出数
据的类型、形式、长度、小数位数等。
如“%d”表示按十进制整型输出,“%ld”表示按十进制长整型输出。
这些格式字符串与输出变量列表中的变量一一对应。
scanf函数从键盘读入变量
scanf()函数是键盘格式化输入函数,可以从键盘输入读取信息,这个函数的使用方法如下所示。
scanf("<格式化字符串>",<地址表>);
一些常用的函数(只要记住函数名及其功能即可)
返回时间函数time
取当前时间函数gmtime
取得当地时间函数localtime
取得目前的时间函数gettimeofday
设置当前时间函数settimeofday
创建目录函数mkdir
删除目录函数rmdir
创建文件函数creat
删除文件函数remove
建立临时文件函数mkstemp
打开文件函数open
关闭文件函数close
在文件中写字符串函数write
读取文件函数read
将缓冲区数据写入到磁盘函数sync
将缓冲区数据写入到磁盘函数fsync
文件锁定函数flock
文件的移动函数rename
文件打开函数fopen
关闭文件函数fclose
字符写入函数putc与fputc
向文件中写入字符串函数fputs
数据写入函数fwrite
用域名取得主机的IP地址函数gethostbyname
用IP地址返回域名函数gethostbyaddr
第11章网络编程
什么是套接字
区分不同进程间的网络通信和连接,主要使用3个参数:通信的目的IP地址、使用的传输层协议(TCP 或UDP)和使用的端口号。
在编程时,就是使用这三个参数来构成一个套接字。
这个套接字相当于一个接口,可以进行不同计算机程序的信息传输。
提示:套接字=传输层协议+端口号+IP地址。
套接字类型
套接字类型指的是在网络通信中不同的数据传输方式。
例如UDP和TCP就是两种不同的套接字类型。
常用的套接字类型有下面3种。
–流套接字(SOCK_STREAM):流套接字使用了面向连接的可靠的数据通信方式,即TCP(The Transmission Control Protocol)协议。
这种服务可以实现无差错、无重复发送、并按顺序接收。
–数据报套接字(Raw Sockets):数据报套接字使用了不面向连接的数据传输方式,即UDP(User Datagram Protocol)协议。
这种协议在数据发送出去以后,即完成通信的任务。
然后,完全依靠网络来完成数据传输。
网络不能完全保证数据正确传输,也不能保证数据按顺序接收。
这种套接字不能保证数据传输的可靠性,可能在通信中出现数据丢失的情况,需要在程序中作出相应的处理。
–原始套接字(SOCK_RAW):前面讲述的两种套接字是系统定义的,所有的信息都需要按照这种方式进行封装。
原始套接字是没有经过处理的IP数据包,可以根据自己程序的要求进行封装。
如果要访问其它的协议,需要使用原始套接字来构造相应的协议。
习题:
1.选择题(自己做答案)
1.以下叙述正确的是(D)
A) C语言比其他语言高级
B) C语言可以不用编译就能被计算机识别执行
C) C语言出现的最晚、具有其他语言的一切优点
D) C语言以接近英语国家的自然语言和数学语言作为语言的表达形式
2. C语言中用于结构化程序设计的三种基本结构是(A)
A) 顺序结构、选择结构、循环结构
B) if、switch、break
C) for、while、do-while
D) if、for、continue
3.以下正确的叙述是(D)。
A) 在C语言中,main函数必须位于文件的开头
B) C语言每行中只能写一条语句
C) C语言本身没有输入、输出语句
D) 对一个C语言进行编译预处理时,可检查宏定义的语法错误
4.在一个C语言程序中(D)
A) main函数必须出现在所有函数之前
B) main函数必须出现在固定位置
C) main函数必须出现在所有函数之后
D) main函数可以在任何地方出现
5.下列关于C语言用户标识符的叙述中正确的是(B)
A) 用户标识符中可以出现下划线和中划线(减号)
B) 用户标识符中不可以出现中划线,但可以出现下划线
C) 用户标识符中可以出现下划线,但不可以放在用户标识符的开头
D) 用户标识符中可以出现下划线和数字,它们都可以放在用户标识符的开头
6.以下C语言中,对函数不正确的描述是( A )。
A) 当用数组名作形参时,形参数组改变可使实参数组随之改变
B) 允许函数递归调用
C) 函数形参的作用范围只是局限于所定义的函数内
D) 函数说明必须在主调函数之前
7.以下叙述中不正确的是(A)。
A) 在C中,函数中的自动变量可以赋初值,每调用一次,赋一次初值。
B) 在C中,在调用函数时,实在参数和对应形参在类型上只需赋值兼容。
C) 在C中,外部变量的隐含类别是自动存储类别。
D) 在C中,函数形参可以说明为register变量。
8.当调用函数时,实参是一个数组名,则向函数传送的是( B )。
A) 数组的长度B) 数组的首地址
C) 数组每一个元素的地址D) 数组每个元素中的值
9.以下对C语言函数的有关描述中,正确的是( A )。
A) 在C中,调用函数时,只能把实参的值传送给形参,形参的值不能传送给实参
B) C函数既可以嵌套定义又可以递归调用
C) 函数必须有返回值,否则不能使用函数
D) C程序中有调用关系的所有函数必须放在同一个源程序文件中
10.以下叙述中错误的是(D)
A.C程序中的#include和#define行均不是C语句
B.除逗号运算符外,赋值运算符的优先级最低
C.C程序中,j++;是赋值语句
D.C程序中,+、-、*、/、%号是算术运算符,可用于整型和实型数的运算11.以下叙述中正确的是(B)
A.预处理命令行必须位于C源程序的起始位置
B.在C语言中,预处理命令行都以"#"开头
C.每个C程序必须在开头包含预处理命令行:#include<stdio.h>
D.C语言的预处理不能实现宏定义和条件编译的功能
12.一个C程序的执行是从( A )。
A)本程序的main函数开始,到main函数结束
B) 本程序的main函数开始,到本程序文件的最后一个函数结束
C) 本程序文件的第一个函数开始,到本程序文件的最后一个函数结束
D)本程序文件的第一个函数开始,到本程序main函数结束
13.以下叙述不正确的是(D )。
A)一个C源程序可由一个或多个函数组成
B)一个C源程序必须包含一个main函数
C)C程序的基本组成单位是函数
D)在C程序中,注释说明只能位于一条语句的后面
14.一个C语言程序是由( B )。
A)一个主程序和若干子程序组成B)函数组成
C)若干过程组成D)若干子程序组成
15.若x,i,j和k都是int型变量,则执行下面表达式后x的值为( C )。
x=(i=4,j=16,k=32)
A)4 B)16 C)32 D)52
16.下列四组选项中,均不是C语言关键字的选项是( A )。
A)define B)getc C)include D)while
IF char scanf go
type printf case pow
17.下面四个选项中,均是不合法的用户标识符的选项是( C )。
A) A B)float C)b-a D)_123
P_0 1a0 goto temp
do _A int INT
18.在C语言中,要求运算数必须是整型的运算符是( D )。
A) / B) ++ C) != D)%
19.在C语言中, char型数据在内存中的存储形式是(D )。
A)补码B)反码C)原码D)ASCII码
20.若有以下定义,则正确的赋值语句是(B )。
int a,b;float x;
A) a=1,b=2, B)b++; C) a= b= 5 D) b= int(x);
21.下面正确的字符常量是( D )。
A、“c”
B、…\\”
C、”
D、…k‟
22.以下叙述不正确的是( D )。
A、在C程序中,逗号运算符的优先级最低
B、在C程序中,MAX和max是两个不同的变量
C、若a和b类型相同,在计算了赋值表达式a=b后,b中的值将放入a中,而b中的值不变
D、从键盘输入数据时,对于整型变量只能输入整型数值,对于实型变量只能输入实型数值23.以下叙述正确的是(C )。
A、在C程序中,每行只能写一条语句
B、若a是实型变量,C程序中允许赋值a=10,因此实型变量中允许存放整型数据
C、在C程序中,%是只能用于整数运算的运算符
D、在C程序中,无论是整数还是实数,都有能被准确无误地表示
24.若一个int型数据在内存中占2个字节,则unsigned int 型数据的取值范围为( B )。
A、0~255 B、0~65535 C、0~32767 D、0~2147483647
25.若x、i、j、k都是int型变量,则通过计算x=(i=4,j=16,k=32)表达式后,x的值为( C )。
A、4
B、16
C、32
D、52
26.设以下变量均为int类型,则值不等于7的表达式是( C )。
A、(x=y=6,x+y,x+1)
B、(x=y=6,x+y,y+1)
C、(x=6,x+1,y=6,x+y)
D、(y=6,y+1,x=y,x+1)
27.若int a,b,c;则为它们输入数据的正确输入语句是(D )。
A、read(a,b,c);
B、scanf(“%d%d%d”,a,b,c);
C、scanf(“%d%d%d”,&a,%b,%c);
D、scanf(“%d%d%d”,&a,&b,&c);
29、下面正确的自定义标识符是( A )
A) a2b3 B) int C) int abc D) 2a3b
30.有以下程序段
int m=0,n=0; char c=‟a‟;
scanf("%d%c%d",&m,&c,&n);
printf("%d,%c,%d\n",m,c,n);
若从键盘上输入:10A10<回车>,则输出结果是: A
A) 10,A,10 B) 10,a,10 C) 10,a,0 D) 10,A,0
31.以下程序中,while 循环的次数是( D )。
#include <stdio.h>
void main(void)
{ int i = 0;
while (i<10) {
if (i<1) continue;
if (i==5) break;
i++;
}
}
A) 1 B) 6 C) 10 D) 死循环,不能确定次数
32.以下程序的输出结果是( C )
#include <stdio.h>
void main(void)
{
int a = 1, b = 2, c = 3;
printf(“%d”, c>b>a);
}
A) 2 B) 1 C) 0 D) 3
33.对以下程序段,while 循环执行的次数是( B )。
int k=0
while (k=1) k++;
A) 无限次B) 有语法错,不能执行C) 一次也不执行D) 执行1次
34.在下列选项中,不正确的赋值语句是( D )。
A) ++t; B) n1=(n2=(n3=0)); C) k=i==j; D) a=b+c=1;
35.若变量a 是int 类型,并执行了语句a = ‘A’+1.6;后,则正确的叙述是(C )。
A) a的值是字符’C’B) a的值是浮点型C) a的值是字符’A’的ASCII值加1
D) 不允许字符型和浮点型相加
36.执行以下程序段后,变量y的值是( A )。
int x, y;
x = 1;
y = (++x*5);
A) 10 B) 5 C) 20 D) 15
37.若有下列说明和语句:int a[4][5], (*p)[5]; p = a; 则对a数组元素的正确引用是( B )。
A) p+1 B) *(p+3) C) *(p+1)+3 D) *(*p+2)
38.表达式3.6-5/2+1.2+5%2的值是D
A.4.3
B.4.8
C.3.3
D.3.8
39.以下数组定义中错误的是(B)
A.int x[][3]={0};
B.int x[2][3]={{l,2},{3,4},{5,6}};
C.int x[][3]={{l,2,3},{4,5,6}};
D.int x[2][3]={l,2,3,4,5,6};
二、编程(自己做答案,考试时尽量不要出现完全相同的答案)
1.sum=2+5+8+11+14----,输入正整数n,求sum的前n项和。
#include <stdio.h>
void main()
{
int i=0;
int n;
int sum=0;
int j=2;
printf("输入正整数n:");
scanf("%d",&n);
while(i<n)
{ sum+=j;
j+=3;
i++;
}
printf("2+5+8+11+……前%d项和为:%d\n",n,sum);
}2.输入一个double 类型的数,使该数保留小数点后2位,且对第3位进行四舍五入处理。
解:#include<stdio.h>
void main()
{double d1;
scanf("%lf",&d1); //d1= (int)(100.0 * d1 + 0.5) / 100.0;
printf("保留小数点后2位,对第三位进行四舍五入处理后:%.2lf",d1);
}
3. 设计一个从5个数中取最小数和最大数的程序。
#include<stdio.h>
void main()
{
int a[5];
int max,min;
int i,j;
printf("请输入5个整数:");
for(i=0;i<5;i++)
{
scanf("%d",&a[i]);
}
min=a[0];
max=a[0];
for(j=0;j<5;j++)
{
if(a[j]>max)
{
max=a[j];
}
if(a[j]<=min)
{
min=a[j];
}
}
printf("其中的最大数和最小数分别为:%d,%d\n",max,min);
}4. 编写程序,输入一个数,打印出它是奇数还是偶数。
解:
int f(int n)
{
return n%2;
}
void main()
{
int n;
scanf("%d",&n);
if(f(n)==1)
printf("奇数\n");
else
printf("偶数\n");
}
5.编写一个程序,输入两个两位数a,b,将a,b合并成一个整数放在c中,合并的方式:将a的十位和个位依次放在c的千位和十位上,b的十位和个位依次放在c的个位和百位上,如当a=45,b=12时,c=4251。
解:
#include<stdio.h>
void merge(int a,int b)
{
int a1,a2,b1,b2,c;
a1=a/10;
a2=a%10;
b1=b/10;
b2=b%10;
c=a1*1000+b2*100+a2*10+b1;
printf("a,b合并后的数为:%d",c);
}
void main()
{
int x,y;
printf("输入2个两位数:");
scanf("%d,%d",&x,&y);
if(9<x<100&&9<y<100)
merge(x,y);
}
6. 求1!+2!+3!+…+10!。
解:
#include<stdio.h>
int f1(int n)
{
int x;
if(n==1) x=1;
else
x=n*f1(n-1);
return x;
}
void main()
{
int i ,sum=0;
for(i=1;i<=10;i++)
{
sum =sum+f1(i);
}
printf("1到10的阶乘和是:%d",sum);
}7. 求1~100间的素数(素数>1,且除了1和自身外,不能被任何其它整数整除)。
解:#include <stdio.h>
int prime(int a)
{
int i;
for(i=2;i<=a/2;i++)
if(a%i==0)
return 0;
return 1;
}
void main()
{
int x;
printf("1到100之间的所有素数有:\n");
x=2;
while(x<=100)
{
if(prime(x))
printf("%d ",x);
x=x+1;
}
}8. 编写程序,输出从公元1800年到2000年所有闰年的年号。
每输出4个年号换一行。
判断年号n为闰年的条件是:
(1) 若n能被4整除但不能被100整除,则n是闰年;
(2) 若n能被400整除,则n是闰年。
解:#include <stdio.h>
void main(){
int a,i=0;
for(a=1800;a<=2000;a++)
{ if((a % 4 == 0 && a % 100 != 0) || a % 400 == 0)
{ printf("-%d-",a); i++;} if(i%4==0) printf("\n");
}
}。