C语言程序设计 王娟勤 西安电子科技大学出版社
ISBN-9787560636702
自建索引, 仅供参考, 以备后查
九、位运算
C语言提供6种基本位运算功能:位取反(单目运算)、位与、位或、位异或、位左移和位右移。
(1)位运算只能是 整型(int) 或 字符型(char),不能为实数型数据。
(2)位运算是对运算量的每一个 二进制位 分别进行操作。
/// C 语言实现:无需临时变量,交换两数的值#include <stdio.h>void main() {int a = 3;int b = 4;a = a ^ b;b = a ^ b;a = a ^ b;printf("a = %d, b = %d", a, b);}/// Java 语言实现:无需临时变量,交换两数的值@Testpublic void swapIntegersWithoutAnotherVariable() {int a = 3, b = 4;System.out.format("a = %d, b = %d %n", a, b);/// do swap ///a = a ^ b;b = a ^ b;a = a ^ b;System.out.println("------------------");System.out.format("a = %d, b = %d %n", a, b);}
位段:当不需要占用完整的字节时,可以仅占用一到多个二进制位,如过程控制、参数检测或数据通信。C语言允许在结构体中以二进制位为单位指定长度,称为位段或位域
位段的使用和结构体成员一样:结构变量名.位段名但赋值时需要注意范围,不能超出对应的值域。
(1) 可以使用 %d %o %x 等格式输出。
(2) 可以用于数值表达式中,被系统自动转换为整数再计算。
(3) 不允许使用 & 取地址运算,所以 scanf("%d\n", &data.b); 是错误的。 正确方式是读入到普通变量,再赋值给位段。
十、编译预处理
预处理命令 #include,#define 和 条件编译等,由预处理程序负责完成,均以 # 开头,末尾不加";" 。C语言的编译程序不能识别它们,不能直接对它们进行编译。
#include <文件名> 或 #include "文件名"
前者 <文件名> 由预处理程序在系统标准目录下查找;后者则首先在引用被包含文件的源文件所在目录中或指定目录查找 ,若未找到,再去系统指定目录查找。
所以 <文件名> 一般用于引用系统库函数等,后者用于引用用户自定义文件。
每个 #include 仅能包含一个文件,且只能是文本文件,但可以嵌套;包含的文件可以是 .c .h 或无扩展名的文件;被包含的文件和 #include 源文件编译后成为同一个文件,可以使用被包含文件的全局变量,不用使用 extern 声明。
使用场景:多模块应用程序开发,使用头文件组织程序模块;源代码共享方式之一,可以将某些公共内容移入头文件,如常量和数据类型的定义; 做为模块对外接口(类似)使用,如在头文件中提供其它模块的函数、全局变量等。
#define 宏名称 替换文本 或 #define CALC(a,b) ((a)*(b))
宏定义是用 文本 替换程序中指定的标识符,也可以叫做 宏替换。
宏名称通常使用大写字母,“替换文件”为“宏名称”要替换为的一串字符。如: #define PI 3.141592653 (宏定义),在程序中出现的所有 PI 宏均会被替换为3.141592653 (宏展开),之后程序再进行编译。
宏替换仅仅是符号替换,不是赋值语句,因此不会做语法检查;宏名称不能有空格,行尾不用加分号;双引号中出现的宏名称不会被替换;替换的作用域为从定义位置开始到文件末尾;可以使用#undef来终止宏的作用域;宏可以嵌套互相引用,后定义引用之前定义的。
宏定义函数时,形参与实参的数据类型要一致。
宏定义函数,运行时会进方法体,需要占用CPU;而宏替换则只是影响程序编译时间。
条件编译
一、C语言程序设计概述
总体上计算机语言分为:机器语言、汇编语言 和 高级语言。
C语言在1973由美国贝尔实验室设计发布,具备高级语言和低级语言的功能。main函数是C语言程序执行的入口点,每个程序有且只能有一个main函数。常用的开发软件有:CodeBlocks、Visual C++ 6.0等。
要设计一个程序:首选要明确要处理的问题中的数据结构(数据与数据间的关系);其次要描述出对问题的处理方法和步骤(算法)。
程序:用计算机语言描述的、为解决某一问题、满足一定语法规则的语句序列。
程序设计:用某种程序语言编写这些解决问题的步骤的过程。程序设计一般可分为以下5步:
(1)分析问题; (2)确定数据结构和算法; (3)编写与编辑源程序; (4)编译、连接与运行; (5)编写程序文档。
二、C语言基础
C语言字符集:字母、数字、下划线、标点等 ASCII (American Standard Code for Information Interchange) 码表中的可视字符组成;有32个保留关键字;标识符开头只能是字母或下划线,之后可包含数字,严格区分大小写,一般不超过32个字符长度,标识符最好见名知意。
数据:对客观事物的符号表示,是所有能被输入到计算机中,且能被计算机处理的符号、数学、字符等的集合,是计算机操作对象的总称。数据是程序处理的对象,处理过程发生在内存中,不同类型的数据,其存放形式和施加的操作也有区别,因此,对数据处理之前要对其类型预先声明定义。
C语言数据类型:字符型char、整型short,int,long,unsigned、实型float,double、枚举型enum、构造类型,[],struct,union,指针类型*,&,空类型void。
整型数据:有原码、反码和补码三种形式,在计算机中以补码方式进行存储。
正数的三码合一,即正数的原码、反码和补码相等;
负数原码:符号位为1,其余位是正数对应的值,如两字节的 -10 原码为 1000 0000 0000 1010;
负数反码:除符号位不变,其余各个二进制位逐个取反,如两字节的 -10 反码为 1111 1111 1111 0101;
负数补码:负数对应的反码+1,如两字节的 -10 补码为 1111 1111 1111 0110。
取值范围(C语言): short: -2^15 ~ 2^15-1;int: -2^31 ~ 2^31-1;long: -2^31 ~ 2^31-1。CodeBlocks、VC6.0编译器中整型与长整型为4字节。
实数类型:在计算机中以指数形式存储,如 345.68 => 0.34568e3。以float类型为例,占用4字节即32位,存放 数据符号位部分、小数部分、指数正负位部分 和 指数部分。实数类型会有误差。
字符类型:占用一个字节即8位的存储空间,字符型可以当作整型来处理。
常量:整型常量如 十进制、八进制(0127)、十六进制(0x1f);实数型常量如 12.34、0.0、2.5E3、-2.89E-6;字符常量如 'x'、‘B'、'\n'等;字符串常量如 "China",尾部多出一个字节存储 '\0' 表示末尾;符号常量如 #define PI 3.141592653。
变量:根据定义类型分配存储空间,先定义后使用,没有赋值则是随机数值。
运算符:算术、关系、逻辑、赋值、位、自增自减,类型转换(type),sizeof(计算其参数在内存所占字节数) 等。
类型转换:
实数型赋值整型,直接丢弃小数部分;
整型数据赋值给实数型,以浮点形式存储;
double与float相互赋值时,是7位截取与16位的有效数字转换截取;
字符转整型,字符占1字节,整型4字节,因此是字符8位放到整型低8位中,其他位有两种情况,(1)若字符是无符号,则除低8位外全部补0 (2)若带符号的字符,高位为0则除低8位补0,若高位为1则补1;
整型转字符,截取低8位。
输入输出:程序一般包含三部分:数据输入、计算处理 和 结果输出。
C语言没有输入输出语句,通过调用标准库函数实现。
putchar(c); 输出 c 代表的字符;
c=getchar();接 收输入的字符并赋值给变量c;
scanf("%d,%f", &a, &b); 读入数据并赋值给变量 a、b,&是取地址符号。
printf("%d %d %d \n", , 1, 1);
%d 带符号十进制整型、%o 无符号八进制整型、%x 无符号十六进制整型、%u 无符号整型、%c 单个字符、%s 字符串、%f 实数(6位小数)、%e、%g
三、程序设计基本结构
结构化程序设计的基本思想是任何程序都可以由顺序、选择和循环三种基本结构通过组合、嵌套构成。
C语言中的判别式非0即为真。
四、数组
数组:包含多个数据的有序集合,可分为一维数组、二维数组和多维数组;数组下标从0开始到n-1。
C语言中,数组定义时,长度需为常量,不能为变量。
排序:一定要用循环嵌套完成,注意两个嵌套循环中循环变量的初值和终值。
逆置:a[0]与a[n-1]互换,a[1]与a[n-2]互换,a[i]与[a-i-1]互换。
无论是排序不是逆置,都要找到要处理的数据元素下标之间的关系,之后用循环进行控制。
C语言的二维数组在内存中的排列顺序是以行序优先相邻排列的,如 a[0][0], a[0][1], a[0][2], a[1][0], a[1][1], a[1][2]
字符数组 char str[100]; 字符串结尾就存放 '\0' 作为结束符号;如 char china[6] = {'C','h','i','n','a','\0'}; 或者 char a[6] = "China"; 后者会自动在末尾追加 '\0' 结束符;printf 函数遇到 '\0' 字符时结束输出;若 printf 函数一直未遇到 '\0' 字符,则会继续读取下一个内存空间,有可能引发异常。
对于数组 char str[10], txt[1000]; 可以通过 scanf("%c", &str[i]); txt[i]=getchar(); 嵌套在循环中逐个字符赋值,不常用,一般使用 scanf("%s", str) 接收不包含空格、回车或跳格的字符串;对于包含空格、回车或跳格的字符串,则需要用 gets(str); 来操作,此函数以换行符为终止输入标志,用'\0'代替换行符存储字符串数组中。
输出则可以通过 printf("%c", str[i]); putchar(txt[i]); 嵌套在循环中输出,不常用,一般使用 printf("%s", str); 打印显示;同样,若包含空格、回车或跳格则需要使用 puts(str); 来打印显示,输出后换行。