第 20讲位运算位段枚举变量大型程序开发
2
例 1:读程序功能?
#include<stdio.h>
void main()
{
short a,b;
printf("请输入一个十六进制数,\n");
scanf("%x",&a);
b=(a & 0xFF00)>>8;
printf("result=%x\n",b);
}
输出一个整型数据的高 8位
位运算符,转换成二进制再运算
& | << >>
思考题:如何编写一个函数,求出一个整数的任意一位。int nth_bit(int x,int n)//求 x的第 n位
{
return ( x & (int)pow(2,n) )>>n;
}
3
位段
struct birthday
{
unsigned int day:5;
unsigned int month:4;
unsigned int year:13;
}a;
当为变量 a分配内存空间时,按后边指定的二进制位数分配。即 a共获得 5+ 4+ 13=
24bits/8=3bytes空间,
比不指定具体位数少用了 3个字节的空间,这种方法可以有效地节省内存。
4
例 3:袋中有红、白、蓝三种颜色的球,有放回地取出时,结果都是?
#include<stdio.h>
#define COLORNUM 3
char *col[COLORNUM]={"red","write","blue"};
void main()
{
int i,j,k;
enum COLOR color;
printf("result:\n");
for(i=0;i<=2;i++) //从 0到 2穷举
for(j=0;j<=2;j++) //从 0到 2穷举
for(k=0;k<=2;k++) //从 0到 2穷举
{
printf("%s\t%s\t%s\t---\t",col[i],col[j],col[k]);
printf("%d\t%d\t%d\n",i,j,k);
}
}
5
方法二
#include<stdio.h>
#define COLORNUM 3
enum Color{red,write,blue};
typedef enum Color COLOR;
char *col[COLORNUM]={"red","write","blue"};
void main()
{
COLOR i,j,k;
printf("result:\n");
for(i=red;i<=blue;i++) //从 red到 blue穷举
for(j=red;j<=blue;j++) //从 red到 blue穷举
for(k=red;k<=blue;k++) //从 red到 blue穷举
{
printf("%s\t%s\t%s\t---\t",col[i],col[j],col[k]);
printf("%d\t%d\t%d\n",i,j,k);
}
}
定义 枚举类型 enum Color
同时指定这种类型的变量可以取得的值,其中的每一个值其实就是一个符号常量,
如果不指定他们的值,默认是 0,1,2。。。
定义 枚举类型的 变量
对枚举变量进行穷举
好处:直观
6
定义的枚举常量往往可直接使用
#include<stdio.h>
#define COLORNUM 3
enum {red,write,blue};
char *col[COLORNUM]={"red","write","blue"};
void main()
{
int i,j,k;
printf("result:\n");
for(i=red;i<=blue;i++) //从 red到 blue穷举
for(j=red;j<=blue;j++) //从 red到 blue穷举
for(k=red;k<=blue;k++) //从 red到 blue穷举
{
printf("%s\t%s\t%s\t---\t",col[i],col[j],col[k]);
printf("%d\t%d\t%d\n",i,j,k);
}
}
定义 枚举类型 enum
没有指明 Color 时,一般不使用这个类型来定义变量,
只是为了直接使用后边定义的符号常量
定义 整型 变量
直接用枚举 常 量
7
多文件程序
程序文件模块
为什么? 当程序较大时,可以把程序分别保存为几个,c文件,或者每个程序员编写一部分函数,
这些函数保存在一个,c文件,最后再构成完整的程序 。
其中的每一个,c文件称为 程序文件模块 。
整个程序只允许有一个 main()函数
组成结构:函数- >文件- >程序
大程序-若干程序文件模块
各程序文件模块分别编译,再连接
8
问题:如何把若干程序文件模块连接成一个完整的可执行程序?
文件包含方法一:包含自己编写的,c文件
9
例如,5个函数分别存储在 2个,C文件上,
要求通过文件包含把它们联结起来。
文件模块名,p r o g 1,c
# i n c l u d e,p r o g 2,c,
i n t m a i n ( v o i d )
{ i n t s e l ;
w h i l e ( 1 ){
s c a n f("% d ",& s e l );
c a l (s e l ) ;
}
}
v o i d c a l (i n t s e l )
{ ……
}
文件模块名,prog 2.c
do u ble v o l_b all ( )
{ ……
}
do u ble v o l_c y li nd ( )
{ ……
}
do u ble v o l_c on e ( )
{ ……
}
编译连接后包含的内容
double vol _ba ll ( )
{ ……
}
double vol _c y lind ( )
{ ……
}
double vol _cone ( )
{ ……
}
int ma in( voi d )
{
int s el ;
w hile (1 ){
sca nf("% d ",&sel );
cal (se l );
}
}
voi d c al(i nt s el)
{ ……
}
10
方法二
新建一个项目文件
打开所有的,c文件,分别编译
再连接
11
外部变量( extern)
在某个程序文件模块中定义了全局变量
该全局变量可以在整个程序的所有文件模块中起作用
在其他模块中如果要使用该全局变量,必须将它声明为外部变量说明这是一个在其他模块中定义的全局变量
12
int x;
void main()
{………
}
文件名 file1.c
extern x;
/*使用 file1.c中的全局变量 x */
f1( )
{
………
}
文件名 file2.c扩大全局变量的作用域
13
static int x;
void main()
{………
}
使全局变量只限于本文件引用,而不能被其他文件引用文件名 file1.c
extern x;
/*使用 file1.c中的全局变量 x */
int f1( )
{
………
}
文件名 file2.c无法引用静态全局变量
14
函数与程序文件模块
外部函数
函数能够被程序中的其他程序文件模块调用
在其他文件模块中调用该函数前,声明为外部函数
extern 函数类型 函数名 (参数表说明 );
extern int f1();
int main(void)
{ ………
f1( );
………
}
文件名 file1.c
int f1( )
{
………
}
文件名 file2.c
调用另一模块中的函数
15
extern int f1();
int main(void)
{ ………
f1( );
………
}
static int f1( )
{
………
}
内部函数使函数只能在本程序文件模块中被调用
static 函数类型 函数名 (参数表说明 );
文件名 file1.c 文件名 file2.c
无法调用
16
编程风格 1
数据风格
尽量定义局部变量
函数之间利用形参和返回值传递数据
选择适当的数据类型和数据结构,尽量避免使用指针,适当采用符号常量
算法风格
算法要简洁,明了,少使用技巧; 如 a = a + b;
b = a – b; a = a – b; 完全可以用 temp = a; a
= b; b = temp; 表示
尽量避免使用多重循环嵌套或条件嵌套结构;
充分利用库函数和其它自定义函数 ;
要注意浮点运算的误差
17
编程风格 2-书写风格
使用足够的注释
包括文件名,变量用途,函数功能、形参、返回值,
数据结构,算法技巧,其它让人误解或不易理解的地方
语句括号风格
标识符风格
SearchByName()和 search_by_name()
Float intresting_f;(表明数据类型 )
语句和表达式风格
使用冗余的圆括号明确计算顺序,使表达式易读 ;
在条件或循环结构中尽量避免采用 "非 "条件测试 ;
尽量避免复杂条件测试 ;
语句和表达式要清晰、易读。
18
课程已全部结束,剩下的时间请大家认真复习,
准备考试。预计考试时间,15周周末
考试形式:上机 (编程题,三道左右,语法正确,
但结果不正确的只能给 2/3的分,语法错误的从总分的 2/3向下减分 )
答疑方式:
邮件答疑 (将问题发至 xiejb@cqupt.edu.cn),注明提问
旧行政楼 206(数理学院二楼,电话 62461048)
有重要通知我会及时在网上公布,请随时关注我的个人主页 http://cs.cqupt.edu.cn/xiejb
谢谢大家一个学期的配合。
希望大家能够 活学活用 C语言 。
19
1,Kernighan和 Ritchie 风格(也称贝尔实验室工业编程风格):
While (bCondition){
if(GetFreeMemory()>500){
AdvanceRecord();
ReadRecord();
} /* if */
else{
ReportError(LOW_MEMRY);
FreeGarbage();
} /* else */
}/* while */
2,Allman风格 (也称 student style——学生风格 ):
While (bCondition)
{
if(GetFreeMemory()>500)
{
AdvanceRecord();
ReadRecord();
} /* if */
else
{
ReportError(LOW_MEMRY);
FreeGarbage();
} /* else */
}/* while */
3,Whitesmitions风格:
While (bCondition)
{
if(GetFreeMemory()>500)
{
AdvanceRecord();
ReadRecord();
} /* if */
else
{
ReportError(LOW_MEMRY);
FreeGarbage();
} /* else */
}/* while */
语句括号风格:
20