资源描述
课程名:Linux下c语言编程专业:08嵌入式系统工程专
试验1 : Linux系统基本shell指令试验2: gee编译器与多文件交叉包含
试验3:库文件的创立与使用试验4: linux系统程序调试一行列式求值程序
试验5:进程与线程程序调试试验6: TCP程序与
试验7: UDP程序试验1 Linux系统基本shell指令
实验一 Linux系统基本文件操作试验目的:
掌握Linux系统常见的文件操作指令;掌握Linux系统常见的文件形式;
试验设备PC机、虚拟机、redhat9,桌面环境KDE
试验原理一、Linux系统常见的文件形式
(一)为便于用户识别文件形式,操作系统一般使用扩展名来标示文件类型。文件扩展 名是文件名的最后一个点之后的局部(在文件sneakers. txt中,“txt”是文件的扩展名)。 下面简单列出了一些文件扩展名和它们的含义:
1 .压缩的和归档的文件.bz2 一使用bzip2压缩的文件
gz —使用gzip压缩的文件.tar —使用tar (tape archive,磁带归档的简写)压缩的文件,乂称tar文件
.tbz 一用tar和bzip压缩的文件.tgz 一用tar和gzip压缩的文件
.zip -使用ZIP压缩的文件,在MS-DOS应用程序中常见。多数为Linux压缩的文件 使用gzip压缩,因此Linux文件中的.zip归档较少见。
2 .文件格式,au —音频文件
,gif — GIF图像文件.html/.htm — HTML 文件
,jpg — JPEG图像文件.pdf一 文档的电子映像;PDF代表Portable Document Format (可移植文档格式)
.png 一 PNG图像文件(Portable Network Graphic的简写,可移植网络图形).ps - PostScript文件,为打印而格式化过的文件
.txt — 纯ASCII文本文件.wav —音频文件
.xpm —图像文件unsigned int i,j,k;
Type T=O,t;Type *p=NULL;
if(n<= 1) return (*a)*n;p=(Type*) malloc(sizeof(Type)*(n-1 )*(n-1));
if(!p) {puts("Err"); return 0:} for(i=0,t=l;i<n;i++,t*=-l) {JZyzs(p,a,n,0,i);
#iRiefMUCH_ZEROif(a[i])
#endif(
T+=(HLSabsDigui(p,n-1 )*t*a[i]);}
) free(p);return T;
int main()(
Type a[400]={ 8,1 ,-51,9,-3。-6,-5,2,-1,204-7,6};
int n=4;
clock_t start,end;
clrscr();
start=clock();
printf("\n# %d\n",HLSabsDigui(a,n));
end二clock。;
printf(',%lf\n%f\n",(end-start)/CLK_TCK,(end-start)/CLK_TCK);
getch();}
试验报告要求:
单步运行程序,分析程序执行过程,写出程序流程图试验4进程与线程程序调试
试验FI的:通过程序清晰进程与线程的概念;试验器材:PC机、redhat9 , kde
试验过程
(1)进程程序如下:
#include <sys/lypes.h>#includc <stdio.h>
#include <unistd.h> int inain(void)(
pid_l pid;
unsigned long i;
int j=prinlf("ju bu bian liang\n");
for(i=0;i< 100000000;i++)
if((pid=fork())<0)
{printfC'fork error!\n");
exit(l);
)
else if(pid==O)
{printfC'Chikl process is printingAn");
1
else
{printf("Paren( process is printingAn");
Icxit(0);
提示:调节循环次数,使循环次数接近系统默认时间片轮转时间,查看父进程和子进程不同 次序的输出情况。
(2)线程
线程(thread)技术早在60年代就被提出,但真正应用多线程到操作系统中去, 是在80年代中期,Solaris是这方面的佼佼者。传统的Unix也支持线程的概念,但 是在一个进程(process)中只允许有一个线程,这样多线程就意味着多进程。现在, 多线程技术已经被许多操作系统所支持,包括Windows/NT,当然,也包括Linux。
为什么有了进程的概念后,还要再引入线程呢?使用多线程到底有哪些好处?什 么的系统应该选用多线程?我们首先必须回答这些问题。
使用多线程的理由之一是和进程相比,它是i种非常“节俭”的多任务操作方式。 我们知道,在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立 众多的数据表来维护它的代码段、塘栈段和数据段,这是一种“昂贵”的多任务工作方 式。而运行于一个进程中的多个线程,它们彼此之间使用相同的地址空间,共享大部 分数据,启动一个线程所花费的空间远远小于启动一个进程所花费的空间,而且,线 程间彼此切换所需的时间也远远小于进程间切换所需要的时间。据统计,总的说来, 一个进程的开销大约是一个线程开销的30倍左右,当然,在具体的系统上,这个数 据可能会有较大的区别。
使用多线程的理由之二是线程间方便的通信机制。对不同进程来说,它们具有独 立的数据空间,要进行数据的传递只能通过通信的方式进行,这种方式不仅费时,而 且很不方便。线程那么不然,由于同一进程下的线程之间共享数据空间,所以一个线程 的数据可以直接为其它线程所用,这不仅快捷,而且方便。当然,数据的共享也带来 其他一些问题,有的变量不能同时被两个线程所修改,有的子程序中声明为static的 数据更有可能给多线程程序带来灾难性的打击,这些正是编写多线程程序时最需要注 意的地方。
除了以上所说的优点外,不和进程比拟,多线程程序作为一种多任务、并发的工 作方式,当然有以下的优点:
1)提高应用程序响应。这对图形界面的程序尤其有意义,当一个操作耗时很长 时,整个系统都会等待这个操作,此时程序不会响应键盘、鼠标、菜单的操作,而使 用多线程技术,将耗时长的操作(time consuming)置于一个新的线程,可以防止这 种尴尬的情况。
2)使多CPU系统更加有效。操作系统会保证当线程数不大于CPU数目时,不 同的线程运行于不同的CPU上。
3)改善程序结构。一个既长又复杂的进程可以考虑分为多个线程,成为几个独 立或半独立的运行局部,这样的程序会利于理解和修改。
下面我们先来尝试编写一个简单的多线程程序。
2简单的多线程编程
Linux系统卜的多线程遵循POSIX线程接11,称为pthreack编写Linux卜的多 线程程序,需要使用头文件pthread.h,连接时需要使用库libpthread.a。顺便说一下, Linux下pthread的实现是通过系统调用clone ()来实现的。clone ()是Linux所 特有的系统调用,它的使用方式类似fork,关于clone ()的详细情况,有兴趣的读 者可以去查看有关文档说明。下面我们展示一个最简单的多线程程序examplel.Co
/* example.c*/
#include <stdio.h>
#include <pthread.h>
void thread(void)
int i;
for(i=0;i<3;i++)
printf(HThis is a pthread.\n°);
)
int main(void)
(
pthread_t id;
int i,ret;
ret=pthread_create(&id,NULL,(void *) thread,NULL);
if(ret!=O){
printf ("Create pthread error!\n");
exit (1);
)
for(i=0;i<3;i++)
printf("This is the main process.\n");
pthread Join(id, NULL);
return (0);
)
我们编译此程序:
gcc examplel .c -Ipthread -o examplel
试验报告要求;写出进程和线程的调试程序
试验5:库文件的创立与使用
试验目的:掌握库文件工作的原理,库文件的创立和使用方法
试验器材:
试验原理:
一、为什么要使用库文件我们在实际编程工作中肯定会遇到这种情况:有几个工程里有一些函数模块的功能相同, 实现代码也相同,也是我们所说的重复代码。比方,很多工程里都有一个用户验证的功能。 代码段如下:
〃UserLogin.h文件,提供函数声明
int IsValidUser(char* username, int namelen);
〃UserLogin.c文件,实现对用户信息的验证
int IsValidUscr(char* username, int namclcn)
(
int IsValid = 0;
/*下面是具体的处理代码,略去*/
return IsValid
)
如果每个工程都保存着这两个UserLogin.h和UserLogin.c文件,会有以下几个弊端:
1、每个工程里都有重复的模块,造成代码重复。
2、代码的重用性不好,一旦IsValidUser的代码发生了变化,为了保持设计的一致性, 我们还要手工修改其他工程里的UserLogin.c文件,既费时又费力,还容易出错。库文件就 是对公共代码的一种组织形式。
为了解决上面两个弊端,就提出了用库文件存放公共代码的解决方案,其要点就是把公 共的(也就是可以被屡次狂用的)目标代码从工程中别离出来,统一存放到库文件中,工程 要用到这些代码的时候,在编译或者运行的时候从库文件中取得目标代码即可。库文件又分 两种:静态库和动态库。
二、静态库与动态库
如果程序是在编译时加载库文件的,就是使用了静态库。如果是在运行时加载目标代码, 就成为动态库.换句话说,如果是使用静态库,那么静态库代码在编译时就拷贝到了程序的代 码段,程序的体积会膨胀。如果使用动态库,那么程序中只保存库文件的名字和函数名,在运 行时去查找库文件和函数体,程序的体枳基本变化不大。
静态库的原那么是“以空间换时间”,增加程序体积,减少运行时间;
动态库那么是“以时间换空间”,增加了运行时间,但减少了程序本身的体积。
下面我们就以实际例子来看看如何使用这两种库.
三、静态库的编写和使用I、概述
静态库文件的扩展名一般为a其编写步骤很简单。
⑴编写函数代码⑵编译生成各目标文件
⑶用ar文件对目标文件归档,生成静态库文件。
注意归档文件名必须以lib打头。
使用要点:
⑴在gcc的-I参数后加上静态库头文件的路径。
⑵在gcc的-L参数后加上库文件所在目录
⑶在gcc的-1参数后加上库文件名,但是要去掠lib和.a扩展名。
比方库文件名是libtest.a那么参数就是-1 test2、编写最简单的静态库文件
编写如下两个文件,注意放在同一目录中
myalib.h〃静态库头文件
myalib.c〃静态库实现文件
//myalib.h文件的内容 void test();//myalib.c文件的内容
#inlcude <stdio.h> void test() (
printf("lest\nM);I
3、制作库文件⑴生成目标文件
gcc -c myalib.c执行完后会生成一个myalib.o文件
⑵用ar命令归档,格式为ar -rc〈生成的档案文件名,<.o文件名列表, 再次提醒,归档文件名一定要以lib打头,.a结尾。
ar -rc libtest.a myalib.o执行完后会生成一个libtest.a文件
4、使用库文件⑴编写一个测试程序main©内容为
//main.c测试静态库调用的程序#include '•myalib.h"〃要把函数的头文件包含进来,否那么编译时会报错
in( main(int argc,char* argv[])( test();
return 0;)
⑵编译目标文件,注意要把静态库头文件的路径加到-I参数里面
gcc -I /root/exercise -o main.o -c main.c现在生成了一个main.o文件
⑶生成可执行文件,注意要把静态库文件的路径加到-L参数里面, 把库文件名(去掉打头的lib和结尾的.a)加到-1参数后面。如卜面所示 gcc -o main -L/root/exercise main.o -Itest 此时就会生成一个名为main的可执行文件另外,注意-1参数好象应该加到输入文件名的后面,否那么会报错。
比方 gcc -o main -L/root/exercise -Itest main.o 就会提示 main.o(.text+Oxl 1): In function 'main':
:undefined reference to 'test'
collect2: Id returned I exit status⑷执行可执行文件查看效果
执行./main,输出
test
说明执行成功。
四、动态库的编写1、概述
动态库一般以.so结尾,就是shared object的意思.
其基本生成步骤为
⑴编写函数代码
⑵编译生成动态库文件,要加上-shared和-fpic选项,
库文件名以lib开头,以.so结尾。
使用方式分为两种:隐式调用和显示调用
隐式调用类似于静态库的使用,但需修改动态链接库的配置文件/etc/ld.so.conf;
显示调用那么是在主程序里使用dlopen、dlsym、dlerrordlclose等系统函数。
具体的调用方式会在"五、动态库的调用”中详细说明.
2、编写最简单的动态库文件
为了便于对照,我们仍然采用静态库中的文件做例子.
编写如下两个文件,注意放在同一目录中
myalib.h〃静态库头文件
myalib.c〃静态库实现文件
//myalib.h文件的内容void test();
//myalib.c文件的内容#inlcude <stdio.h>
void tcst()(
printf("test\n");)
3、编译生成动态库,库文件名以lib开头,以.so结尾。
gcc -fpic -shared -o libtcst.so myalib.c此时就生成一个libtest.so文件
五、动态库的隐式调用隐式调用的含义是代码里不出现库文件名,就是说这个代码和
调用静态库的代码是类似的。
I、编写测试文件//main.c测试动态库隐式调用的程序
#include "myalib.h"〃要把函数的头文件包含进来,否那么编译时会报错
int main(in( argc,char* argv(J)(
test();
return 0;2、编译测试程序,与静态库类似,要把头文件的路径加到-I参数里面 gcc -I /root/exercise -o main.o -c main.c
现在生成了一个main.。文件3、连接生成测试程序
gcc -o main -L/root/exercise main.o -Itest现在生成了一个main文件
4、执行测试程序 ./main 此时出现提示
./main: error while loading shared libraries: libtest.so: cannot open shared object file: No uch file or directory o
这个原因就是程序运行时并不知道动态库所在的路径,因此自然找不到。
解决这个问题的方法有三种。见下节六、使动态库被系统共享的三种方法
(再次说明:本节参考了计算机世界网雨亦奇的文章”LINUX动态链接库高级应用” 地址 )(1)拷贝动态链接库到系统共享目录下,或在系统共享目录下为该动态链接库 建立连接(硬连接或符号连接均可.,常用符号连接).这里说的系统共享目录, 指的是LINUX动态链接库存放的目录,包括
/lib,/usr/lib以及文件内所列的•系列目录.
(2)将动态链接库所在目录名追加到动态链接库配置文件中.
# pwd » Idconfig
此时再执行main,即可成功.
(3)利用动态链接库管理命令Idconfig,强制其搜索指定目录,并更新缓存文件,便于动态装入.
# Idconfig 'pwd'
试验6: TCP程序与UDP程序
试验目的:掌握TCP程序和UDP程序的不同编写方法试验器材:PC机器、redhaty KDE
试验原理:
TCP服务器端的编写步骤:
1 .首先,你需要创立一个用于通讯的套接口,一般使用socket调用来实现。这等于你 有了一个用于通讯的 :)
2 .然后,你需要给你的套接口设定端口,相当于,你有了 号码。这一步一般通过 设置网络套接口地址和调用bind函数来实现。
3 .调用listen函数使你的套接口成为一个监听套接字。以上三个步骤是TCP服务器的 常用步骤。
4 .调用accept函数来启动你的套接字,这时你的程序就可以等待客户端的连接了。
5 .处理客户端的连接请求。
6 .终止连接。
现在让我们来看看网络程序客户端的编程步骤:
1 .和服务器的步骤一样。
2 .通过设置套接口地址结构,我们说明,客户端要与之通讯的服务器的IP地址和端I I。
3 .调用connect函数来连接服务器。
4 .发送或者接收数据,一般使用send和recv函数调用来实现。
5 .终止连接。
Tcp程序如下:
int main(int argc,char *argv[])
{
int listensock,connsock; /定义两个socket套接字,一个用于监听,一个用于通讯 struct sockaddrjn serveraddr; /定义网络套接字地址结构
const char buff[] = "Hello! Welcome here!\r\n"; /定义要发送的数据缓冲区;
listensock = socket(AF_INET,SOCK_STREAMzO); /创立一个套接字,用于监听 bzero(&serveraddr,sizeof(servaddr)); /地址结构清零 serveraddr.sin_family = AF_INET; /指定使用的通讯协议族
serveraddr.sin_addr.s_addr = htonl(INADDR_ANY); /指定接受任何连接,因为 服务器不知道谁会要求连接
serveraddr.sin_port = htons(5000); /指定监听的端口
bind(listensockz(sockaddr *)&serveraddr/sizeof(serveraddr)); /给套接口邦定 地址
listen(listensock,1024); /开始监听
connsock = accept(listensock,(sockaddr *)NULL, NULL); /建立通讯的套接字,accept函数,等待客户端程序使用connect函数的连接
send(connsockzbuff,sizeof(buff)z 0); /向客户端发送数据
close(connsock); /关闭通讯套接字
close(listensock); /关闭监听套接字
}
这是客户端的程序:
int main(int argczchar **argv)
{
char recvbuff[100]; /定义要接收的数据缓冲区 int sockfd; /定义一个socket套接字,用于通讯 struct sockaddr_in serveraddr;/定义网络套接字地址结构 if(argc != 2){
printf("Usage: echo ip 地址”); exit(O);
}sockfd = socket(AF_INET,SOCK_STREAM,0); /创立一个套接字 bzero(&serveraddrzsizeof(serveraddr));
serveraddr.sin_family = AF_INET; /指定使用的通讯协议族 serveraddr.sin_port = htons(5000);/指定要连接的服务器的端口 inet_pton(AF_INETZ argv[l]z &serveraddr.sin_addr);
connect(sockfdz(sockaddr *)&serveraddrzsizeof(serveraddr)); /连接服务器 recv(sockfd,recvbuff,sizeof(recvbuff),0); /接收服务器的数据 p「intf("%s\n,「ecvbuff); /打印接收到的数据
close(sockfd); /关闭套接字
}
udp程序如下:
int port = 5500;
void main()
{
int sockfd;
int count = 0;
int flag;
char buf[80];
struct sockaddrjn address;
sockfd = socket(AF_INET, SOCK_DGRAMZ 0); 〃看到不同的地方了吗? memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_addr.s_addr = inet_addr(" 127.0.0.1");
address.sin_port = htons(port);
flag = 1;
do{
sprintf(bufz"Packet %d\n"/ count);
if(count > 30){
sprintf(bufz"over\n");
flag = 0;
)
sendto(sockfd,buf,sizeof(buf),0,(struct sockaddr *)&address, sizeof(address)); //发现了吗使用的函数不一样,它也是发送数据 count++;
3 .系统文件.conf种配置文件。配置文件有时也使用.cfgo
Jock -锁(lock)文件;用来判定程序或设备是否正在被使用.rpm — Red Hat用来安装软件的软件包管理器文件
4 .编程和脚本文件.C - C程序语言的源码文件
,cpp - C++程序语言的源码文件.h — C或C++程序语言的头文件
.0 —程序的对象文件.pl — Perl 脚本
.py - Python 脚本.so —库文件
.sh 一 shell 脚本.tel — TCL 脚本
文件扩展名不总是被使用或被一致地使用。那么,如果一个文件没有扩展名,或者它与 它的扩展名不符时怎么办呢?
这个时候,file命令就会对你有所帮助。
譬如,你找到了一个叫做Saturday的文件、它没有扩展名。使用file命令,你就可以 判定这个文件的类型:
file Saturday
(二)为便于系统磁盘和文件系统的管理,Linux系统将所有Linux对目录和设备都当 作文件来进行处理,这样就简化了对各种不同类型设备的处理,提高了效率。Linux中主要 的文件类型分为4种:普通文件、目录文件、链接文件和设备文件。
(1)普通文件普通文件如同Windows中的文件一样,是用户日常使用最多的文件。它包括文本文件、shell 脚本(shell的概念在第2章会进行讲解)、二进制的可执行程序和各种类型的数据。
(2)目录文件
在Linux中,目录也是文件,它们包含文件名和子目录名以及指向那些文件和子目录 的指针。目录文件是Linux中存储文件名的惟一地方,当把文件和目录相对应起来时,也 就是用指针将其链接起来之后,就构成了目录文件。因此,在对目录文件进行操作时,一般 不涉及对文件内容的操作,而只是对目录名和文件名的对应关系进行了操作。
(3)链接文件
链接文件有些类似于Windows中的“快捷方式”,但是它的功能更为强大。它可以实 现对不同的目录、文件系统甚至是不同的机器上的文件直接访问,并且不必重新占用磁盘空 间。
(4)设备文件
Linux把设备都当作文件一样来进行操作,这样就大大方便了用户的使用(在后面的 Linux编程中可以更为明显地看出)。在Linux下与设备相关的文件一般都在/dev目录下, 它包括两种,一种是块设备文件,另一种是字符设备文件。
块设备文件是指数据的读写,它们是以块(如由柱面和扇区编址的块)为单位的设 备,最简单的如硬盘(/dev/hdal)等。
字符设备主要是指串行端口的接口设备。
Linux中的文件属性
}while (flag);
)
这是接收数据的程序:
char *hostname = "127.0.0.1"; 〃这个特殊的ip表示本的计算机 void main(){
int sinlen;int port = 8080;
char message[256];int sockfd;
struct sockaddrjn sin;struct hostent *server_host_name; // hostent 结构有着机器的名字等信息 server_host_name = gethostbyname(" 127.0.0.1"); // 这个函数用来得到
“127.0.0.1”的主机名字,也就是本机的名字
bzero(&sin,sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = htonl(INADDR_ANY);
sin.sin_port = htons(port);sockfd = socket(PF_INETzSOCK_DGRAMz0); 〃这里也不一样 bind(sockfdz(struct sockaddr *)&sinzsizeof(sin));
while(l){sinlen = sizeof(sin);
recvfrom(sockfd/message/256/0z (struct sockaddr*)&sin,&sinlen);〃它是接受数据的函数
printf("\nData come from server:\n%s\n"/message); if(strncmp(messagez"over"z4) ==0)break;) close(sockfd);
}
试验报告要求:
写成TCP程序和UDP程序编程的主要不同点
试验7:复杂C程序调试一keil试验FI的:通过其他编译调试工具keil进一步熟悉程序调试的思想。 试验仪器:keil, PC机
试验过程:
利用keil调试如下代码:
#include <reg51 .h>//int neg=O;
void delayns(void)(
int i;
for(i=0;i<10();i++)I
int gelkeyO(
int i,ml=0,key=0;
P3=0Xfe;
P1=OXFF;
for(i=0;i<4;i++)
{
ml=Pl;
while(Pl!=OXFF)
switch(ml)
{
case Oxfe: key=16;break;
case Oxfd: key=9;break;
case Oxfb: key=8;break;
case 0xf7: key=7;break;
I
P1=OXFF;
P3=0XfD;
P1=OXFF;
for(i=0;i<4;i++)
{
ml=P1;
while(Pl!=OXFF)
switch(ml)
case Oxfe:key= 15;break;
case Oxfd:key=6;break;
case Oxfb:key=5;break;
case 0xf7:kcy=4;break;
)
P1=OXFF;
P3=OXfB:
P1=OXFF;
for(i=0;i<4;i++)
(
ml=Pl;
whilc(Pl!=OXFF)
switch(ml)
(
case Oxfe: key= 14;break;
case Oxfd: key=3;break;
case Oxfb: key=2;break;
case Oxf7: kcy= 1;break;
)
P1=OXFF;
P3=OXf7;
P1=OXFF;
for(i=0;i<4;i++)
(
ml=Pl;
while(Pl!=OXFF)
svvitch(ml)
{
case Oxfe: kcy=13; break;
case Oxfd: key= 12; break;
case Oxfb: key=l 0; break; case Ox 17: key= 11; break;
1
PI=OXFF;delayns();
return key;void main(void)
{getkey();
)试验报告要求:写出使用keil调试程序和使用kdb调试程序的相同和不同。Hj 水
资料:不需要的可以自行删除Abstract: Based on the comprehensive analysis on the plastic part's structure service requirement, mounding quality and mould menu factoring cost. A corresponding injection mould of internal side core pulling was designed. By adopting the multi-direction and multi-combination core-pulling. A corresponding injection mould of internal side core pulling was designed, the working process of the mould was introduced
C语言详解-枚举类型注:以下全部代码的执行环境为VC++ 6.0
在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这 项工作,您的代码可能是:
# dcfinc MON 1define TUE 2
# define WED 3defineTHU 4
# define FRI 5define SAT 6
# define SUN 7在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。
1 .定义一种新的数据类型一枚举型以下代码定义了这种新的数据类型一枚举型
enum DAY
MON=1,TUE, WED. THU, FRI, SAT, SUN};
(I)枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号, 隔开。
⑵DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。
(3)第•个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。
(4)可以人为设定枚举成员的值,从而自定义某个范围内的整数。
(5)枚举型是预处理指令#define的替代。
(6)类型定义以分号;结束。
2 .使用枚举类型对变量进行声明新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float,双精度浮点型double,字符型char,短整型shori等等。用这些基本数据 类型声明变量通常是这样:
char a; 〃变量a的类型均为字符型charcharletter;
ini x,y,
z; 〃变量x,y和z的类型均为整型intint number;
double m, n;double result; 〃变量result的类型为双精度浮点型double
既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。
方法一:枚举类型的定义和变量的声明分开enum DAY
{
MON” TUE, WED. THU, FRI, SAT, SUN};
enum DAY yesterday;enum DAY today;
enum DAY lomorrow; 〃变量 tomorrow 的类型为枚举型 enum DAYenum DAY good_day, bad_day; //变量 good_day 和 bad_day 的类型均为枚举型 enum DAY
方法二:类型定义与变量声明同时进行:
enum 〃跟第一个定义不同的是,此处的标号DAY省略,这是允许的。 {Saturday, Sunday = 0, monday, tuesday, Wednesday, thursday, friday
} workday; 〃变量workday的类型为枚举型enum DAYenum week { Mon=l, Tue, Wed, Thu, Fri Sat, Sun} days; 〃变量 days 的类型为枚举型 enum week
enum BOOLEAN { false, true } end_flag, malch_flag; 〃定义枚举类型并声明了两个枚举型变 量方法三:用[ypedef关键字将枚举类型定义成别名,并利用该别名进行变量声明: typedef enum workday {
Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, Friday} workday; 〃此处的workday为枚举型enum workday的别名
workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday enum workday 中的 workday 可以省略:
typedef enum {Saturday, sunday = 0, monday, luesday, Wednesday, thursday, friday
} workday; 〃此处的workday为枚举型enum workday的别名workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举型 workday,也即 enum workday 也可以川这种方式:
typedef enuni workday {
Saturday, sunday = 0, monday, tuesday, Wednesday, thursday, friday 1;workday today, tomorrow; 〃变量 today 和 tomorrow 的类型为枚举
展开阅读全文