一、位运算
指针运算和位运算和适合于编写系统软件,是c语言的重要特色。在计算机用于检测和控制领域中,要用到位运算的知识。
1、按位与(&)
作用:(1)清零
(2)取一个数中某些指定位
(3)要想将哪一位保留下来,就与一个数进行&运算,此数在改位取1.
2、按位或(|)
作用:常用来对一个数据的某些位定值位1.
3、异或(^)异号则为1
作用:
(1)使特定位翻转:要使哪几位翻转就将其与进行异或运算的该几位置1即可,这是因为原数中值为1的位与1进行异或运算得0,原数中的位值0与1进行异或运算的结果得1.
(2)与0异或,保留原值。
(3)交换两个数,不用临时变量。
假如 a = 3 ,b = 4,想将a和b的值互换,可以用以下赋值语句实现:
a = a^b; b = b^a; a = a^b;
4、取反(~)
5、左移(<<):用来将一个数的个二进位全部左移若干位。a = a<<2.
6、右移(>>):功能类似。在右移时,需要注意符号位问题,
对无符号数,右移时左边高位移入0,
对于有符号的值,如果原来符号位为0,则左边也是移入0
如果原来符号位为1,则左边移入0还是1,要取决于所使用的计算机
系统。
7、位运算赋值运算符:位运算符与赋值运算符可以组成复合赋值运算符号。
如:&=,|=,>>=,<<=。
8、不同长度的数据进行位运算,系统会将二者按右端对齐。
二、位段
c语言允许在一个结构体中以位为单位来指定其成员所占内存长度,这种以位为单位的成员称为“位段”,利用位段能够用较少的位数存储数据。
如:
struct packed_data
{
unsigned a:2;
unsigned b:6;
unsigned c:4;
unsigned d:4;
int i;
}data;
其中a、b、c、d分别占2位,6位,4位,4位。
对位段中的数据引用的方法:
data.a = 2;
data.b = 7;
data.c = 9;
注意:
(1)位段成员的类型必须指定为unsigned int 类型;
(2)一个位段必须存储在同一存储单元中;
(3)可以定义无名字段;
unsigned a:2;
unsigned :2;(这两位空间不用)
unsigned b:3;
(4)位段可以用整型格式输出;
(5)位段可以在数值表达式中引用,它会被系统自动地转换成整型数。
三、结构体
1、定义:在一个组合项目中包含若干个类型不同的数据项,c语言允许用户自己指定这样一种数据结构,称为结构体。但是c语言没有提供这种现成的数据类型,因此用户要在程序中建立所需要的结构体数据类型,然后用此类型去定义结构体变量。
如:struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
};
注意不要忽略最后的分号“;”。
2、结构体类型变量的定义方法:
(1)先声明结构体类型再定义变量名:如 struct student student_1,student_2;
(2)在声明结构体类型的同时定义变量名:
如:struct student
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student_1,student_2;
(3)直接定义结构类型变量
如:struct
{
int num;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student_1,student_2;
3、关于结构体类型,有几点说明:
(1)类型与变量是不同的概念,不要混同。只能对变量赋值,存取或者运算,而不能对一个类型赋值、存取或运算;在编译时,对类型是不分配空间的,只对变量分配空间;
(2)对结构体中的成员可以单独使用;
(3)成员也可以是一个结构体变量。
4、结构体变量的引用:
结构体变量名.成员名;如:student_1.num,student_1.name。
5、结构体变量的初始化
可在定义时指定初始值:
如:struct student
{
int NUM;
char name[20];
char sex;
int age;
float score;
char addr[30];
}student_1 = {89031,"Li Lin",'M',"123 Beijing Road"};
6、结构体数组
(1)概念:一个结构体变量可以存放一组数据,如果有10个学生的数据需要参加运算,显然应该使用数组。结构体数组与数值型数组不同之处在于每个数组元素都是一个结构体类型的数据,它们都包括各个成员项。
(2)定义结构体数组
struct student stu[3];
(3)初始化
7、指向结构体类型数据的指针
指向结构体变量的指针:
一个结构体变量的指针就是该变量所占的内存段的起始地址,可以设一个指针变量来指向一个结构体变量,此时该指针变量的值是结构体变量的起始地址。
定义指向结构体变量的指针:struct student *p;
使用指针来读取结构体元素:(*p).num,(*p).name,(*p).sex。
在c语言中,为了使用方便和直观,可以把(*p).num写成 p—>num,其中—>称为指向运算符。
以下三种形式等价:
(1)(*p).num;
(2)student_1.num;
(3)p—>num;
指向结构体数组的指针:
用结构体变量和指向结构体的指针作为函数参数
(1)用结构体变量的成员作参数,和普通变量作参数是一样的用法,属于“值传递”;
(2)用结构体变量作实参,采取的是“值传递”的方式,将结构体变量所占的内存单元的内容全部顺序传递给形参;
(3)用指向结构体变量的指针作为实参,将结构体变量的地址传给形参。
四、共用体
1、概念:有时需要使几种不同类型的变量存放到同一内存单元中,这种使几个不同变量共占同一内存的结构,称为共用体类型的结构
2、一般形式:
union data
{
int i;
char ch;
float f;
}a,b,c;
3、共用体变量的引用方式:
a.i, a.ch , a.f ;
4、共用体类型数据的特点:
(1)在每一时刻只能存放其中一种数据类型,而不是同时存放几种;
(2)共用体变量中起作用的成员是最后一次存放的成员;
(3)共用体变量的地址和它的各个成员的地址是同一地址;
(4)不能对共用体变量名赋值,也不能在定义共用体变量时对它初始化;
(5)不能把共用体变量作为函数参数,但可以使用指向共用体变量的指针。
五、枚举类型
1、概念:如果一个变量只有几种可能的值,可以定义位枚举类型。
2、声明枚举类型:enum weekday(sun,mon,tue,wed,thu,fri,sat);
3、定义变量:enum weekday workday,week_end;
也可直接定义枚举变量:enum(...)workday,week_end;
4、说明:
(1)在c编译中,对枚举元素按照常量处理,如sun = 0,mon = 1;
(2)枚举元素作为常量,它们是有值的,c语言编译时按定义时的顺序使它们的值为0,1,2,...
(3)枚举值可以用来做判断比较
如:if(workday == mon)...
if(workday > sun)...
(4)一个整数不能直接赋给一个枚举常量
如:workday = 2 是不对的
应先进行强制类型转换才能赋值:
workday = (enum weekday)2;