C++之C语言位运算、预处理、文件操作

位运算符

含 义

&

按位与:对应的两个二进制位均为1时,则结果为1,否则为0

|

按位或:对应的两个二进制位其中一个为1时,则结果为1,否则为0

~

取反:~为单目运算符,把0转为1,把1转为0

^

按位异或:两个对应二进制位数不相同时,结果为1,否则为0

<<

左移:把二进制位向左移动指定的位数,高位丢弃,低位补0

>>

右移:把二进制位向右移动指定的位数,当为正数时高位补0,负数时高位补0还是1取决于编译系统的规定。

#define  _CRT_SECURE_NO_WARNINGS

#include  





int main()

{

int a = 25;

int b = 29;

int sum = a & b; //按位与

printf("%u \n", sum);



 sum = a | b; //按位或

printf("%u \n", sum);



sum = ~b; //按位取反

printf("%u \n", sum);



sum = a^b; //按位异或

printf("%u \n", sum);



sum = b<<2; //左移动两位

printf("%u \n", sum);



sum = b>>2; //右移动两位

printf("%u \n", sum);



return 0;

}

循环移位: 将移除的低位放到该数的高位,或者是将移除的高位放到该数的低位。

循环左移过程分为三步:

  1. 将x的左端n位先放到z的低n位中,z=x>>(32-n)  ;
  2. 将x左移n位,其右面低n位补0,y=x<
  3. 将y、z进行按位或运算,y=y|z  ;

循环右移过程分为三步:

  1. 将x的右端n位先放到z的高n位中,z=x<<(32-n)  ;
  2. 将x右移n位,其左端高n位补0,y=x>>n  ;
  3. 将y、z进行按位或运算,y=y|z  ;

位段

位段是一种特殊的结构体类型,其所有成员的长度均以二进制为单位进行定义,结构体中的成员被称为位段。位段的定义形式:

Struct 结构体名称{

类型 变量名1 :长度

.......

}

#define  _CRT_SECURE_NO_WARNINGS

#include  





int main()

{



struct MyStruct

{

unsigned a : 1; //表示a只占用1个二进制位

unsigned b : 2; //表示b只占用2个二进制位



unsigned  : 0; //表示无名字段,代表后面的内容从这里开始存储

unsigned c : 1; //表示a只占用1个二进制位

unsigned d : 2; //表示b只占用2个二进制位

};



/*

位段类型和位段变量的定义、位段成员的引用,均与结构体类型和结构体变量相同。

位段后面的长度代表该位段占用的二进制位数

*/



//可以使各段占满一个字节,也可以不占满(一个字节8位,也就是结构体内部的各位段长度加起来的和小于8的情况)

struct MyStruct2

{

unsigned a : 1; //表示a只占用1个二进制位

unsigned b : 2; //表示b只占用2个二进制位



unsigned : 0; //表示无名字段,代表后面的内容从这里开始存储

unsigned c : 1; //表示a只占用1个二进制位

unsigned d : 2; //表示b只占用2个二进制位

};



/*

1,一个位段必须存储在一个存储单元中(通常为一个字节),不能跨两个存储单元。如果本单元不够容纳某位段,则从下一个单元开始存储该位段。

2,可以用 %d, %x, %u, %o 等格式字符,以整数形式输出位段。

3,在数值表达式中引用位段时,系统自动将位段转换为整型数。

*/





return 0;

}





预处理

宏定义:是预处理命令的一种,它提供了一种可以替代源代码中字符串的机制。

#define  _CRT_SECURE_NO_WARNINGS

#include   



//不带参数的宏定义,宏定义不是C语句,不需要在末尾加上分号。宏定义的好处是:程序中引用该宏的地方在修改时只需要修改一处即可。

#define PI 3.14  

//带参数的宏定义: 不但要替换字符串,还要替换参数

#define tax(a,b) (a+b)  





int main()

{

printf("%d ,",PI);  //把PI替换为3.14

printf("%d",tax(4,6)); //把ax(4,6) ,替换为(4+6)

return 0;

}







#include命令:用于将其他源文件的内容包含进来,也就是将其他文件包含到本文件中。



#include   

#include "stdio.h"

如上所示,使用<> 号和使用 “”的区别是:

1,使用<>为标准方式,系统会直接到存放C库函数头文件所在的目录中寻找要包含的文件。

2,使用“”包含首先会在用户当前目录中寻找要包含的文件,若找不到,再到存放C库函数头文件所在的目录中寻找要包含的头文件。

经常用在头文件头部的被包含文件称为标题文件或头文件,一般以 .h为后缀。一般放在头文件中的内容有:宏定义、结构、联合、枚举申明、typedef申明、外部函数申明、全局变量申明。

关于头文件包含需要注意以下几点:

  1. 一个#include命令只能指定一个被包含的文件;
  2. 文件包含是可以嵌套的,即在一个被包含文件中还可以包含另一个被包含文件。
  3. 若a.c中包含头文件a.h, 则预编译后两者会成为一个文件。如果a.h中有全局静态变量,则该全局变量在a.c文件中也有效,这是不需要再用extern申明。

条件编译

默认情况下,源程序中的所有行都会参加编译,如果希望其中一部分内容只有再满足一定条件下时才能编译,这是就需要使用条件编译命令。

使用条件编译可以很好地处理正式版本程序与调试版本程序,同时还会增强程序的可移植性。

#define  _CRT_SECURE_NO_WARNINGS

#include   

#define NUM 55



//#if语句:如果if语句后面的表达式为真,则编译 #if 与 #endif 之间的程序段。

#if NUM>50

//这里书写代码

#endif 



//#if #else  语句: 使用类似于常规代码的 if else

#if  NUM==50

//满足条件执行这里

#else

//不满足条件执行这里

#endif





//if  #elif语句 : 多条件语句,类似于if  else if

#if NUM<55

//条件1满足执行这里

#elif  NUM>52

//条件2满足执行这里

#endif





//#ifdef 语句:如果后面跟着的宏已经被定义,则编译后面的程序,如果后面跟着的宏未被定义,则不编译后面的程序,

#ifdef NUM

//如果宏NUM已经被定义,则不编译这里面的程序

#endif 





//#ifdef #else 语句:如果后面跟着的宏已经被定义,则编译后面的程序,如果后面跟着的宏未被定义,则编译#else后面的程序,

#ifdef NUM

//如果宏NUM已经被定义,则不编译这里面的程序

#else

//如果宏NUM已经被定义,则编译这里面的程序

#endif 





//#ifndef 语句:如果后面跟着的宏未被定义,则编译后面的程序,如果后面跟着的宏已经定义,则不编译后面的程序,

#ifndef NUM

//如果宏NUM未被定义,则编译这里面的程序

#endif 





//#ifndef #else 语句:如果后面跟着的宏未被定义,则编译后面的程序,如果后面跟着的宏已经定义,则编译#else后面的程序,

#ifndef NUM

//如果宏NUM未被定义,则编译这里面的程序

#else

//如果宏NUM已经已经定义,则编译这里面的程序

#endif 





// #undef命令 : 删除事先定义好的宏定义,相当于是限制了宏PI的使用范围,即只在#define 与 #undef之间。

#define PI 3.14

//PI只在这里面有效

#undef PI







int main()

{

// #line命令: 用于显示_LINE_ 与 _FILE_ 的内容。 _LINE_用于显示当前编译行的行号  , _FILE_用于存放当前编译的文件名。常用于调试环境中。

printf("当前行号: %d \n", __LINE__);

printf("当前文件名称: %s \n", __FILE__);







//#pragma 命令 : 用于设定编译器状态或指示编译器完成一些特定的动作。格式为://#pragma 参数,参数主要有以下三个:

#pragma message  //在编译信息窗口中输出的相应信息

#pragma code_seg //设置程序中函数代码存放的代码段

#pragma once     //保证头文件被编译一次



/*

标准的预定义宏名有以下几个:

_LINE_  :当前被编译代码的行号

_FILE_  :当前源程序的文件名称

_DATE_  :当前源程序的创建日期

_TIME_  :当前源程序的创建时间

_STDC_  :判断当前编译器是否为标准C,若是标准C则其值为1,否则不是标准C编译器

*/

return 0;

}

文件

文件是一组相关数据的有序集合,名称叫做文件名。

C语言中,操作文件的类型为结构体FILE,且操作文件的方式是以 FILE *的方式。

#define  _CRT_SECURE_NO_WARNINGS

#include   

int main()

{

FILE* fp = fopen("a.txt", "r"); //使用指针的方式打开一个文件,且是只读模式

return 0;

}

文件使用方式

含义

r

操作文本文件只读

w

操作文本文件只写

a

在文本文件末尾追加

rb

操作二进制文件只读

wb

操作二进制文件只写

ab

在二进制文件末尾追加

r+

操作文本文件读写

w+

操作文本文件读写

a+

操作文本文件读写,或在文件末尾追加

rb+

操作二进制文件读写

wb+

操作二进制文件读写

ab+

操作二进制文件读写,或在文件末尾追加

#define  _CRT_SECURE_NO_WARNINGS

#include   



int main()

{

//使用指针的方式打开一个文件,且是只读模式,若打开文件失败则返回NULL

FILE* fp = fopen("G:\VS\CDemo\CDemo\c.txt", "a");





char C ='A';

//fputc函数用于向文件中写入一个字符串

fputc(C, fp);



int i = 12;

//fprintf将变量i格式写入到文件中去

fprintf(fp, "%d", i);



//读取fp执行的文件中的i的值

fscanf(fp, "%d", &i);



char a[100];//数据存储块

//fread代表以某种规则来读取数据块

fread(a, 20, 5, fp);  //参数a代表存储数据的块,20代表每次读取的数量,5代表读取的次数,fp是文件指针



//fwrite代表以某种规则写入文件,参数a代表存储数据的块,20代表每次要写的数量,5代表写的次数,fp是文件指针

fwrite(a, 20, 5, fp);



//移动文件内部的位置指针,fp代表要移动的指针,200代表偏移量,0代表起始位置

fseek(fp, 200, 0);



//将位置指针重返文件开头

rewind(fp);



//得到流式文件中的当前位置

ftell(fp);



//文件使用完毕后,关闭文件,关闭成功返回0,否则返回EOF

fclose(fp);



return 0;

}

你可能感兴趣的:(C++教程+实战项目,c++,c语言)