位运算符 |
含 义 |
& |
按位与:对应的两个二进制位均为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;
}
循环移位: 将移除的低位放到该数的高位,或者是将移除的高位放到该数的低位。
循环左移过程分为三步:
循环右移过程分为三步:
位段
位段是一种特殊的结构体类型,其所有成员的长度均以二进制为单位进行定义,结构体中的成员被称为位段。位段的定义形式:
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申明、外部函数申明、全局变量申明。
关于头文件包含需要注意以下几点:
条件编译
默认情况下,源程序中的所有行都会参加编译,如果希望其中一部分内容只有再满足一定条件下时才能编译,这是就需要使用条件编译命令。
使用条件编译可以很好地处理正式版本程序与调试版本程序,同时还会增强程序的可移植性。
#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;
}