C语言基础 第12章
第12章 c语言位运算.ppt

unsigned half_carry: 1; /*半进位标志*/
unsigned negative: 1; /*减标志*/
} flags;
显然,对CPU的状态寄存器而言,使用位段类型(仅需1 个字节),比使用结构类型(需要6个字节)节省了5个 字节。
定义位段的一般格式 struct [结构类型名]
76543210
图11-1 1个字节各二进制位的编号 2.数值的原码表示 数值的原码表示是指,将最高位用作符号位(0表示正 数,1表示负数),其余各位代表数值本身的绝对值(以二 进制形式表示)的表示形式。为简化描述起见,本节约定
用1个字节表示1个整数。
例如,+9的原码是00001001
└→符号位上的0表示正数 -9的原码是10001001。
main()
{ int num, mask, i;
printf("Input a integer number: ");
scanf("%d",&num);
mask = 1<<15; /*构造1个最高位为1、其余各位为0的整数(屏蔽字)*/
printf("%d=" , num);
for(i=1; i<=16; i++)
/*案例代码文件名:AL12_1.C*/ /*程序功能:输出一个整数中由8~11位构成的 数*/ main()
{ int num, mask; printf("Input a integer number: "); scanf("%d",&num); num >>= 8; /*右移8位,将8~11位移到低4位上*/ mask = ~ ( ~0 << 4); /*间接构造1个低4位为1、其
第12章 对C语言的进一步讨论

第十二章对C语言的进一步讨论一、选择题1:Cmain()函数的参数通常是两个,第一个必须是int型,第二个必须是字符串的指针。
2:D程序的含义表明将输入的参数命令行看作字符串,将第2,4个字符串即(abcd h3)的字符个数相加,存放到len中,输出。
3:DInt*f()表示返回值是指针的函数4 :DA,B,C选项正确,D选项中,f是指向函数的指针不能这样调用5:B函数的递归调用分为直接地归调用和间接递归调用两种,其中间接递归调用自己的称为间接递归调用6:C这是函数递归调用:Fun(7)调用后等价于7-fun(5),又去调用fun(5),fun(5)又相当于5-fun(3)这时程序相当于计算7-(5-fun(3)),即7-5+fun(3), 又去调用fun(3),fun(3)又相当于3-fun(1),程序相当于计算7-5+3-fun(1),结果为2。
7:A这是函数递归调用:x的输入值为10,调用fun(10),相当于以下过程:fun(10)=10+fun(9);10+fun(9)=10+9+fun(8)10+9+fun(8)= 10+9+8+fun(7)10+9+8+fun(7)= 10+9+8+7+fun(6)10+9+8+7+fun(6)= 10+9+8+7+6+fun(5)..........10+9+8+7+6+5+4+3+2+fun(1)= 10+9+8+7+6+5+4+3+2+1;结果为558:DA项:预处理命令不一定要放在程序开头,B:一行只能有一条预处理命令。
C 宏名可以小写,但一般用大写进行区别,D正骨俄9:Cf(x)为代参数的宏,f(8)相当于8*8,f(4)相当于4*4,同样f(4+4)相当于4+4*4+4,f(2+2) 相当于2+2*2+2所以结果是4,3.10:AF(X,Y) 为代参数的宏,F(a++,b++)相当于(a++)*(b++),结果为1211:M1+M2相当于(N*3)+(N*2),而N相当于5所以结果为25。
《C语言程序设计》(第2版)苏小红-13章 12

2021/7/31
40/60
struct sample {
short i; char ch; float f; };
union sample {
short i; char ch; float f; };
2021/7/31
共用体
【例12.8】
printf("%d\n", sizeof(struct sample));
Before function call:1999/04/23 After function call:2000/05/22
指针作函数形参 实参必须为地址值
2021/7/31
33/60
struct date
{
int year; int month;
结构体变量
int day; };
作函数返回值
struct date Func(struct date p)
2021/7/31
【例12.3】利用 结构体数组计 算每个学生的 平均分
25/60
结构体指针的定义和初始化
如何定义指向结构体变量的指针?
pt STUDENT stu1; STUDENT *pt; pt = &stu1;
等价于
STUDENT *pt = &stu1;
stu1 成员1 成员2 成员3 成员4
i ch
f
8个字节
printf("%d\n", sizeof(union sample));
0x0037b00
cfih
4个字节 41/60
共用体
sizeof(union number)取决于占空间最多的那个成员 变量
同一内存单元在每一瞬时只能存放其中一种类型的成员 起作用的成员是最后一次存放的成员,不能作为函数参数 不能进行比较操作,只能对第一个成员初始化
编程语言基础——C语言(第四版)陈琳课后题答案复习进程

for(i=2;i<=20;i++)
s=s+s*i;
printf("s=%f",s);
getch();
}
14、输入一个数字a和一个数字n,s=a+aa+aaa+aa…a,最后一项为n个a。计算并输出s的值。
#include<stdio.h>
main()
{inta,n,i;
floatsum=0,sun=0;
{intsign=1,i;
floats=0;
for(i=1; ;i+=2)
{ s=s+1.0/(i*sign);
sign=-sign;
if(1.0/i<0.0001) break;
}printf("PI=%f",4*s);
getch();
}
12孙悟空在大闹蟠桃园的时候第一天吃掉了所有桃子总数的一半多一个第二天又将前一天剩下的桃子吃掉了一半多一个以后每天吃掉前一天剩下的一半多一个到第天时准备吃的时候只剩下一个桃子
编程语言基础——C语言(第四版)陈琳课后题答案
第三章
五、编程
1、从键盘上输入一个整数,判断并输出它是奇数还是偶数。
2、从键盘上输入一个浮点数,输出它的绝对值。
3、从键盘上输入a、b、c三个整数,输出其中的最小数。
4、从键盘上输入a、b、c三个数,将它们按从小到大的顺序输出。
#include<stdio.h>
main()
{
inta,b,c,t;
scanf("%df(a>b) t=a,a=b,b=t;
if(b>c) t=b,b=c,c=t;
数据结构(C语言版)9-12章练习 答案 清华大学出版社

数据结构(C语言版)9-12章练习答案清华大学出版社9-12章数据结构作业答案第九章查找选择题1、对n个元素的表做顺序查找时,若查找每个元素的概率相同,则平均查找长度为( A )A.(n+1)/2 B. n/2 C. n D. [(1+n)*n ]/2 2. 下面关于二分查找的叙述正确的是 ( D )A. 表必须有序,表可以顺序方式存储,也可以链表方式存储B. 表必须有序且表中数据必须是整型,实型或字符型 C. 表必须有序,而且只能从小到大排列 D. 表必须有序,且表只能以顺序方式存储3. 二叉查找树的查找效率与二叉树的( (1)C)有关, 在 ((2)C )时其查找效率最低 (1): A. 高度 B. 结点的多少 C. 树型 D. 结点的位置(2): A. 结点太多 B. 完全二叉树 C. 呈单枝树 D. 结点太复杂。
4. 若采用链地址法构造散列表,散列函数为H(key)=key MOD 17,则需 ((1)A)个链表。
这些链的链首指针构成一个指针数组,数组的下标范围为 ((2)C) (1) A.17 B. 13 C. 16 D. 任意(2) A.0至17 B. 1至17 C. 0至16 D. 1至16判断题1.Hash表的平均查找长度与处理冲突的方法无关。
(错) 2. 若散列表的负载因子α<1,则可避免碰撞的产生。
(错)3. 就平均查找长度而言,分块查找最小,折半查找次之,顺序查找最大。
(错)填空题1. 在顺序表(8,11,15,19,25,26,30,33,42,48,50)中,用二分(折半)法查找关键码值20,需做的关键码比较次数为 4 .算法应用题1. 设有一组关键字{9,01,23,14,55,20,84,27},采用哈希函数:H(key)=key mod7 ,表长为10,用开放地址法的二次探测再散列方法Hi=(H(key)+di) mod 10解决冲突。
要求:对该关键字序列构造哈希表,并计算查找成功的平均查找长度。
C语言新教材PPT课堂课件第12章位运算

1011=11 (3)主要用途:将1个数的某(些)位置1,其余各位不变。
3.按位异或── ^ (1)格式:x^y (2)规则:对应位相同时为0,不同时为1:3^9=10。 例如,3^9=1: 0011
^ 1001
────
1010=10 (3)主要用途:使1个数的某(些)位翻转(即原来为1的位变为0,为0 的变为1),其余各位不变。 4.按位取反── ~ (1)格式:~x (2)规则:各位翻转,即原来为1的位变成0,原来为0的位变成1: 在IBM-PC机中,~0=0xffff,~9=0xfff6。 (3)主要用途:间接地构造一个数,以增强程序的可移植性。 5.按位左移── << (1)格式:x<< 位数 (2)规则:使操作数的各位左移,低位补0,高位溢出:5<<2=20。
程序运行情况:
Input a integer number:1000 ←┘
result=0x3
程序说明:~ ( ~0 << 4)按位取0的反,为全1;左移4位后,其低4位为0,其 余各位为1;再按位取反,则其低4位为1,其余各位为0。这个整数正是我们 所需要的。
[例12.2] 从键盘上输入1个正整数给int变量num,按二进制位输 出该数。
printf("Input a integer number: ");
scanf("%d",&num);
num >>= 8;
/*右移8位,将8~15位移到低8位上*/
mask = ~ ( ~0 << 4);/*间接构造1个低4位为1、其余各位为0的整数*/
printf("result=0x%x\n", num & mask); }
计算机二级C语言第12章 编译预处理与动态存储分配

正确答案:D 【解析】ANSI C标准规定malloc函数的返回值类型为void *,要是p指向double类型的动态存储单 元,需要使用强制类型转换double *,本题答案为D。
假设short int型数据占2字节、float型数据占4字节存储单元,则以下程序段将使Pi指向一个short int类型的存 储单元,使pf指向一个float类型的存储单元: short int *pi; float * pf; pi = ( short * ) malloc ( 2 ); pf = ( float * ) malloc(4); malloc函数返回的指针为void *(无值型),在调用函数时,必须利用强制类型转换将其转成所需的类型。上面的 程序段中,调用malloc函数时括号中的*号不可少,否则就转换成普通变量类型而不是指针类型了。
C语言中还有一种称作“动态存储分配”的内存空间分配方式:在程序执行期间需要空间来 存储数据时, 通过“申请”得到指定的内存空间;当有闲置不用的空间时,可以随时将其释放,由系统另作他用。
malloc函数
函数的调用形式为:malloc ( size)。
该函数包含在头文件stdlib.h里,返回值的类型为void *, malloc函数用来分配size个字节的存储区,返回一 个指向存储区首地址的基类型为void的地址。若没有足够的内存单元供分配,函数返回空(null)。
目录页
CONTENTS PAGE
计算机二级C语言 第12章 编译预处理与动态存储分配
所谓“编译预处理”就是在C编译程序对C源程序进行编译前,由编译预处理程序对这些编译预处理命 令行进行处理的过程。 预处理命令行必须在一行的开头以“#”号开始,每行的末尾不得用“;”号结束。 这些命令行的语法与C语言中其他部分的语法无关。根据需要,命令行可以出现在程序的任何一行的开 始部位,其作用一直持续到源文件的末尾。 重点是:#define 和 #include 命令行
C21第12章 位运算

位操作符
C语言提供的位操作符有按位与&、按位或|、按位异或 语言提供的位操作符有按位与& 按位或|、按位异或 |、 ^、取反~、左移<<和右移>>。 取反~ 左移<<和右移>>。 <<和右移>> 位操作符的操作数仅限整型(字符型), 位操作符的操作数仅限整型(字符型), 为简明下面示例中位操作符的操作数多为字符型。 为简明下面示例中位操作符的操作数多为字符型。
结构体中的结构体
结构体struct bitfield虽然有三个整型成员a,b,c,但 虽然有三个整型成员a,b,c, 结构体struct bitfield虽然有三个整型成员a,b,c,但 它们存储空间的长度只有2 它们存储空间的长度只有2位、4位和2位。 位和2 特别强调,整型成员a 特别强调,整型成员a、b、c虽然位数不多,但仍为有 虽然位数不多, 符号数, 符号数,即a、c的取值范围为-2至1,b的取值范围为-8至 的取值范围为的取值范围为7。
新编C语言程序设计教程
清华大学出版社
周二强
zeq@ 软件学院
计算机科学与工程系
配套视频: 配套视频: 博客: 博客:/stunt
第12章 位运算 12章
12. 12.1 位操作符
12.1.1 按位与操作符& 12.1.2 按位或操作符| 12.1.3 异或操作符^ 12.1.4 取反操作符~ 12.1.5 左移操作符<< 12.1.6 右移操作符>>
12. 12.2 位运算示例 12. 12.3 位段
位运算
位运算是指按二进制位进行的运算, 位运算是指按二进制位进行的运算,实际上就是直接对整数 在内存中的二进制位进行操作。 在内存中的二进制位进行操作。 考虑这样的问题:编程控制编号为0 考虑这样的问题:编程控制编号为0至7的八盏灯的开关。 的八盏灯的开关。 可以定义一个长度为8的短整型数组变量a。 可以定义一个长度为8的短整型数组变量a 可以定义一个无符号的字符型变量c 可以定义一个无符号的字符型变量c。 如果c的值为128( 0000), ),则 号灯亮,其余灯灭; 如果c的值为128(1000 0000),则7号灯亮,其余灯灭;为 128 192时 0000), ),则 号和7号灯亮,其余的灭。 192时(1100 0000),则6号和7号灯亮,其余的灭。 但是要改变某盏灯的状态而不影响其他灯的,却并非易事。 但是要改变某盏灯的状态而不影响其他灯的,却并非易事。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序如下: #include "stdio.h" #define PRIME for(i=2; i<n; i++)\ if(n%i==0) prime=0; /* 宏定义 */ main() { int n, i, prime, num, k=0;
printf("Enter a number:"); scanf("%d", &num); for(n=2; n<num; n++) { prime=1; PRIME; /* 宏替换 */ if(prime) {
return;
}
在以上两个例子中, 宏的形参都用圆 括号括起来了。这不是绝对必要的。例如, 例12.1.5中宏定义也可以写成下面的形式:
#define PI 3.14159 #define S(r) PI*r*r #define L(r) 2*S(r)/r
但是,对于实参为表达式的情况,上 面参数不带括号宏定义,可能会给出错误 的计算结果。 设有 r=3.0. a=1.0. b=2.0 根据上面的宏定义,则有: S(r)=s(3)=28.27431, L(r)=l(3)18.84954 而参数为表达式时, S(a+b)=S(3)=7.14159, L(a+b)=12.28318
使用包含文件的结果,本例的源程序 由四个文件组成:三个头文件和一个主程 序文件。经过编译预处理后,三个头文件 被“包含”到主程序文件中,成为程序的 组成部分。图12.1给出本例包含文件处理 的情形。
不带参数的宏定义的一般形式为: #define 宏名 字符序列 宏定义的作用是,在对源程序编译之前, 将程序中出现的所有的宏名用对应的字符序 列来代替。这种替换称宏替换或宏引用。
不带参数宏替换,通常的用途是,用宏 名定义程序中的常量,如: #define FALSE 0 #define WORDS "Turbo C++"
第12章
C语言的预处理器
12.1 宏定义和宏替换 12.2 文件包含 12.3 条件编译
编译预处理命令不是C语言的语句, 它的作用只是告诉(命令)编译系统,在 编译源程序之前对源程序进行某种预加工, 而后再进行编译。所有的编译预处理命令 都是以符号“#”开头,末尾不加分号。预 处理命令可以用在程序的任何地方。 本章主要介绍以下的C语言的编译预 处理命令:
通常把宏定义写在文件的开始部分,函 数的外面,或写在包含文件(#include)中。
例12.1.1 宏定义与宏替换应用。 程序定义了一个宏名:SIZE,用来定义 数组str的容量。程序中还使用了系统定义的 一个宏名NULL(空字符),用于检查字符 型数组中字符串的结束符。程序的功能是, 将用户输入的字符串存入数组str,然后,变 成大写字母将其输出。 程序如下:
printf("%4d", n); if(!(++k%5)) printf("\n"); } } printf("\n"); return 0; } 宏定义可以嵌套进行。也就是说,在定 义宏时,可以引用已有定义的宏名,实现层 层替换。例如:
#define PI 3.14159 #define S PI*r*r #define L 2*S/r 其中定义S时,使用了已定义的PI;定义L 时,使用了已定义的S。 例12.1.3 应用上面嵌套结构的宏定义, 计算圆的面积和周长。
下面是一个带参数的宏定义的例子: #define MAX(a,b) ((a)>(b))?(a):(b) 例12.1.5 利用上面的带参数的宏定义, 编写求两个数中的较大者的程序。 程序如下:
#include "stdio.h" #define MAX(a,b) /* 宏定义 */ main() { int a, b, max;
#include"stdio.h" #define PRN printf #define D "%d\n" #define F "%f\n" #define S "%s\n" main() {
/* 定义宏 */
int i=10; float f=20.0; char ch[]="string.";
但它们的工作的机理是完全不同的,在 概念更上不要混淆。它们之间的不同,体现 在以下四个方面。
( 1 )函数调用时,要计算实参并向形参 传送。而宏中的参数,只是进行简单的替 换。既没有向形参拷贝数据,也没有传送 参数地址。
(2)函数中的实参和形参有确定数据类 型,并且两者是一一对应的。宏名没有 数据类型。它只是个符号。其参数也只 是个符号而已。引用时,代入指定的字 符。宏定义的字符串可以是任何数据类 型。 (3)宏是在编译时进行替换的,不分配 内存空间。而函数调用是在程序运行时 处理的,并分配相应的临时的内存空间。
显然结果是错的。后者因为实参没有括 号,所以计算过程是: S(a+b)=3.14159×1+2×1+2=3.14159+2+2=7.1 4159 如果在宏定义里给参数r加上括号,则计 算过程是: S(a+b)=3.14159×(1+2)×(1+2)=3.14159×3× 3=28.27431 结果是正确的。
程序输出举例(带下划线的数据是用 户输入的): Enter r: 1 r=1.000000 S=3.141590 L=6.283180
需要注意的是,这个程序的语句 printf("r=%f\tS=%f\tL=%f\n",r,S,L);
中,两次出现S和L:在格式字符串中出现 了S和L,在输出项列表中也出现了S和L。 C语言规定,宏名出现在字符串中时,将 不看作是宏名,因而也不做宏替换。所以 才有如上所示的输出。 例12.1.4 将宏用于输出语句中的例子。
PRN(D,i); PRN(F,f); PRN(S,ch);
return;
}
程序的运行结果为:
10 20.000000 string.
12.1.2 带参数的宏定义和引用
带参数的宏定义的一般形式为: #define 宏名(形参表) 字符序列 程序中引用宏名时,写入实参,就像函数调 用那样。 定义了宏名后,编译系统在开始编译源程序 前,把程序中引用的宏替换成相应的一串符号, 然后进行编译。在替换过程中用实参代替形参。
为了避免出现上述可能出现的错误, 在定义带参数的宏时,最好给参数加上圆 括号。
12.1.3 取消宏定义
#undef命令用于取消先前已定义的宏 名。其一般形式为:
#undef 宏名
12.2
文 件 包 含
所谓文件包含,是指一个源文件将另一 个源文件包含到自己的文件之中。 文件包含命令有如下两种形式: #include <文件名> #include "文件名" 包含命令的功能是,在编译预处理时,用命 令指定的文件名的文本内容来替代该命令, 使包含文件的内容成为本程序的一部分。
#include "stdio.h" #define SIZE 80 main() { int i; char str[SIZE];
/* 宏定义SIZE */
/* 宏SIZE的引用 */
printf("Enter a string: "); gets(str);
for(i=0; str[i]!=NULL; i++) /* 宏NULL的引用 */ printf("%c", toupper(str[i])); printf("\n"); return; }
max = MAX(a,b); printf("The manximum num = %d", max);
写成如下的一个语句: printf("The manximum num = %d", MAX(a,b)); 其效果是一样的。 我们看到,这种宏替换很象调用函数。 例如:
max=MAX(a,b); MAX(a,b);
如果文件名用了双引号,则首先查找 当前目录,若找不到该文件,则查找命令 行定义的其他目录。如果仍找不到该文件, 则查找系统定义的标准目录。 如果文件名使用了尖括号,则编译器 首先查找命令行指定的目录;如果找不到 该文件,则查找标准目录,不查找当前工 作目录。
例12.2.1 给定半径,计算圆的周长和圆 面积。 为了展示利用文件包含命令处理多文件 程序的设计方法,我们设计三个如下的包含 文件,或称头文件: 头文件1名为myin1.h。文件内容包含如 下两条: #include<stdio.h> #define PI 3.14159 /* 宏定义 PI */
程序如下: #include"stdio.h" #define PI 3.14159 #define S PI*r*r #define L 2*S/r main() {
float r; printf("Enter r:"); scanf("%f",&r); printf("r=%f\tS=%f\tL=%f\n",r,S,L); return; }
#include"myin2.h" main() { float x=3.0; printf("L=%f\n",lr(x)); printf("S=%f\n",sr(x)); }
这里在文件myin3.h和文件myin2.h中 定义的两个函数是嵌套的。即函数lr()的定 义中引用着函数sr()。函数sr()定义中还引 用着头文件myin1.h中的宏定义PI。因此, 在主函数文件中,三个包含命令的文件书 写顺序,必须是先myin1.h,然后myin3.h, 最后是myin2.h。