共用体
定义和理解
在C语言中,允许几种不同类型的变量存放到同一段内存单元中,也就是使用覆盖技术,几个变量互相覆盖。这种几个不同的变量共同占用一段内存的结构,被称为共用体类型结构,简称共用体。一般定义形式为:
union 共用体名
{
数据类型 成员名 1;
数据类型 成员名 2;
......
数据类型 成员名 n;
}变量名表列;
2,使用
不能直接引用共用体变量,而只能引用共用体变量中的成员。引用方法如下:
共用体变量名.成员名
3,共用体变量的特点和注意点
(1)同一个内存段可以用来存放几种不同类型的成员,但是在每一瞬间只能存放其中的一种,而不是同时存放几种。
(2)共用体变量中起作用的成员是最后一次存放的成员。
例子:
#include<stdio.h>
union INFO
{
int a;
int b;
int c;
};
int main()
{
union INFO A;
A.a=1;
A.b=2;
A.c=3;
printf("a:%d\n",A.a);
printf("b:%d\n",A.b);
printf("c:%d\n",A.c);
return 0;
}
结果:
a:3
b:3
c:3
(3)不能在定义共用体变量的时候进行初始化。
(4)共用体变量可以出现在结构体定义中,可以使用共用体数组。
结构体变量也可以出现在共用体中,数组中也可以出现共用体变量。
C语言typedef用法
定义
typedef 已定义的类型 新的类型;
2,作用
使用类型说明语句typedef定义新的类型来代替已有的类型。
tvpedef语句通常用于定义结构体变量
例子:
#include<stdio.h>
#include<string.h>
typedef struct _INFO
{
int num;
char str[256];
}INFO;
//typedef还可以用于替换指针结构体
typedef struct _INFO
{
int num;
char str[256];
}INFO,*INFO2;
int main()
{
struct _INFO A;
INFO B; //通过typedef重命名后的名字INFO与struct _INFO完全等价!
A.num = 2014;
strcpy(A.str,"Welcome to dotcpp.com");
B=A;
printf("This year is %d %s\n",A.num,A.str);
printf("This year is %d %s\n",B.num,B.str);
return 0;
}
C语言enum枚举类型
1,定义
enum 枚举名 {枚举元素1,枚举元素2,……};
2,作用
它可以让代码更简介、更易读
这样就会定义了一个“枚举名”的枚举类型,其值为枚举元素1(即0)、枚举元素2(即1)...(依次递增)。(默认第一个为0,要想修改要给某一个枚举类型的变量赋值)
例子
#include<stdio.h>
int main()
{
enum Week{MON, TUE, WED, THU, FRI, SAT, SUN};
enum Week A=WED;
printf("%d\n",A);
return 0;
}
//当THU不赋值时A=3
//当给MON赋值5时,输出A为8
C语言实现文件读写
1,打开文件
用fopen函数来实现,这一步作用主要是建立程序和文件的关系,获取文件在内存中的文件指针,方便后面两步。
该函数需要两个字符串类型的参数,第一个是文件名,既要操作的文件对象。第二个是打开方式,
例子
FILE *fp;
fp=fopen("d:\\abc.dat","r")
//后面通过fp指针开始读文件
函数的返回值则表示打开成功后的文件指针,格式为FILE类型,是一个结构体类型,供后面使用,如果打开失败,则返回NULL。
打开方式表
参数 | 作用 |
r | 以只读方式打开文件,该文件必须存在。 |
r+ | 以读/写方式打开文件,该文件必须存在。 |
rb+ | 以读/写方式打开一个二进制文件,只允许读/写数据。 |
rt+ | 以读/写方式打开一个文本文件,允许读和写。 |
w | 打开只写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。 |
w+ | 打开可读/写文件,若文件存在则文件长度清为零,即该文件内容会消失;若文件不存在则创建该文件。 |
a | 以附加的方式打开只写文件。若文件不存在,则会创建该文件;如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF 符保留)。 |
a+ | 以附加方式打开可读/写的文件。若文件不存在,则会创建该文件,如果文件存在,则写入的数据会被加到文件尾后,即文件原先的内容会被保留(EOF符不保留)。 |
wb | 以只写方式打开或新建一个二进制文件,只允许写数据。 |
wb+ | 以读/写方式打开或新建一个二进制文件,允许读和写。 |
wt+ | 以读/写方式打开或新建一个文本文件,允许读和写。 |
at+ | 以读/写方式打开一个文本文件,允许读或在文本末追加数据。 |
ab+ | 以读/写方式打开一个二进制文件,允许读或在文件末追加数据。 |
2,读写文件
读写文件分为fprintf、fscanf或者fwrite、fread或者fputs、getss等多组函数来实现。
1,fprintf
该函数是一个格式化写入的库函数,可以看到,除了长得和printf函数很像以外,参数也非常像,多了一个第一个参数文件指针
例子:
fprintf(fp,"%s","www.dotcpp.com");
而返回值为整型,如果写入成功则返回写入字符的格式,否则返回一个负数。
2,fscanf
作为格式化写数据函数,它的参数同样比scanf也多一个参数,即第一个参数文件指针,表示读取的文件目标
例子:
char str[100];
fscanf(fp,"%s",str);
则表示从fp所指向的文件中进行读数据,与空格或换行结束,将结果保存到str数组中。
3,fwrite
1.使用: fwrite(ptr,size[ sizeof(str)] , nmemb, stream);
可以看到这个函数的参数有四个:
第一个ptr是要写入的数据的头指针,无符号类型;
第二个参数size是大小,表示每个写入元素的大小,单s位是字节;
第三个参数nmemb是个数,以上一个参数为单位的个数;
第四个参数stream就是文件指针,表示往哪里写。
2.具体在使用之前要先定义并打开一个文件(fopen),使用之后关闭文件(fclose)
3.程序运行后,并不会在屏幕上有任何显示
4,fread
1.使用:fread(ptr,size,nmem,stream);
fread函数的作用是从文件里读内容到程序中,它的参数意思是:
第一个参数ptr表示盛放内容的首地址;
第二个参数size表示每个元素的大小,单位还是字节;
第三个参数nmem表示要读取的元素个数;
第四个参数stream表示的是文件指针,即从哪个文件中读取。
2.使用之前要有文件和定义盛放内容的数组。
3.返回值则是表示读取元素的个数,与nmemb一致表示读取成功,否则失败。
3,关闭文件
用fclose函数实现,这一步则是切断文件指针和文件的关联,避免误操作。
int fclose( FILE *fp );
fp为第一步fopen时成功打开文件的指针;
返回值为整型,如成功关闭返回0,失败则返回-1.
C语言预处理之宏定义
1,概念
宏定义在C语言源程序中允许用一个标识符来表示一个字符串,称为“宏”,被定义为“宏”的标识符称为“宏名”。在编译预处理时,对程序中所有出现的宏名,都用宏定义中的字符串去代换,这称为“宏代换”或“宏展开”。
宏调用实际上相当于替换了自定义函数,它比自定义函数执行起来更有效率。
2,无参宏
1,定义
#define 标识符 字符串;
其中“#”表示这是一条预处理命令(在C语言中凡是以“#”开头的均为预处理命令)“define”为宏定义命令,“标识符”为所定义的宏名,“字符串”可以是常数、表达式、格式串等。
3,有参宏
1,定义
#define 宏名(形参表) 字符串;
2,调用
宏名(实参表);
3,例子
#include <stdio.h>
#define MAX(a,b) (a>b)?a:b
/*带参数的宏定义*/
main()
{
int x,y,max;
printf("input two numbers: ");
scanf("%d %d",&x,&y);
max=MAX(x,y);
printf("max=%d\n",max);
/*宏调用*/
}
4,其它预处理命令
#error
#line
#pragma
C语言文件包含include的用法
1,一般形式
#include "文件名"
或者
#include <文件名>
两种形式的区别
双引号表示先在源文件的目录中查找,若未找到再去包含目录中找。
尖括号则表示直接去包含目录里找
2,作用
当一个大程序由多个程序员共同完成时,公用宏定义和常量可单独构成文件,由include包含进来。
(文件包含允许嵌套,即在一个被包含的文件中又可以包含另一个文件。)
C语言条件编译的用法
1,作用
预处理程序提供了条件编译的功能,可以按不同的条件去编译不同的程序部分,因而产生不同的目标代码文件,这对于程序的移植和调试是很有用的。
2,三种形式
1,
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
如果标识符被define定义过,则执行程序段1,否则执行程序段2。
2,
#ifndef 标识符
程序段 1
#else
程序段 2
#endif
如果标识符被define定义过则执行程序段2,否则执行程序段1。
3,
#if 常量表达式
程序段 1
#else
程序段 2
#endif
如果常量表达式为非零则对程序段1进行执行,否则执行程序段2。
C语言位运算符
运算符表
左移运算符<< | 向左(即高位)移位,右侧补0 |
右移运算符>> | 向右(即低位)移位,左侧补0 |
按位取反~ | 如名,即0变1,1变0 |
按位与& | 相对应的两个位都为1则为1,反之为0 |
按位或| | 相对应的两个位至少有一个为1即为1,反之为0 |
按位异或^ | 相对应的两个位相同为0,相异(不同)为1 |
2,移位运算符(<<,>>)
1,作用
1. 左移N位的本质是乘以2的N次方。
2. 右移N位的本质是除以2的N次方。
2,运行原理
<<和>>运算符,通过箭头方向可以很好的辨别,分别是C语言位运算符中的左移运算符和右移运算符,如表达式13<<2,它的运算过程为:13的用二进制(四个字节,不考虑符号)表示0000 1101,那么向左移两位,右侧补0,则变为0000 0011 0100 换成十进制即变为52。
3,按位与运算符&
1,作用
1. 清零:
我们可以对某一个数与0进行按位与运算,由于两个位都为1才为1,因此最终全部位都变为0,起到清零的作用
2. 取指定位:
如某些存储场景下,“第1~3位表示xxxx“”,我们需要取出1~3位,则可以让原数值与数字7进行按位与运算,得到的结果即是原数值的1~3位的值。
3. 判断奇偶:
可以发现,数字的奇偶取决于二进制位的最低一位是1还是0,因此只需要与1按位与运算,判断是1是0即可得知奇偶。(数字变化是偶,数字不变时奇)。
2,运行原理
3 0000 0000 0000 0000 0000 0000 0000 0011
5 0000 0000 0000 0000 0000 0000 0000 0101
& ------------------------------------------
0000 0000 0000 0000 0000 0000 0000 0001
4,按位或运算符|
1,作用
对一个数字的指定位置为1,如“某个数字的第七位”表示开关,原先是0,需要改为1的状态,即可以将这个数字与64按位或,即可得到第七位变为1,其余位的值依旧不变。
2,运行原理
8 0000 0000 0000 0000 0000 0000 0000 1000
7 0000 0000 0000 0000 0000 0000 0000 0111
& ------------------------------------------
0000 0000 0000 0000 0000 0000 0000 1111
5,按位异运算符^
1,作用
1. 指定位数的翻转:
如想对某个数字的低4位进行翻转,则可以将这个数字与15(二进制为00001111)进行按位异或运算,既可以将原数字的低四位进行翻转,即高四位不变,低四位0变1,1变0。
2. 与0异或还是原值:
一个数字与0进行异或,结果还是原值。
3. 交换两个数字:
int* a;
int* b;
*a=*a^*b;
*b=*b^*a;
*a=*a^*b;
2,运行原理
两个数字的二进制代码相异,即不同则为1,反之为0。
6,取反运算符
~取反运算符,是对数值的二进制位进行取反,运算过程是即0变为1,1变为0。