实训课堂笔记


extern变量又称全局变量
extern 类型 变量名 = 初始化表达式 ;
register变量也属于局部变量。只能在函数体内定义register变量
只要是在外部,即不是在任何一个函数内定义的变量,编译器就将其当作全局变量,无论变量定义前是否有extern说明符
register 数据类型 变量1[=初始化表达式], 变量2[=初始化表达式]……;
static数据类型 变量1[=初始化表达式], 变量2[=初始化表达式]……; 与extern变量都是全局变量
static变量有静态全局变量和静态局部变量之分

C语言基础

#include<stdio.h> //预处理  用<>为系统提供 -> 用""为自定义  stdio.h为系统输入输出头文件
#include<stdlib.h>
//预处理作用:让系统知道有这个函数存在

//io->input output 接口->函数
//函数声明->函数原型
//返回值类型 函数名(参数列表);int add(int, int);
//函数功能:->参数 ->返回值

//测试函数
//每个项目有且仅有一个主函数
//项目的执行是从主函数开始,也是从主函数结束
//C语言的最小单位是函数->(行为,动作,接口,方法,数据处理)
//数据->属性,量
int main(int argc, char*argv[])
{
	//printf(int a,...)
	printf("Hello"); //printf -> stdio.h
	system("pause");   //getchar(),加断点 解决跳闪
	return 0;//函数与函数之间的数据交流  结束函数的作用  
}
//数据交流:return,函数参数,全局变量

1.基本知识
什么是软件:一系列按照特定顺序组织的计算机数据和指令的集合
常见软件:系统软件,应用软件
什么是开发:制造软件
软件的出现实现了人与计算机之间的更好的交互
计算机组成:输入,输出,存储器,CUP(运算器,控制器)
位(bit):度量数据最小的单位
字节(byte):最常用的基本单位,一个字节有8位 1B(byte)=8b(bit)
K字节:1k=1024byte=2^10byte
M兆字节:1M=1024K=2^10K
G吉字节:
T太字节

进制转化2,8,10,16
正数的原码反码补码相同,移码变符号位
负数原码是二进制码符号位为1,反码在原码基础上符号位不变,其他位转变,补码在反码的基础上加1,移码在补码的基础上变符号位
计算机以补码保存,唯一性

    +0           -0
原码:0000 0000   1000 0000
反码:0000 0000   1111 1111
补码:0000 0000   0000 0000

所有指令的集合称为计算机的指令系统
指令格式:操作码 操作数

32关键字
在这里插入图片描述
9中控制语句
在这里插入图片描述

运算符 优先级
在这里插入图片描述

CMD-DOS命令
在这里插入图片描述
typedef unsigned int u16; //将unsigned int简写成u16,有了这句之后,u16 a; 等价于unsigned int a;

结构体

struct Students
{
	int age_s;
	float socre_s;
};

float MaxSocre(Student*s)

将Students简写成stu,等价于上面结构体

typedef struct Students
{
	int age_s;
	float socre_s;
}stu;//类型名

float MaxSocre(stu*s)

与上面相比缺少typedef,这里的stu为结构体变量名,Students类型的变量名

struct Students
{
	int age_s;
	float socre_s;
}stu;//变量名
实例

student.h文件

#ifndef STUDENT_H_
#define STUDENT_H_ //防止重复定义
//结构体
typedef struct Students{
	int age_s;
	float socre_s;
}stu;

float MaxSocre(stu*s); //形参

#endif;

student.c

#include"student.h"
float MaxSocre(Students*s)
{
	return 0;
}

主函数文件

#include<stdio.h>
#include"student.h"

int main()
{
	stu s[] = { { 12, 90.0 }, { 12, 90.0 }, { 12, 90.0 } };//定义多个stu对象,数组
	//stu s[] = { 12, 90.0, 12, 90.0, 12, 90.0 };//等于上方
	stu a = { 19, 98.8 }; //定义一个stu对象

	MaxSocre(s); //实参 Students*s=s
	MaxSocre(&a); //Students*s=&a
	return 0;
}

实参与形参

#include<srdil.h>
//两个整形数据相加,将其和进行返回
//1.由实参传入
int add(int, int);//函数原型,只有续形式不带变量名,也可以写入变量名
int add(int a, int b);//同上
//定义
int add(int a1, int b1)
{
	return a+b;
}

int add1()
{
	int a,b;
	scanf("%d %d",&a, &b);
	return a+b;//int obj = a+b;    int *obj = &(a+b);
	//所有返回值类型都属于一个命名空间
}

//等式的左边:返回值类型,形参
//等式的右边:return 后面的表达式,实参
int main()
{
	int a=5, b=7;
	add(4, 4);//int a=4,b=4;
	add(a, b);//int a=a,b=b;
	add1();
	
	int a; //整形变量->整形数据
	int *p;	//p指针变量->指针(地址)
	p = &a;
	int pr[4];//pr是一个地址常量
	p = pr;
	for (int i = 0; i<4; i++)
	{
		scanf_s("%d", p + i);//如果是p++最后p指向末尾,如果要用,需执行语句p=pr或p=p-4
	}
	//p = pr;
	//p = p-4;
	for int i=0;i<4;i++)
	{
		printf("%d",*p++);
	}
	p++;

	return 0;
}

变量

//局部大于全局
int a=6; //全局变量
int main()
{
	printf("%d\n", a);	//6
	int a=3;
	printf("%d\n", a);  //3
	{//语句块
		int a=5;
		printf("%d\n", a); //5
	}//语句块结束,其中的a被释放
	printf("%d\n", a); //3
}

2021.5.23

C语言类型

构造类型 基本类型 指针类型 void空类型
基本类型:int, short, long, float, double, char, enum

构造<-基本类型
数组:int p[3]; int p[2][3];
结构体:struct(),union
int a; //a是整形变量
struct{ //匿名结构体
}s; //s是结构体变量
struct stu{ //stu是结构体类型名
}s; //s是stu结构体类型变量
typedef struct stu{ //stu是结构体类型名
}s; //s是stu结构体类型名

//只能合并不能拆解,一定要单一最大字节对齐,不够补充
typedef struct stu{ 
	unsinged int age_s; //4字节,不够8个,score_s8个,则补4个,为8个
	double score_s;     //8个字节
	unsinged int num_s; //4字节,不够8个,补四个,为8个
}s; //24字节
printf("%d\n", sizeof(s));  //24
typedef struct stu{ 
	unsinged int age_s; //4字节,不够8个,num_s是4个,两则合并为8个
	unsinged int num_s; //4字节,与age_s合并,总共8个
	double score_s;     //8个字节
}s; //16字节
printf("%d\n", sizeof(s));  //16

//最大字节用单独最大字节对齐,最大的为name_s[20]为20字节,单一最大为double 8字节,与其对齐为24字节,没有double则与单一最大字节int 4字节对齐,对齐字节为20
union stu{
	char name_s[20];
	unsinged int age_s; //
	unsinged int num_s; //
	double score_s;    //
};

void 变量名; //void a;错误,不能直接声明变量

void 函数的返回值
void add(int, int);
void *malloc(int size_t);//空类型指针可以指向任意数据类型
int *p=(int*)malloc(sizeof(int)*5);

基本类型

void test()
{
	int p[] = { 2, 34, 6 };
	char str[] = "dasfdf";
	printf("%d\n", sizeof(p) / sizeof(int)); //3
	printf("%d\n", sizeof(str) / sizeof(char)); //7
	printf("%d\n", strlen(str)); //6   cstring头文件,#include<cstring>
	//用strlen求字符串长度不包括'\0'
	//sizeof是运算符,不是函数
	printf("%d\n", sizeof(long));   // 4
	printf("%d\n", sizeof(int));    // 4
	printf("%d\n", sizeof(short));  // 2
	printf("%d\n", sizeof(float));  // 4
	printf("%d\n", sizeof(double)); // 8
	printf("%d\n", sizeof(char));   // 1

}
#include<math.h>
sqrt();  //开方
转义字符

在这里插入图片描述字符串:每个字符串尾自动加入‘\0’作为字符串结束标志
字符用单引号,字符串用双引号

ASCII码值
在这里插入图片描述
大写字母转小写字母

char c1, c2;
c1 = 'A';
c2 = c1 + 32;
printf("%c\n", c2);
printf("%d\n", c2);

数据类型极限
在这里插入图片描述

定义常量——define/const

#define N 3;//N定义成一种符号,N只是3的别名,直接替换
const float N = 3;//定义成变量,值固定不变

//define只能放开头
const可以放任意位置,值是固定不变的
#define M 4+3*4  //直接替换,不加任何修饰

void test()
{
	printf("%d", M * 5 + 4);  //M*5+4=4+3*4*5+4=68
}


const int a = 3; //常量const修饰int->a
int b;//
const int *p1 = &a;//const修饰int->*p1  p1是指针变量->pi可变的 
p1 = &a;
//*p1 = 2; //错误,*p是常量,不可变
int const* p2 = &b;//const修饰*p2
int * const p2 = &b;//const修饰p2 常量指针->必须有初值

2021.5.24

类型转换

隐式转换

在这里插入图片描述
不同数据类型直接运算会自定类型转换
在这里插入图片描述
在这里插入图片描述

强制类型转换

精度损失问题:较高类型向较低类型转换时可能发生

int main()
{
	bool b = 33;  //输出b为1
	int a = b;  //输出a为1  b进行隐式转换int
	int a = (int)b; //显示转换int
	//ctatic
void test()
{
	unsigned char a = -1;//1000 0001->1111 1110->1111 1111 (0-255)无符号 -1补码无符号为255
	printf("%d", a);//255
}

运算符

在这里插入图片描述
在这里插入图片描述
赋值的转换规则:使赋值号右边表达式值自动转换成其左边变量的类型
int i; i=2.56;则i=2
float f;int i;i=10; f=i;则f=10.0

void test()
{
	int a = 2;
	printf("%d\n", (a++, a++));// 3

	int b=(3,4,5);//等于最后一个值5
	int c=(a,b+3);//8   b=3
	int d=(c++,c);//9   c
}

条件运算符的结合方向为“自右到左”

int a = 5, b = 6, c = 7, d = 8;
printf("%d\n",a>b ? a : c>d ? c : d);//a>b?a:(c>d?c:d)   8  从右到左,先(c>d?c:d)

void test()
{
	int a = 2, b = 3;
	//0000 0010
	//0000 0011

	//0000 0011
	printf("%d\n", a | b);// 3
	//0000 0010
	//0000 0011
	
	//0000 0010
	printf("%d\n", a & b);//2
	//0000 0010
	//0000 0011

	//0000 0001
	printf("%d\n", a ^ b);//1
	printf("%d\n", !a);//0  非0即1
}

输入与输出

#incldue<stdio.h>

输出——putchar字符、printf格式、puts字符串

输出格式符
中括号可以省
在这里插入图片描述

在这里插入图片描述在这里插入图片描述

	char name[4] = "asd";
	char a[4];//a指针常量
	strcpy_s(a, name);  //#include<string> 复制

	printf("%07s", a);//0000asd
	printf("%s", a);
	printf("%07.4f",10.0);//10.0000

putchar 函数是字符输出函数, 其功能是在显示器上打印单个字符

putchar(c);//c为字符型或整型数据,也可输出转义字符,如“\n”等.输出c所代表的一个字符
putchar('a');//a       字符数据也可以是一个字符常量
putchar(65);//A        整数
char c_var='a';
putchar(c_var);//a     字符型变量
putchar('a'+25);//z    表达式
putchar('\n');         //转义字符

puts函数功能非常单一,在显示器屏幕上输出一个字符串,并换行

puts(字符串);
puts("hello world");  //hello world

char a[4] = "af";
puts(a);        // af
输入——getchar字符、scanf_s格式、gets_s

scanf_s:如果数据不止一个,应在数据之间用一个或多个空格间隔,也可以用回车键或跳格键tab间隔
在这里插入图片描述在这里插入图片描述scanf_s("%d,%d",&a,&b);输入时需要输入逗号用于匹配

	int a, b;
	scanf_s("%d,%d", &a, &b);  //1,3
	printf("%d,%d", a, b);    //1,3
//指定输入的数据所占据的字符个数,scanf_s函数自动按照指示截取所需长度的数据
int a, b;
scanf_s("%3d%3d", &a, &b);
printf("%d,%d", a, b); // 123  456

//%后面的*格式符,用来表示在解析时,将读入的数据忽略不赋给任何变量
int a, b;
scanf_s("%d%*d%d", &a, &b);//1 2 3
printf("%d,%d", a, b);//1,3

如果格式字符串中有非空白字符,也就是除了格式控制字符和空白字符之外的字符,则用户在输入的时候一定也要输入这些字符。否则将出现不匹配格式控制字符串的情况

在用%c格式符时,空格字符和转义字符都被当作有效字符输入

	char c1, c2, c3;
	scanf_s("%c,%c,%c", &c1, 1, &c2, 1, &c3, 1);//a,b,c
	printf("%c %c %c", c1, c2, c3);//a b c

	char a[5], b[5];
	scanf_s("%s%s", &a, sizeof(a), &b, sizeof(b)); // ab cd
	printf("%s,%s", a, b);             //ab cd

getchar 函数是得到用户输入的一个字符

	char ch;
	ch = getchar();//a
	printf("%c", ch);//a

gets_s可以接受空格
scanf_s遇到空格、回车和Tab键都认为输入结束

//gets(), scanf();
void test()
{
	char str[15];
	gets_s(str);   //abc def    puts();
	printf("%s\n", str); //abc def
	
	//scanf_s在使用%c和%s读入字符或字符串时,应在地址参数后附加一个缓冲区边界值。使用sizeof
	scanf_s("%s", &str, sizeof(str)); //abc def
	printf("%s\n", str); //abc
}
strcpy_s字符串复制

strcpy(str2, str1); 将字符串1复制给字符串2

	char p[5];
	strcpy_s(p, "sa,");
	printf("%s", p);

getchar(); 等待,按任意键继续
strcmp(str2, str1); 字符串比较

语句结构——if、switch、goto

if(a>b)
	c = a;
else
	c = b;
c = a>b?a:b; //等价于上方
	switch (1 + 2)
	{
	case 2:
		printf("2");
		break;
	case 3:
		printf("3");
		break;
	default:
		printf("0");
		break;
	}
continue//退出本次循环,进行下一个循环,只放循环语句中
break//退出该循环
int main()
{
	int i = 0;
AAA:
	i++;
	if (i<5)goto AAA;

在这里插入图片描述return语句中表达式的类型应与函数值类型一致。若不一致时,则以函数值的类型为准int max(float x)返回的是int类型(强转)

5.25

若有p=a(p指向数组a),则:
p++(或p+=1),表示p指向下一元素。
p++与(p++)等价。同样优先级,结合方向为自右向左。
(p++) 与(++p)。前者是先取p的值,后使p值加1,相当于a[i++];后者是先使p加1,再取p,相当于a[++i]。
(*p)++表示p所指向的元素值加1,而非指针值加1。

指针指向函数

int test(int a, int b)
{
	if (a > b)
		return a;
	else
		return b;
}

int main()
{
	int a = 3, b = 4;
	int (*p)(int, int);
	p = test;
	printf("%d", test(a, b));
	printf("%d", p(a, b));

	system("pause");
	return 0;
}
void swap(int, int);//值传递,实参复制值给形参,单向传递,形参变化不影响实参变换 分配了两个整形数据空间
void swap(int*, int*);//指针传递,实参地址给形参,通过实参地址取实参数据进行交换,最后实参变化,形参分配了两个指针空间

//不要调用局部变量
int *max(int* a, int* b) // 返回指针函数
{
	if (*a>*b)return a;
	return b; // 返回值是指针
}

int main()
{
	int a = 5, b = 3;
	int c = *max(&a, &b);
	system("pause");
	return 0;
}
//形参赋值是从参数右边开始,连续,不能间断
//int add(int a=3, int b, int c) //错误
int add(int a, int b, int c=3)
{
	return a + b + c;
}

int main()
{
	printf("%d\n", add(2, 3));
	printf("%d\n", add(2, 3, 5));
	system("pause");
	return 0;
}

5.26

可变参数…

/*
可变参数
1.首尾确定长度的
2.首尾结束符
va_list:首地址
va_strat:从首地址开始遍历参数
va_arg:从内存读取数据,类型转换
va_end:结束
*/
#include<stdarg.h>
int add(int num, ...)//最后一个数字为-1结束
{
	int res = 0, arg;
	va_list argp;
	va_start(argp, num);
	arg = num;
	do{
		res += arg;
		arg = va_arg(argp, int);
	} while (arg != -1);
	va_end(argp);
	return res;
}

int add1(int num, ...) //数字位数,相加的数字
{
	int res = 0;
	va_list argp;
	va_start(argp, num);
	for (int i = 0; i < num; i++)
		res += va_arg(argp, int);
	va_end(argp);
	return res;
}

5.28

指针

/*
p[4][3]
p->整个数组的首地址
p+0
&p[0][0]->第0行第0列的地址
*(p+0)+0->第0行第0列的地址
p[0]->第0行的首地址
*(p+0)->第0行的首地址
*p
*/

void test()
{
	int p[4][3];
	printf("%x\t", p);         // bff89c
	printf("%x\t", &p[0][0]);  // bff89c
	printf("%x\t", &p[1][0]);  // bff8a8
	printf("%x\t", p[0]);      // bff89c
	printf("%x\t", p[1]);      // bff8a8
	printf("%x\t", *(p + 0));  // bff89c
	printf("%x\t", *(p + 1));  // bff8a8
	printf("%x\t", *p);        // bff89c
	printf("%x\t", *(p+0)+0);  // bff89c
	
	//p+11数组第11行,*p+11数组第11个数
    printf("%x\t%x\t%x\t%x\t", &p[3][2], *(p + 3) + 2, *p + 11, p + 11);
    //f3fa50  f3fa50  f3fa50  f3faa8
	
	//地址加*为值
	printf("%x\t", *(*(p+0)+0)); // 值
	printf("%x\t", **p);         // 值
	printf("%d\t", *(&p[0][0])); // 值
	printf("%d\t", *p[0]);       // 值
	printf("%d\t", **(p + 0));   // 值
}

双指针

	int num = 3; //值3 地址0xffffff
	int *p = &num;//值0xffffff 地址0xfffffc
	int **p1 = &p;
	/*
	num = *p=3
	&num = &(*p)=0xffffff
	&num = p=0xffffff
	*(&num)=*p=3

	*(&p) = 0xffffff
	**(&p) = 3
	p1 = &p
	*/

数组

相同类型的元素集合

#include<string.h>
void test()
{
	char p[5] = { "abc" };
}
//4*3数组输出
void test(int p[][3])
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 3; j++)
			printf("%d\t", *(p[i] + j)); //p[i][j]
		printf("\n");
	}
}

int main()
{
	int p[4][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };
	//int p[][3] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; //等同于上方的
	test(p);
	return 0;
}

/*
void test(int (*p)[3])
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 3; j++)
			printf("%d\t", p[i][j]);
		printf("\n");
	}
}
test(p);

void test(int *p)
{
	for (int i = 0; i < 4; i++)
	{
		for (int j = 0; j < 3; j++)
			printf("%d\t",*(p+i*3+j));
		printf("\n");
	}
}
test(*p);
*/

一维数组指针

	int *ptr = NULL;
	int arr[5];
	ptr = arr;//p指针指向arr数组首地址
	//arr[0] = *(ptr + 0) = *ptr = ptr[0] = *arr = *(arr + 0)
	//&arr[0] = &(*ptr + 0) = &prt[0] = &(*arr) = ptr = arr

动态分配整形变量空间

	int *ptr = (int*)malloc(sizeof(int));
	*ptr = 5;
	printf("%d\n", *ptr);
	free(ptr);

动态分配数组空间

	#define MaxSize 100
	
	int *ptr = (int*)malloc(sizeof(int)*MaxSize);
	for (int i = 0; i < MaxSize; i++)
	{
		scanf_s("%d", ptr + i);
	}
	for (int i = 0; i < MaxSize; i++)
	{
		printf("%d\n", *(ptr + i));
	}
	free(ptr);
	ptr = NULL;
int test(int *a, int *b) //形参有存放整形数据的地址空间,返回值类型是存放数据空间
{
	if (*a > *b)
		return *a;
	else
		return *b;
}

int main()
{
	int a = 1, b = 3; //存放整形数据空间
	printf("%d\n", test(&a, &b));//存放整形数据的地址空间
	/*
	int (*p)(int*, int*);
	p = &test;
	(*p)(&a, &b);//等价于test(&a, &b)
	*/
	system("pause");
	return 0;
}

5.31

student.h

#ifndef STUDENT_H_
#define STUDENT_H_

extern int Map[4][5];

#endif;

student.c

#include"student.h"

int Map[4][5] = { 1, 2 }; //定义,并且给该数组赋值

主函数test.c

#include<stdio.h>
#include<stdlib.h>
#include"student.h"

int main()
{
	printf("%d\t%d\n", Map[0][0], Map[0][1]);
	system("pause");
	return 0; 
}
	//错误代码
	char str[20];
	str = "asg sdg e";
	//正确代码
	char *str;
	str = "asg sdg e";

指针先有地址,再有值

	int *p; //p先有地址,*p再有值

数组字符串赋值

	char str[14];
	str = "fsgerg";//错误,str是一个常量
	//错误
	char *a;
	scanf_s("%s",a);
	//正确
	char *a, str[10];
	a = str;
	scanf_s("%s", a);

	
	char *p;
	p = (char*)"aggrag"; //const char[]
	//p = "aggrag";
	printf("%s\n", p);
	//char *p = "aggrag"; //等价于上方

	char str[] = { "afsdger" };
	char str[] = "afsdger";
	char str[] = { 'a', 'g', 'e' };
	char *str = "ageg";
	int a[] = { 1, 2, 3, 4, 5 };

结构体

结构体输入输出

#pragma warning(disable:4996)

struct Students
{
	int num_t;
	char sex_t;
	float score_t;
	char name_t[20];
}stu[N];

struct Students
{
	int num_t;
	char sex_t;
	float score_t;
	char name_t[20];
}stu;

struct Students
{
	int num_t;
	char sex_t;
	float score_t;
	char name_t[20];
}stu[N]={{}{}};

typedef struct Students
{
	int num_t;
	char sex_t;
	float score_t;
	char name_t[20];
}stu;

struct Students
{
	int num_t;
	char sex_t;
	float score_t;
	char name_t[20];
};

input(Students* p)
input(Students p)

共用体

//共用体,边输入边输出,否则会覆盖之前的值,两个变量只有一个用,总共分配20字节
//分配最大的空间,即只分配char[20]空间
union MyUnion
{
	int num;
	char name[20];
}ss;

int main()
{
	scanf_s("%d", &ss.num);//使用char[20]空间
	printf("%d", ss.num);
	scanf_s("%s", ss.name);//使用char[20]空间
	printf("%s", ss.name);

	return 0;

}

移位

	int a = 3;
	printf("%d\n", a << 2); //12
	printf("%d\n", a >> 2); //0
	printf("%d\n", a ^ 2);//异或  相同为0,不同为1   0000 0010,0000 0011—>0000 0001
	printf("%d\n", ~a);//取反 3的补码0000 0011->补码:1111 1100->反码:1111 1011-> 源码1000 0100-> -4

文件

在这里插入图片描述

	//printf   scanf   gets   puts  getc  putc
	//fprintf   fscanf  fgets  fputs  fgetc  fputc
	//fprintf
	//打开文件fopen(char *filename,char *mode)
	/*
	mode:
	1.r/rb只读文件是已有的文件进行读,不存在不会创建
	2.w/wb只写文件,没有该文件,会自动新建
	3.a/ab向文件尾部追加数据
	4.r+/rb+为读写建立文本
	5.w+/wb+为读写建立文本
	6.a+/ab+为读写打开或建立文本
	FILE* fp;
	char *filename = "a.txt"; //路径用反斜杠/或双斜杠\\

	fp = fopen(filename, "r");
	if (fp == NULL)
	{
		printf("there are not file %s\n", filename);
	}
	fclose(fp);

写文件

fp = fopen(filename, "w");
	if (fp == NULL)
	{
		printf("there are not file %s\n", filename);
	}
	fputs("abcdef", fp); //将字符串写入文件

读文件

char str[20];
	fp = fopen(filename, "r");
	if (fp == NULL)
	{
		printf("there are not file %s\n", filename);
	}
	fgets(str, 20, fp);
	printf("%s\n", str);//输出
	puts(str);//输出

char str[20];
	fp = fopen(filename, "r");
	if (fp == NULL)
	{
		printf("there are not file %s\n", filename);
	}

	int i = 0;
	while (!feof(fp))
	{
		str[i++] = fgetc(fp);
	}
	puts(str);//abcdef烫烫烫烫烫烫烫烫烫烫谈Xi
	for (int j = 0; j < 7; j++)
		printf("%c", str[j]);  //abcdef

项目 属性 配置属性 调试命令参数后输入

int main(int argc, char* argv[])
{
	while (argc > 1)
	{
		++argv;
		printf(" % s\n", *argv);
		--argc;
	}
	return 0;
}

俄罗斯方块项目

info.cpp

#include"info.h"
int gameMap[24][30] = { 0 };
int gscore = 0;
int glevel = 0;

int score = 0; //历史分数
//记录19种图形的结构体,这个思维数组初学者还是不太容易理解的
char g_aCubeShape[7][4][4][4] = {
		{
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 1, 0, 0 }, //■■
				{ 1, 1, 0, 0 } // ■■
			},
		},

		{
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 1, 1, 1 } //■■■■
			},
			{
				{ 0, 1, 0, 0 }, //■
				{ 0, 1, 0, 0 }, //■
				{ 0, 1, 0, 0 }, //■
				{ 0, 1, 0, 0 }, //■
			},
		},

		{

			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 0, 1, 1, 0 }, // ■■
				{ 1, 1, 0, 0 } //■■
			},
			{
				{ 0, 0, 0, 0 },
				{ 1, 0, 0, 0 }, //■
				{ 1, 1, 0, 0 }, //■■
				{ 0, 1, 0, 0 } //   ■
			}
		},
		{
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 1, 0, 0 }, //■■
				{ 0, 1, 1, 0 } //   ■■

			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 1, 0, 0 }, //  ■
				{ 1, 1, 0, 0 }, //■■
				{ 1, 0, 0, 0 } // ■
			}
		},
		{
			{
				{ 0, 0, 0, 0 },
				{ 1, 1, 0, 0 }, //■■
				{ 0, 1, 0, 0 }, //  ■
				{ 0, 1, 0, 0 } //   ■
			},
			{

				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 }, 
				{ 0, 0, 1, 0 }, //    ■
				{ 1, 1, 1, 0 }  //■■■
			},
			{
				{ 0, 0, 0, 0 },
				{ 1, 0, 0, 0 }, //■
				{ 1, 0, 0, 0 }, //■
				{ 1, 1, 0, 0 }  //■■
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 1, 1, 0 }, //■■■
				{ 1, 0, 0, 0 }  //■
			}

		},
		{
			{
				{ 0, 0, 0, 0 },
				{ 1, 1, 0, 0 }, //■■
				{ 1, 0, 0, 0 }, //■ 
				{ 1, 0, 0, 0 }  //■ 
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 1, 1, 0 }, //■■■
				{ 0, 0, 1, 0 }     // ■
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 1, 0, 0 }, // ■
				{ 0, 1, 0, 0 }, // ■
				{ 1, 1, 0, 0 } //■■
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 1, 0, 0, 0 },//■ 
				{ 1, 1, 1, 0 } //■■■
			}
		},
		{
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 },
				{ 0, 1, 0, 0 }, // ■
				{ 1, 1, 1, 0 } //■■■
			},
			{
				{ 0, 0, 0, 0 },
				{ 1, 0, 0, 0 }, //■
				{ 1, 1, 0, 0 }, //■■
				{ 1, 0, 0, 0 }  //■
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 0, 0, 0 }, //
				{ 1, 1, 1, 0 }, //■■■
				{ 0, 1, 0, 0 }  //  ■
			},
			{
				{ 0, 0, 0, 0 },
				{ 0, 1, 0, 0 }, //  ■
				{ 1, 1, 0, 0 }, //■■
				{ 0, 1, 0, 0 } //   ■
			}
		},
};
//设置缓冲区窗口,开机动画
void openAnimal()
{
	SetConsoleTitleA("俄罗斯方块");
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD size = { 90, 50 };
	SetConsoleScreenBufferSize(handle, size);
	SMALL_RECT rect = { 0, 0, 90 - 1, 50 - 1 };
	//设置窗体大小
	SetConsoleWindowInfo(handle, true, &rect);

}
//初始化地图
void initMap()
{
	memset(gameMap, 0, sizeof(gameMap));
	for (int y = 0; y < 24; y++) {
		for (int x = 0; x < 30; x++) {
			if (x == 0 || y == 0 || x == 29 || y == 23)
			{
				gameMap[y][x] = WALL;
				//printf("%d",gameMap[y][x]);
			}
		}
		//printf("\n");
	}
}
//将字符串写入windows窗口,并设置颜色
void WriteWchar(int x, int y, const char szString[], int attr)
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//API
	COORD pos = { x * 2, y };
	SetConsoleTextAttribute(hOut, attr);
	SetConsoleCursorPosition(hOut, pos);
	printf("%s", szString);
}
//绘制游戏地图
void drawMap()
{
	for (int y = 0; y < 24; y++) {
		for (int x = 0; x < 30; x++) {
			if (gameMap[y][x] == WALL)
				WriteWchar(x, y, "■", F_H_WHITE);
			else {
				WriteWchar(x, y, "  ", F_H_WHITE);
			}
		}
		printf("\n");
	}

	//右边的设置
	WriteWchar(34, 2, "俄罗斯方块", F_H_GREEN);
	//绘制分数、等级、下一个方块
	WriteWchar(32, 5, "分数:", F_H_GREEN);
	WriteWchar(32, 7, "等级:", F_H_GREEN);
	//把成绩格式化到缓存区
	char buf[6] = { 0 };
	sprintf_s(buf, sizeof(buf), "%d", gscore);
	//sprintf(buf, "%d", gscore); vc 6.0写法
	WriteWchar(36, 5, buf, F_H_GREEN);
	//绘制等级
	char buf1[6] = { 0 };
	//把等级格式化输出到缓存区中
	sprintf_s(buf1, sizeof(buf1), "%d", glevel);
	sprintf(buf1, "%d", glevel); vc 6.0写法
	WriteWchar(36, 7, buf1, F_H_GREEN);

	WriteWchar(32, 11, "NEXT:", F_H_GREEN);

	WriteWchar(32, 17, "操作说明:", F_H_GREEN);
	WriteWchar(34, 19, "(W)键 变形", F_H_GREEN);
	WriteWchar(34, 20, "<-(A)键  ->(D)键", F_H_GREEN);
	WriteWchar(34, 21, "↓(S)键", F_H_GREEN);
}
//获取随机的形状,方向,颜色
void getRandom(pRandom pRand)
{
	srand(time(NULL));
	//随机生成
	pRand->shape = rand() % 7;//0-6
	pRand->dir = rand() % 4;//0-3
	pRand->color = rand() % 11;
	//特殊处理,比如:第一种形状,没有必要随机变化方向
	//因为不知道什么时候会产生第一种形状
	while (true)
	{
		if (pRand->shape == 0) {
			pRand->dir = 0;
			break;
		}
		else if (pRand->shape == 1 && pRand->dir > 1)
		{
			pRand->dir = rand() % 4;
		}
		else if (pRand->shape == 2 && pRand->dir > 1)
		{
			pRand->dir = rand() % 4;
		}
		else if (pRand->shape == 3 && pRand->dir > 1)
		{
			pRand->dir = rand() % 4;
		}
		else
			break;


	}
	//随机分配颜色
	switch (pRand->color)
	{
	case 0:
		pRand->color = F_BLUE;
		break;
	case 1:
		pRand->color = F_H_BLUE;
		break;
	case 2:
		pRand->color = F_GREEN;
		break;
	case 3:
		pRand->color = F_H_GREEN;
		break;
	case 4:
		pRand->color = F_RED;
		break;
	case 5:
		pRand->color = F_H_RED;
		break;
	case 6:
		pRand->color = F_YELLOW;
		break;
	case 7:
		pRand->color = F_H_YELLOW;
		break;
	case 8:
		pRand->color = F_PURPLE;
		break;
	case 9:
		pRand->color = F_H_PURPLE;
		break;
	case 10:
		pRand->color = F_CYAN;
		break;
	default:
		break;
	}

}
//获取形状
void getShape(pShapeInfo  shape)
{
	Random m_ran = { 0 };
	COORD pos = { 15, 3 };
	getRandom(&m_ran);//重新获取随机数
	//下一个形状
	shape->isMove = TRUE;
	shape->pos = pos;
	shape->ran = m_ran;
}
//绘制图形
void  drawShape(ShapeInfo shape)
{
	//printf("%d,\t%d",shape.pos.X,shape.pos.Y);
	for (int y = shape.pos.Y - 3; y <= shape.pos.Y; y++)
	{
		for (int x = shape.pos.X - 3; x <= shape.pos.X; x++)
		{
			//WriteWchar(x, y, "  ", F_H_WHITE);
			if (g_aCubeShape[shape.ran.shape][shape.ran.dir][y - shape.pos.Y + 3][x - shape.pos.X + 3])
			{
				gameMap[y][x] = SHAPE;
				WriteWchar(x, y, "■", shape.ran.color);
			}
		}
	}
	//有可能方块图案出生时将边框覆盖掉。
	for (int X = 12; X <= 15; X++)
	{
		gameMap[0][X] = WALL;
		WriteWchar(X, 0, "■", F_WHITE);
	}
}
//右边显示下一个出现的图形
void  drawNextShape(ShapeInfo shape)
{
	COORD pos = { 38, 15 };
	for (int y = pos.Y - 3; y <= pos.Y; y++)
	{
		for (int x = pos.X - 3; x <= pos.X; x++)
		{
			WriteWchar(x, y, "  ", F_H_WHITE);//先清除在画
			if (g_aCubeShape[shape.ran.shape][shape.ran.dir][y - pos.Y + 3][x - pos.X + 3]) {
				WriteWchar(x, y, "■", shape.ran.color);
			}

		}
	}

}
//清除原先形状(4*4数组),为新形状变化后,使得地图干净
void clsShape(ShapeInfo shape)
{
	for (int y = shape.pos.Y - 3; y <= shape.pos.Y; y++)
	{
		for (int x = shape.pos.X - 3; x <= shape.pos.X; x++)
		{
			if (g_aCubeShape[shape.ran.shape][shape.ran.dir][y - shape.pos.Y + 3][x - shape.pos.X + 3])
			{
				WriteWchar(x, y, "  ", F_BLUE);
				gameMap[y][x] = 0;
			}
		}
	}
}
//判断形状是否移动
BOOL isMove(ShapeInfo shape)
{
	for (int y = shape.pos.Y - 3; y <= shape.pos.Y; y++)
	{
		for (int x = shape.pos.X - 3; x <= shape.pos.X; x++)
		{
			if (gameMap[y][x] == WALL && g_aCubeShape[shape.ran.shape][shape.ran.dir][y - shape.pos.Y + 3][x - shape.pos.X + 3])
				return FALSE;
		}
	}
	return TRUE;
}
//相当于画,擦,判段方块都在这里面
void drawMoveShape(pShapeInfo newShape, pShapeInfo oldShape)
{
	//方块在移动
	if (isMove(*newShape))
	{
		//擦除就方块
		clsShape(*oldShape);
		//绘制新方块
		drawShape(*newShape);
		//更新方块信息
		*oldShape = *newShape;
		return;//结束此方法
	}
	//方块左右碰到墙壁
	ShapeInfo shape = *oldShape;
	shape.pos.Y++;
	if (isMove(shape))
	{
		//更新方块信息
		*newShape = *oldShape;
		return;
	}
	newShape->isMove = FALSE;
}
//通过键盘控制图形变化方向,左移,右移,加速下移
void keyControl(pShapeInfo shape)
{
	char ch = _getch();
	switch (ch)
	{
	case 72:
	case 'w':
	case 'W':
		if (shape->ran.shape == 0)
			shape->ran.dir = 0;
		else if (shape->ran.shape == 1 || shape->ran.shape == 2 || shape->ran.shape == 3)
			shape->ran.dir = (shape->ran.dir+1) % 2;//0-1
		else shape->ran.dir = (shape->ran.dir+1) % 4;
		break;

	case 75:
	case 'a':
	case 'A':
		shape->pos.X--;
		break;
	case 77:
	case 'd':
	case 'D':
		shape->pos.X++;
		break;
	case 80:
	case 's':
	case 'S':
		shape->pos.Y++;
		break;
	default:
		break;
	}
}
void drawFallShape(ShapeInfo shape)
{
	for (int y = shape.pos.Y - 3; y <= shape.pos.Y; y++)
	{
		for (int x = shape.pos.X - 3; x <= shape.pos.X; x++)
		{
			if (g_aCubeShape[shape.ran.shape][shape.ran.dir][y - shape.pos.Y + 3][x - shape.pos.X + 3])
			{
				gameMap[y][x] = WALL;
				WriteWchar(x, y, "■", F_GREEN);
			}
		}
	}
}
//消除函数
void clsRow(int posY)
{
	//将以找到的满行,标为红色
	for (int x = 1; x < 29; x++)
	{
		WriteWchar(x, posY, "■", F_H_RED);
	}
	Sleep(100);//休眠0.1s
	//将以找到的满行,填充空格
	for (int x = 1; x < 29; x++)
	{
		gameMap[posY][x] = 0;
		WriteWchar(x, posY, "  ", F_H_RED);
	}
	//从posY行上方所有格子下移
	for (int x = 1; x < 29; x++)
	{
		for (int y = posY - 1; y > 3; y--)
		{
			if (!gameMap[y][x])
				break;
			for (int i = y + 1; i <= 22; i++)
			{
				if (!gameMap[i][x]) //只有格子为空才进行下移
				{
					//下一行使用绿色填充
					gameMap[i][x] = WALL;
					WriteWchar(x, i, "■", F_H_GREEN);
					gameMap[y][x] = 0;//将上一行清空
					WriteWchar(x, y, "  ", F_H_WHITE);
					continue;
				}
				break;
			}
		}
	}
	gscore += 100;
	switch (gscore / 100)
	{
	case 3:
		glevel++;
		break;
	default:
		break;
	}
}
//遍历行,和列满,并处理行满返回TRUE,列满返回FALSE
BOOL findFull()//查看行和列是否满
{
	for (int y = 22; y > 3; y--) {
	label:
		int count = 0;
		for (int x = 1; x < 29; x++)
		{//列满,游戏结束
			for (int j = 1; j < 29; j++)
				if (gameMap[4][j] == 1)return FALSE;
			//行满
			//1.有空格就跳下一行
			if (!gameMap[y][x])break;
			//2.不是空格
			count++;
		}//列识别结束
		if (count == 28)//行满消行
		{
			//消行
			clsRow(y);
			count = 0;
			y = 22;
			goto label;
		}
	}//行
	//分数和等级显示
	//把成绩格式化到缓存区
	char buf[6] = { 0 };
	sprintf_s(buf, sizeof(buf), "%d", gscore);
	//sprintf(buf, "%d", gscore); vc 6.0写法
	WriteWchar(36, 5, buf, F_H_GREEN);
	//绘制等级
	char buf1[6] = { 0 };
	//把等级格式化输出到缓存区中
	sprintf_s(buf1, sizeof(buf1), "%d", glevel);
	sprintf(buf1, "%d", glevel); vc 6.0写法
	WriteWchar(36, 7, buf1, F_H_GREEN);
	return true;

}
//欢迎界面
void drawPic(){
	//相对于电脑
	//定义四个坐标点
	COORD posDown = { 9, 0 };
	COORD  posUp = { 29, 41 };
	COORD  posRight = { 39, 11 };
	COORD  posLeft = { 0, 29 };
	//设定死循环
	
	int k = -20;
	while (true)
	{

		Sleep(100);
		if (k < 2)
		{

			system("cls");
			k++;
			if (k>0) WriteWchar(9, k, "           ■■                                        ", F_RED);
			if (k>-1) WriteWchar(9, k + 1, "           ■■   ■■                                  ", F_RED);
			if (k>-2) WriteWchar(9, k + 2, "■■■■   ■■   ■■           ■■       ■■                   ■■", F_RED);
			if (k>-3) WriteWchar(9, k + 3, "■■■■   ■■   ■■■■       ■■       ■■                   ■■ ", F_RED);
			if (k>-4) WriteWchar(9, k + 4, "■■■■   ■■   ■■■■   ■■■■■■   ■■■■■■   ■■■■■■", F_RED);
			if (k>-5) WriteWchar(9, k + 5, "■■■■   ■■       ■■   ■■■■■■   ■■■■■■   ■■■■■■", F_RED);
			if (k>-6) WriteWchar(9, k + 6, "           ■■       ■■                                    ", F_RED);
			if(k>-7) WriteWchar(9, k + 7, "           ■■                                               ", F_RED);

			if (k>-10) WriteWchar(9, k + 10, "       ■■■■■■   ■■               ■■       ■■    ■■                        ", F_RED);
			if (k>-11) WriteWchar(9, k + 11, "       ■■■■■■   ■■              ■■■       ■■  ■■                 ", F_RED);
			if (k>-12) WriteWchar(9, k + 12, "       ■■    ■■   ■■            ■■  ■■      ■■■■                   ", F_RED);
			if (k>-13) WriteWchar(9, k + 13, "       ■■    ■■   ■■           ■■    ■■      ■■■                   ", F_RED);
			if (k>-14) WriteWchar(9, k + 14, "       ■■■■■■   ■■           ■■■■■■       ■■", F_RED);
			if (k>-15) WriteWchar(9, k + 15, "       ■■■■■■   ■■           ■■■■■■       ■■   ", F_RED);
			if (k>-16) WriteWchar(9, k + 16, "       ■■           ■■■■■■   ■■    ■■       ■■                         ", F_RED);
			if (k>-17) WriteWchar(9, k + 17, "       ■■           ■■■■■■   ■■    ■■       ■■                             ", F_RED);
		}
		else
			break;
	}
	
	//执行控制台命令cls,就是CMD下面的cls,功能是清屏,清除所有显示的信息。
	system("cls");
	WriteWchar(9, 4, "           ■■                                        ", F_RED);
	WriteWchar(9, 5, "           ■■   ■■                                  ", F_RED);
	WriteWchar(9, 6, "■■■■   ■■   ■■           ■■       ■■                   ■■", F_RED);
	WriteWchar(9, 7, "■■■■   ■■   ■■■■       ■■       ■■                   ■■ ", F_RED);
	WriteWchar(9, 8, "■■■■   ■■   ■■■■   ■■■■■■   ■■■■■■   ■■■■■■", F_RED);
	WriteWchar(9, 9, "■■■■   ■■       ■■   ■■■■■■   ■■■■■■   ■■■■■■", F_RED);
	WriteWchar(9, 10,"           ■■       ■■                                    ", F_RED);
	WriteWchar(9, 11,"           ■■                                               ", F_RED);
	
	WriteWchar(9, 14, "       ■■■■■■   ■■               ■■       ■■    ■■                        ", F_RED);
	WriteWchar(9, 15, "       ■■■■■■   ■■              ■■■       ■■  ■■                 ", F_RED);
	WriteWchar(9, 16, "       ■■    ■■   ■■            ■■  ■■      ■■■■                   ", F_RED);
	WriteWchar(9, 17, "       ■■    ■■   ■■           ■■    ■■      ■■■                   ", F_RED);
	WriteWchar(9, 18, "       ■■■■■■   ■■           ■■■■■■       ■■", F_RED);
	WriteWchar(9, 19, "       ■■■■■■   ■■           ■■■■■■       ■■   ", F_RED);
	WriteWchar(9, 20, "       ■■           ■■■■■■   ■■    ■■       ■■                         ", F_RED);
	WriteWchar(9, 21, "       ■■           ■■■■■■   ■■    ■■       ■■                             ", F_RED);
	
	//分数
	readFile();

	
	//检测键盘是否输入,检测当前输入的键盘是否是enter键
	while (!(_kbhit() && _getch() == 0x0d)){
		WriteWchar(27, 26, "press enter to start", F_RED);

	}
	//清零屏幕
	system("cls");
}

//读文件
void readFile()
{
	WriteWchar(23, 24, "最高分:", F_RED);
	FILE *fp;
	errno_t err;
	char filename[20] = "a.txt";
	err = fopen_s(&fp, filename, "r");
	fscanf_s(fp, "%d", &score);
	char str[20];
	_itoa_s(score, str, 10);
	WriteWchar(28, 24, str, F_RED);
	fclose(fp);

}
//写文件
void writeFile()
{
	if (gscore > score)
	{
		FILE *fp;
		errno_t err;
		char filename[20] = "a.txt";
		err = fopen_s(&fp, filename, "w");
		fprintf_s(fp, "%d", gscore);
		fclose(fp);
	}
}
//结束动画
void drawOver(){
	//相对于电脑
	//定义四个坐标点
	COORD posDown = { 9, 0 };
	COORD  posUp = { 29, 41 };
	COORD  posRight = { 39, 11 };
	COORD  posLeft = { 0, 29 };
	//设定死循环

	//执行控制台命令cls,就是CMD下面的cls,功能是清屏,清除所有显示的信息。
	system("cls");
	WriteWchar(9, 7,  "■■■■    ■■    ■■■■■  ■■■    ■■    ■      ■  ■■■  ■■■    ", F_RED);
	WriteWchar(9, 8,  "■         ■  ■   ■  ■  ■  ■       ■  ■    ■    ■   ■      ■  ■          ", F_RED);
	WriteWchar(9,9,  "■  ■■  ■■■■  ■  ■  ■  ■■■  ■    ■    ■  ■    ■■■  ■■■           ", F_RED);
	WriteWchar(9, 10,  "■    ■  ■    ■  ■  ■  ■  ■       ■  ■      ■■     ■      ■■   ", F_RED);
	WriteWchar(9, 11,  "■■■■  ■    ■  ■  ■  ■  ■■■    ■■        ■      ■■■  ■  ■", F_RED);

	WriteWchar(20, 18, "本次游戏获得的分数是:", F_RED);
	char str[20];
	_itoa_s(gscore, str, 10);
	WriteWchar(32, 18, str, F_RED);


	//检测键盘是否输入,检测当前输入的键盘是否是enter键
	while (!(_kbhit() && _getch() == 0x0d)){

	}
	//清零屏幕
	system("cls");
}


//游戏实现函数
void playGame()
{
	ShapeInfo newShape, nextShape, oldShape;//定义形状
	getShape(&newShape);//获取形状
	drawShape(newShape);
	oldShape = newShape;
	getShape(&nextShape);//获取形状
	drawNextShape(nextShape);
	int time = 10000;
	while (TRUE) {
		//绘制下一个方块,去查看方块本身属性
		if (newShape.isMove == FALSE)
		{
			//到把以下落不能移动方块对应的值修改为1,为墙
			drawFallShape(oldShape);
			//消行且计分或则上方已经满
			if (findFull() == FALSE)break;
			newShape = nextShape;
			oldShape = nextShape;
			getShape(&nextShape);//获取形状
			drawNextShape(nextShape);//绘制下一个图形
			drawShape(newShape);//绘制移动的图形
		}
		time--;
		if (!time)
		{
			//绘制移动形状
			newShape.pos.Y++;
			drawMoveShape(&newShape, &oldShape);
			time = 10000;
		}
		if (!_kbhit())
		{
			continue;
		}
		keyControl(&newShape);
		drawMoveShape(&newShape, &oldShape);
	}

	WriteWchar(12, 8, "游戏结束!", F_RED);
	WriteWchar(8, 12, "本次游戏获得的分数是:", F_RED);
	char str[20];
	_itoa_s(gscore, str, 10);
	WriteWchar(20, 12, str, F_RED);

	drawOver();
	writeFile();
}

info.h

#ifndef INFO_H_
#define INFO_H_
/*头文件*/
#include <stdio.h>//
#include <stdlib.h>
#include <Windows.h>
#include <time.h>
#include <conio.h>//键值



#define WALL 1//墙壁
#define SHAPE 2//图形

// 字体颜色
#define F_BLUE FOREGROUND_BLUE // 深蓝
#define F_H_BLUE 0x0001|0x0008 // 亮蓝
#define F_GREEN 0x0002 // 深绿
#define F_H_GREEN 0x0002|0x0008 // 亮绿
#define F_RED 0x0004 // 深红
#define F_H_RED 0x0004|0x0008 // 亮红
#define F_YELLOW 0x0002|0x0004 // 深黄
#define F_H_YELLOW 0x0002|0x0004|0x0008 // 亮黄
#define F_PURPLE 0x0001|0x0004 // 深紫
#define F_H_PURPLE 0x0001|0x0004|0x0008 // 亮紫
#define F_CYAN 0x0002|0x0004 // 深青
#define F_H_CYAN 0x0002|0x0004|0x0008 // 亮青
#define F_WHITE 0x0004|0x0002|0x0001//白
#define F_H_WHITE 0x0004|0x0002|0x0001|0x0008//空白

/*变量声明*/
extern int gameMap[24][30];
extern char g_aCubeShape[7][4][4][4];
extern int gscore;
extern int glevel;

/*结构体声明*/
//获取随机数
typedef struct _RANDOM{
	//4种方向0-3
	int dir;
	//7种图形0-6
	int shape;
	//11颜色0-10
	int color;
}*pRandom, Random;
typedef struct _SHAPEINFO {
	//是否移动
	BOOL isMove;
	//坐标
	COORD pos;
	//获取随机的形状,方向,颜色
	Random ran;
}*pShapeInfo, ShapeInfo;
/*函数声明*/
void openAnimal();//设置缓冲区窗口,开机动画
void initMap();//初始化地图
//绘制设置位置和颜色
void WriteWchar(int x, int y, const char szString[], int attr);
void drawMap();//绘制地图
获取随机的形状,方向,颜色
void getRandom(pRandom pRand);
//绘制图形
void  drawShape(ShapeInfo shape);
//下一个图形
void  drawNextShape(ShapeInfo shape);
//获取形状
void getShape(pShapeInfo shape);
//清楚形状
void clsShape(ShapeInfo shape);
//判断形状是否移动
BOOL isMove(ShapeInfo shape);
//相当于画,擦,判段方块都在这里面
void drawMoveShape(pShapeInfo newShape, pShapeInfo oldShape);//绘制移动图形
void keyControl(pShapeInfo shape);//按键控制游戏
void drawFallShape(ShapeInfo shape);//不再移动的形状处理
//行满,消行并统计分数
void clsRow(int posY); //消除行
BOOL findFull();//遍历行,和列满,并处理行满返回TRUE,列满返回FALSE
void drawPic();//欢迎界面
void readFile();//读文件

void writeFile();//写文件
void drawOver();
void playGame();
#endif // !INFO_H_

test.cpp

#include"info.h"
#include<stdlib.h>

int main()
{
	drawPic(); //开始界面
	openAnimal();//设置window窗口
	initMap();//初始化地图
	drawMap();//绘制地图
	playGame();
	drawOver();//结束界面

	//getchar();
	return 0;
}

推箱子项目

test.cpp

#include"info.h"
#include<stdio.h>

int main()
{
	drawPic(); //开始界面
	PleyGame(); //开始游戏
	return 0;
}

info.h

#ifndef INFO_H_
#define INFO_H_
/*头文件*/
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#include <time.h>
#include <conio.h>

// 字体颜色 
#define F_BLUE FOREGROUND_BLUE  // 深蓝
#define F_H_BLUE 0x0001|0x0008  // 亮蓝
#define F_GREEN 0x0002          // 深绿
#define F_H_GREEN 0x0002|0x0008 // 亮绿
#define F_RED 0x0004            // 深红
#define F_H_RED 0x0004|0x0008   // 亮红
#define F_YELLOW 0x0002|0x0004  // 深黄
#define F_H_YELLOW 0x0002|0x0004|0x0008 // 亮黄
#define F_PURPLE 0x0001|0x0004  // 深紫
#define F_H_PURPLE 0x0001|0x0004|0x0008 // 亮紫
#define F_CYAN 0x0002|0x0004    // 深青
#define F_H_CYAN 0x0002|0x0004|0x0008   // 亮青
#define F_WHITE 0x0004|0x0002|0x0001    //白
#define F_H_WHITE 0x0004|0x0002|0x0001|0x0008//空白

/*函数声明*/

//绘制设置位置和颜色
void WriteWchar(int x, int y, const char szString[], int attr);
void drawPic();    // 欢迎界面
void drawMap();    // 绘制游戏地图
int PleyGame();    // 开始游戏
int MoveMap();     // 移动
void readFile();   // 读文件
void Winter();     // 绘制胜利界面
void writeFile();  // 写文件
void GameOver();   // 结束界面
void CopyMap();    // 复制关卡
void anew();       // 从新开始
#endif // !INFO_H_

info.cpp

#include"info.h"
int gscore = 0; //游戏步数
#define N 15
#define M 3
int limit[M] = { 30, 100, 100 }; //步数限制
int level = 0;
int game[15][15]; //保存当前关卡地图
//关卡,地图
int gameMap[M][15][15] = {//0空白  1墙  3目的地  4箱子  5人
		{//关卡1
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0 },
			{ 0, 0, 0, 1, 1, 1, 4, 0, 4, 3, 1, 0, 0, 0, 0 },
			{ 0, 0, 0, 1, 3, 0, 4, 5, 1, 1, 1, 0, 0, 0, 0 },
			{ 0, 0, 0, 1, 1, 1, 1, 4, 1, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 1, 3, 1, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
		},
		{//关卡2
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 1, 3, 3, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 1, 1, 0, 3, 1, 1, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 1, 0, 0, 4, 3, 1, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 1, 0, 4, 0, 0, 1, 1, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 0, 0, 1, 4, 4, 0, 1, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 0, 0, 5, 0, 0, 0, 1, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }

		},
		{//关卡3
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 1, 1, 1, 0, 3, 4, 0, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 1, 0, 4, 0, 0, 4, 0, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 1, 0, 0, 0, 1, 3, 0, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 1, 1, 1, 3, 0, 5, 1, 1, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
			{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
		}
};
//复制关卡
void CopyMap()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			game[i][j] = gameMap[level][i][j];
		}
	}
}
//从新开始
void anew()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			gameMap[level][i][j] = game[i][j];
		}
	}
	gscore = 0;
}
//将字符串写入windows窗口,并设置颜色
void WriteWchar(int x, int y, const char szString[], int attr)
{
	HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);//API
	COORD pos = { x * 2, y };
	SetConsoleTextAttribute(hOut, attr);
	SetConsoleCursorPosition(hOut, pos);
	printf("%s", szString);
}
//读文件
void readFile()
{
	WriteWchar(43, 5, ".............................", F_GREEN);
	WriteWchar(43, 6, ":", F_GREEN);
	WriteWchar(57, 6, ":", F_GREEN);
	WriteWchar(43, 7, ":", F_GREEN);
	WriteWchar(57, 7, ":", F_GREEN);
	WriteWchar(43, 8, ":", F_GREEN);
	WriteWchar(57, 8, ":", F_GREEN);
	WriteWchar(43, 9, ":", F_GREEN);
	WriteWchar(57, 9, ":", F_GREEN);
	WriteWchar(43, 10, ":", F_GREEN);
	WriteWchar(57, 10, ":", F_GREEN);
	WriteWchar(43, 11, ":", F_GREEN);
	WriteWchar(57, 11, ":", F_GREEN);
	WriteWchar(43, 12, ":", F_GREEN);
	WriteWchar(57, 12, ":", F_GREEN);
	WriteWchar(43, 13, ":", F_GREEN);
	WriteWchar(57, 13, ":", F_GREEN);
	WriteWchar(43, 14, ":", F_GREEN);
	WriteWchar(57, 14, ":", F_GREEN);
	WriteWchar(43, 15, ":", F_GREEN);
	WriteWchar(57, 15, ":", F_GREEN);
	WriteWchar(43, 16, ".............................", F_GREEN);
	WriteWchar(49, 7, "排行榜", F_GREEN);
	WriteWchar(45, 10, "关卡1最快步数:", F_GREEN);
	WriteWchar(45, 12, "关卡2最快步数:", F_GREEN);
	WriteWchar(45, 14, "关卡3最快步数:", F_GREEN);

	FILE *fp;
	int a[M];
	errno_t err;
	char str[20];
	err = fopen_s(&fp, "a.txt", "r");
	for (int i = 0; i < M; i++)
	{
		fscanf_s(fp, "%d", &a[i]);
		_itoa_s(a[i], str, 10);
		WriteWchar(55, 10 + 2*i, str, F_GREEN);
	}

	fclose(fp);
}
//欢迎界面
void drawPic(){
	//相对于电脑
	//定义四个坐标点
	COORD posDown = { 9, 0 };
	COORD  posUp = { 29, 41 };
	COORD  posRight = { 39, 11 };
	COORD  posLeft = { 0, 29 };
	//设定死循环

	int k = -20;
	while (true)
	{

		Sleep(100);
		if (k < 2)
		{

			system("cls");
			k++;
			if (k>0) WriteWchar(9, k, "            ■■■              ■■■■            ■■■■", F_YELLOW);
			if (k>-1) WriteWchar(9, k + 1, "            ■☆■              ■☆☆■            ■    ■■■", F_YELLOW);
			if (k>-2) WriteWchar(9, k + 2, "            ■  ■■■■      ■■  ☆■■      ■■■  ☆□  ■", F_YELLOW);
			if (k>-3) WriteWchar(9, k + 3, "        ■■■□  □☆■      ■    □☆■      ■  □    □  ■ ", F_YELLOW);
			if (k>-4) WriteWchar(9, k + 4, "        ■☆  □○■■■    ■■  □    ■■    ■      ■☆  ■", F_YELLOW);
			if (k>-5) WriteWchar(9, k + 5, "        ■■■■□■        ■    ■□□  ■    ■■■☆  ○■■", F_YELLOW);
			if (k>-6) WriteWchar(9, k + 6, "              ■☆■        ■    ○      ■        ■■■■■", F_YELLOW);
			if (k>-7) WriteWchar(9, k + 7, "              ■■■        ■■■■■■■■ ", F_YELLOW);

			if (k>-10) WriteWchar(9, k + 10, "       ■■■■■■   ■■               ■■       ■■    ■■                        ", F_RED);
			if (k>-11) WriteWchar(9, k + 11, "       ■■■■■■   ■■              ■■■       ■■  ■■                 ", F_RED);
			if (k>-12) WriteWchar(9, k + 12, "       ■■    ■■   ■■            ■■  ■■      ■■■■                   ", F_RED);
			if (k>-13) WriteWchar(9, k + 13, "       ■■    ■■   ■■           ■■    ■■      ■■■                   ", F_RED);
			if (k>-14) WriteWchar(9, k + 14, "       ■■■■■■   ■■           ■■■■■■       ■■", F_RED);
			if (k>-15) WriteWchar(9, k + 15, "       ■■■■■■   ■■           ■■■■■■       ■■   ", F_RED);
			if (k>-16) WriteWchar(9, k + 16, "       ■■           ■■■■■■   ■■    ■■       ■■                         ", F_RED);
			if (k>-17) WriteWchar(9, k + 17, "       ■■           ■■■■■■   ■■    ■■       ■■                             ", F_RED);
		}
		else
			break;
	}

	//分数
	readFile();
	//检测键盘是否输入,检测当前输入的键盘是否是enter键
	while (!(_kbhit() && _getch() == 0x0d)){
		WriteWchar(43, 24, "press enter to start", F_RED);

	}
	//清零屏幕
	system("cls");
}
//绘制游戏地图
void drawMap()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			switch (gameMap[level][i][j])
			{
			case 0:
				WriteWchar(j, i, "  ", F_YELLOW);
				break;
			case 1:
				WriteWchar(j, i, "■", F_YELLOW);
				break;
			case 3:
				WriteWchar(j, i, "☆", F_YELLOW);
				break;
			case 4:
				WriteWchar(j, i, "□", F_YELLOW);
				break;
			case 5:
				WriteWchar(j, i, "○", F_YELLOW);
				break;
			case 7:     //4 + 3  箱子在目的地中
				WriteWchar(j, i, "★", F_YELLOW);
				break;
			case 8:     // 5 + 3  人在目的地当中
				WriteWchar(j, i, "○", F_YELLOW);
				break;
			}
		}
	}
	//右边的设置
	WriteWchar(34, 2, "推箱子", F_H_GREEN);
	//绘制分数、等级、下一个方块
	WriteWchar(32, 5, "步数:", F_H_GREEN);
	WriteWchar(32, 7, "关卡:", F_H_GREEN);
	char buf[6] = { 0 };
	sprintf_s(buf, sizeof(buf), "%d", gscore);
	WriteWchar(36, 5, buf, F_H_GREEN);
	char buf1[6] = { 0 };
	sprintf_s(buf1, sizeof(buf1), "%d", level+1);
	WriteWchar(36, 7, buf1, F_H_GREEN);

	WriteWchar(32, 14, "操作说明:", F_H_GREEN);
	WriteWchar(37, 15, "W(上", F_H_GREEN);
	WriteWchar(37, 16, "A(左)", F_H_GREEN);
	WriteWchar(37, 17, "D(右)", F_H_GREEN);
	WriteWchar(37, 18, "S(下)", F_H_GREEN);

	WriteWchar(37, 20, "Q(退出)", F_H_GREEN);
	WriteWchar(37, 21, "T(从新开始)", F_H_GREEN);
}
//移动
int MoveMap()
{
	int r, c;  //人的坐标
	for (int i = 0; i < 9; i++)
	{
		for (int j = 0; j < 11; j++)
		{
			if (gameMap[level][i][j] == 5 || gameMap[level][i][j] == 8)   //i j 人的下标
			{
				r = i;
				c = j;
			}
		}
	}

	char ch;  //字符变量
	ch = _getch();  //键盘的输入保存到字符中
	switch (ch)
	{
	case 'W':  //W A S D方向   72  80  75  77 虚拟键值
	case 'w':
	case 72:
		if (gameMap[level][r - 1][c] == 0 || gameMap[level][r - 1][c] == 3)
		{
			gameMap[level][r - 1][c] += 5;
			gameMap[level][r][c] -= 5;
			gscore++;
		}
		else if (gameMap[level][r - 1][c] == 4 || gameMap[level][r - 1][c] == 7)
		{
			if (gameMap[level][r - 2][c] == 0 || gameMap[level][r - 2][c] == 3)
			{
				gameMap[level][r - 2][c] += 4;
				gameMap[level][r - 1][c] += 1;
				gameMap[level][r][c] -= 5;
				gscore++;
			}
		}
		break;

	case 'S':  //enter按键的作用  确认 返回
	case 's':
	case 80:
		if (gameMap[level][r + 1][c] == 0 || gameMap[level][r + 1][c] == 3)
		{
			gameMap[level][r + 1][c] += 5;
			gameMap[level][r][c] -= 5;
			gscore++;
		}
		else if (gameMap[level][r + 1][c] == 4 || gameMap[level][r + 1][c] == 7)
		{
			if (gameMap[level][r + 2][c] == 0 || gameMap[level][r + 2][c] == 3)
			{
				gameMap[level][r + 2][c] += 4;
				gameMap[level][r + 1][c] += 1;
				gameMap[level][r][c] -= 5;
				gscore++;
			}
		}
		break;

	case 'A':
	case 'a':
	case 75:
		if (gameMap[level][r][c - 1] == 0 || gameMap[level][r][c - 1] == 3)
		{
			gameMap[level][r][c - 1] += 5;
			gameMap[level][r][c] -= 5;
			gscore++;
		}
		else if (gameMap[level][r][c - 1] == 4 || gameMap[level][r][c - 1] == 7)
		{
			if (gameMap[level][r][c - 2] == 0 || gameMap[level][r][c - 2] == 3)
			{
				gameMap[level][r][c - 2] += 4;
				gameMap[level][r][c - 1] += 1;
				gameMap[level][r][c] -= 5;
				gscore++;
			}
		}
		break;

	case 'D':
	case 'd':
	case 77:
		if (gameMap[level][r][c + 1] == 0 || gameMap[level][r][c + 1] == 3)
		{
			gameMap[level][r][c + 1] += 5;
			gameMap[level][r][c] -= 5;
			gscore++;
		}
		else if (gameMap[level][r][c + 1] == 4 || gameMap[level][r][c + 1] == 7)
		{
			if (gameMap[level][r][c + 2] == 0 || gameMap[level][r][c + 2] == 3)
			{
				gameMap[level][r][c + 2] += 4;
				gameMap[level][r][c + 1] += 1;
				gameMap[level][r][c] -= 5;
				gscore++;
			}
		}
		break;
	case 'q':    //退出
	case 'Q':
		return 0;
	case 'T':   //从新开始
	case 't':
		anew(); // 从新开始当前关卡
	}
	return 1;
}
//是否胜利
BOOL isWin()
{
	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (gameMap[level][i][j] == 3 || gameMap[level][i][j] == 4)
				return false;
		}
	}
	return true;
}
//绘制胜利界面
void Winter()
{
	system("cls");
	WriteWchar(9, 10, "       ■■        ■■        ■■    ■■■■      ■■■       ■■                         ", F_RED);
	WriteWchar(9, 11, "        ■■      ■■■      ■■       ■■        ■■■■     ■■                 ", F_RED);
	WriteWchar(9, 12, "         ■■    ■■■■    ■■        ■■        ■■  ■■   ■■            ", F_RED);
	WriteWchar(9, 13, "          ■■  ■■  ■■  ■■         ■■        ■■   ■■  ■■             ", F_RED);
	WriteWchar(9, 14, "           ■■■■    ■■■■          ■■        ■■    ■■ ■■            ", F_RED);
	WriteWchar(9, 15, "            ■■■      ■■■           ■■        ■■     ■■■■    ", F_RED);
	WriteWchar(9, 16, "             ■■        ■■          ■■■■      ■■       ■■■                         ", F_RED);

	WriteWchar(27, 20, "exit:q", F_RED);
	WriteWchar(27, 23, "continue:r", F_RED);
}
//写文件
void writeFile()
{
	FILE *fp;
	int a[M];
	errno_t err;
	char str[20];
	err = fopen_s(&fp, "a.txt", "r");
	for (int i = 0; i < M; i++)
	{
		fscanf_s(fp, "%d", &a[i]);
		_itoa_s(a[i], str, 10);
		WriteWchar(55, 10 + 2 * i, str, F_GREEN);
	}

	fclose(fp);

	if (a[level] == 0 || gscore < a[level])
	{
		a[level] = gscore;
		err = fopen_s(&fp, "a.txt", "w");
		fprintf_s(fp, "%d\n", a[0]);
		fprintf_s(fp, "%d\n", a[1]);
		fprintf_s(fp, "%d\n", a[2]);
		fclose(fp);
	}
}
//结束界面
void GameOver()
{
	system("cls");
	WriteWchar(9, 10, "         ■■        ■■           ■■   ■■■■■   ■■■■■■                          ", F_RED);
	WriteWchar(9, 11, "      ■■  ■■      ■■         ■■    ■■■■■   ■■■■■■         ", F_RED);
	WriteWchar(9, 12, "    ■■      ■■     ■■       ■■     ■■         ■■    ■■            ", F_RED);
	WriteWchar(9, 13, "   ■■        ■■     ■■     ■■      ■■■■■   ■■■■■■              ", F_RED);
	WriteWchar(9, 14, "   ■■        ■■      ■■   ■■       ■■■■■   ■■■■              ", F_RED);
	WriteWchar(9, 15, "    ■■      ■■        ■■ ■■        ■■         ■■ ■■     ", F_RED);
	WriteWchar(9, 16, "      ■■  ■■           ■■■          ■■■■■   ■■   ■■                   ", F_RED);
	WriteWchar(9, 17, "         ■■               ■■           ■■■■■   ■■    ■■                         ", F_RED);

	while (true){
		WriteWchar(43, 24, "exit:q", F_RED);
		if (_getch() == 'q')
		{
			break;
		}
	}
}

//开始游戏
 int PleyGame()
{
	drawMap();//绘制游戏地图
	CopyMap(); //复制关卡
	while (true)
	{
		if (gscore > limit[level])
		{
			WriteWchar(12, 7, "超过步数失败按enter从新开始", F_RED);
			gscore = 0;
			anew();
			while (!(_kbhit() && _getch() == 0x0d))
			{
			}
		}
		if(!MoveMap())  // 移动,退出
			return 0;
		system("cls");
		drawMap();//绘制游戏地图
		if (isWin())
		{
			writeFile();
			gscore = 0;
			level = (level + 1);
			CopyMap(); //复制关卡
			if (level >= M)  //超过规定关卡则退出
				return 0;
			Winter(); //绘制胜利界面
			while (true)
			{
				if (_getch() == 'q')
				{
					return 0;
				}
				if (_getch() == 'r')
				{
					system("cls");
					drawMap();
					break;
				}
			}
		}
	}
	return 0;
}

C++

2021.6.7

友元:朋友,要使用成员仍必须通过对象 friend
静态成员:属于类,静态成员在类外定义 static
using有多少使用方式
constexprconst
四种对象的使用
int a; int *p; int arr[3]; int &ap = a;
类名 a; 类名 *p=nullptr;(NULL) 类名 arr[3]; 类名 &p = a;
抽象类至少拥有一个纯虚函数,此类不能定义对象,可以定义对象指针或引用
抽象类一般都是作为父类存在

coutcin都是对象

#include<iostream>

//istream  ostream
//using namespace std;
int main()
{
	int a = 3;
	char str[3] = "sa";
	std::cout << "3" << std::endl;
	std::cout << a << std::endl;
	std::cout << str << std::endl;

	getchar();
	return 0;
}
3
3
sa
#include<iostream>

using namespace std;
int main()
{
	int a = 3;
	char str[3] = "sa";
	cout << "3" << endl;
	cout << a << endl;
	cout << str << endl;

	getchar();
	return 0;
}
3
3
sa

#include<iostream>

using namespace std;
namespace ddd{
	int a = 3;
};
int a = 2;
int main()
{
	int a = 7;
	cout << "a=" << ::a << endl; // 5   ::前没加相当于全局变量
	cout << "a=" << ddd::a << endl; // 3  ::前有ddd相当于ddd域里的变量
	cout << "a=" << a << endl; // 7   前面什么都没有为该区域变量

	getchar();
	return 0;
}
a=2
a=3
a=7

静态成员

#include<iostream>

using namespace std;
void func();

int main()
{
	//静态成员:只初始化一次,它有记忆功能,最后才释放空间,下回使用时会计入上次的值
	//a为静态成员,b不是
	//第一次定义a=5,b=4,a++,结果a=6,b=10
	func();//a=6,b=10
	//第二次使用上一次的值,即a=6,b=4
	func();//a=7,b=11
	//第三次使用上一次的值,即a=7,b=4
	func();//a=8,b=12


	getchar();
	return 0;
}

void func()
{
	static int a = 5;
	int b = 4;
	a++;
	b = a + b;
	cout << "a=" << a << ",b=" << b << endl;
}
a=6,b=10
a=7,b=11
a=8,b=12

#include<iostream>
using namespace std;

//class/struct有相同的作用
//默认为public公有属性
struct students{ //students类名->类类型名
private:
	int a;//不能在这直接给值,这里没有空间
public:
	//const只能修饰类中函数,成为常函数
	//常函数只能获取值,不能修改值,即const只能获取值,不能修改值
	int getA()const; //void getA();
	void setA(int a); // void setA();
}s1;//对象名

int students::getA()const
{//类中的函数可以使用类中所有成员,不需要通过对象
	return a;//cout<<a<<endl;
}

void students::setA(int a)
{//通过传入参数a给本对象的私有成员a赋值
	this->a = a;//cin>>a;
}

//默认为private私有属性
class Student{ //
	int b;//私有
}s2;

int main()
{//类外所定义的对象只能用类中的公有成员
//在类外函数要使用类中成员,必须通过对象(只有对象才是实体)
	//int a;int*p;int arr[3];int &ap;
	//对象创建时系统自动调用构造函数,给其数据成员初始化    上面有new
	//对象结束时系统自动调用析构,                      下面就有delete
	students stu, *sut1 = nullptr, arr[3];//0-2
	stu.setA(3);
	cout<<stu.getA()<<endl;//3

	//*sut1 = nullptr
	stu1 = &stu;
	(&stu)->setA(4);
	(*stu1).setA(5);
	stu1->setA(6);
	cout<<stu1->getA()<<endl; // 6
	
	for (int i = 0; i < 3; i++)
	{
		arr[i].setA(i+2);//(arr+i)->setA(i+2);
	}
	for (int i = 0; i < 3; i++)
	{
		cout << arr[i].getA() << endl;
	}

	getchar();
	return 0;
}
//enum web{a, b=2, c}; //无赋值为0
enum class web{a, b, c};

int main()
{
	int k;
	//k = a;//隐式转换 
	k=static_cast<int>(web::a); //显示类型转换
	k = (int)web::a; //强转
	cout << k << endl; //0

	getchar();
	return 0;
}

左值引用

#include<iostream>
using namespace std;
//左值引用
class AAA{
	int x, y; //数据成员->属性
public:
	//成员函数->方法->数据处理
	void setInfo(int a, int b);
	int getX()const;
	int getY()const;
};

void AAA::setInfo(int a, int b)
{
	x = a;
	y = b;
}
int AAA::getX()const
{
	return x;
}
int AAA::getY()const
{
	return y;
}

/*void swap(int, int);//值传递
void swap(int*, int*);//指针传递
*/
void swap(int&a, int&b)//引用传递
{
	int temp;
	temp = a;
	a = b;
	b = temp;
}


int main()
{//左值引用是给响应的变量取别名,不会分配自己的空间
	//引用必须定义时给其赋初值,赋的必须是变量名
	//引用名用法与普通变量名用法相同
	int a = 3;
	int &b = a;//int &b;会报错,没有初始化
	cout << "a=" << a << ",b=" << b << endl;//a=3b=3
	cout << "&a=" << &a << ",&b=" << &b << endl;//&a=00CFFEAC&b=00CFFEAC
	AAA a1;//通过AAA类类型定义对象a1
	AAA &b1 = a1;//给a1取别名b1
	b1.setInfo(3, 4);
	cout << "b1.x=" << b1.getX() << ",b1.y=" << b1.getY() << endl;//b1.x=3,b1.y=4


	int a=3, b=4;
	swap(a, b);

	getchar();
	return 0;
}

6.8

输入

cin get(),getline(),read()
gcount(),ignore(),sync(),clear()

char str;
str = cin.get();//原型int get(); 
cout << "str=" << str << endl;
q
str = q

形式不一样,含义一样

cin.get(str);//istream& get(char&c)   //char&c = str;
cout << "str=" << str << endl;
q
str = q
	char str[20];
	cin.getline(str, 20); //首地址,字符长度 可以获取空格
	cout << str << endl;
ahge rglieg a
ahge rglieg a
	char str[20];
	cin.getline(str, 20, '#');//读取字符从#结束
	cout << str << endl;
dsfer#w
dsfer
	char str[20];
	cin.read(str, 20);//块语句读法,只有满足字符长度才结束,可以获取换行,空格等
	cout << "str=" << str << endl;
afe gg
ger grege
fsg er
str=afe gg
ger grege
fsg烫烫E^彎曾
	char str[20];
	cin.get(str, 20);
	cout << "input char number:" << cin.gcount() << endl;
awef fwef
input char number : 9
	char str[20];
	cin.getline(str, 5);//Study C++!
	cout << str << endl;//Stud
	cin.clear();//设置失效位,从新打开输入流
	cin.getline(str, 20);//y C++!
	cout << str << endl;
Study C++!
Stud
y C++!
	int m;
	cin >> m;
	char str[20];
	cin.ignore();//cin.ignore(int);cin.ignore(int,char);
	cin.getline(str, 20);
	cout << "m=" << m << endl;
	cout << "str=" << str << endl;
5
f er sdf
m=5
str=f er sdf
	int m;
	cin >> m;
	char str[20];
	//cin.ignore();
	cin.getline(str, 20);
	cout << "m=" << m << endl;
	cout << "str=" << str << endl;
忽略cin.ignore();
5
m=5
str=
cin.sync();//清空输入缓冲区
	int a;
	bool b;
	char c;
	double d;
	//cin >> a >> b >> c >> d;//需要对应格式输入,空格区分
	//cout << a << b << c << d;

	cin >> a;
	//cin >> b;//bool输入0,1
	cin >> boolalpha >> b;
	cout << a << " " << boolalpha << b << endl;
	int a = 17;
	cout << hex << a;//十六进制输出
	float a = 17.6;
	cout << hexfloat << a;
#include<cstdio> //stdio.h
#include<cmath> //math.h
#include<cstring>//srlen,strcpy

string

#include<string>
	int a(1), b = 2;//给a,b赋除值
	cout << a << endl;//1
	cout << b << endl;//2
	char str[] = "中国江西"; //一个中文两个字符,反斜杠结束符为一个字符
	cout << sizeof(str) / sizeof(char) << endl; //9

	string s1 = "This is a test string ";
	string s2("teacher"); //使用字符串常量初始化
	//string(string&,int n);
	string s3(s1); //使用string对象初始化,对象给新对象赋初值
	string s4(str, 4); //使用字符数组前4个字符初始化
	string s5(s1, 10, 12);//使用string对象子串初始化,10起始位,12长度
	cout << "s1:" << s1 << endl;
	cout << "s2:" << s2 << endl;
	cout << "s3:" << s3 << endl;
	cout << "s4:" << s4 << endl;
	cout << "s5:" << s5 << endl;
9
s1:This is a test string
s2:teacher
s3:This is a test string
s4:中国
s5:test string

内存动态分配new,delete

void test()
{
	//内存动态分配
	//int *p=&a;->int *p=NULL;p=&a;
	//int *p = new int(3); ->int *p = nullptr; p = new int(3);
	int *p = new int(3);//动态申请整形变量地址,返回给p,并且给其赋初值为3	
	cout << "*p=" << *p << endl;
	delete p;//先释放,才能执行下面的分配
	//动态分配4个连续整形空间,将其首地址返回给p,没赋值的为0
	p = new int[4]{1, 2, 3};
	for (int i = 0; i < 4; i++)
		cout << *(p + i) << " ";
	cout << endl;
	delete []p;
	p = nullptr;
}
*p=3
1 2 3 0
void test()
{
	string*str = new string("sad");
	cout << *str << endl;//sad
	delete str;
	str = new string[3]{"da", "asd"};
	for (int i = 0; i < 3; i++)
		cout << *(str + i) << " ";//da asd
	cout << endl;
	delete []str;
	str = nullptr;
}
void test()
{
	char*ch = new char('a');
	cout << *ch << endl;//a
	delete ch;
	ch = new char[6]{'a','b','c','d'};
	for (int i = 0; i < 6; i++)
		cout << *(ch + i) << " "; //a b c d
	cout << endl;
	delete []ch;
	ch = nullptr;
}

6.9

左值引用,右值引用

#include<iostream>
#include<stdlib.h>
#include<string>

using namespace std;
//namespace防止命名冲突
int main()
{
	//左值引用
	int a = 3;
	int &b = a;
	int&& p = 3;//右值引用
	//不可以int&& p=a,可以int&& p=a+2
	//int&& p=move(a),a地址被移除,不能再被使用,move来自std::move(),move(a)只能用一次
	cout << "&p=" << &p << endl;
	/*
	int a=3;
	int&& p=move(a);
	int&& d=move(p);//可以
	*/
	system("pause");
	return 0;
}

取别名

typedef unsigned int u16;
using u16 = unsigned int;//等同于上一行
#define u16 unsigned int;//等同于上一行

const不能改变

void test()//const修饰谁谁不变
{
	//1.常函数->类中函数,不改变其中的值
	int b = 3;
	const int a = 2;//a不能变,不能出现a=
	const int *p = nullptr;//p指针变量可以重新赋值,*p常量,不能变,不能出现*p=
	p = &a;
	//*p = 4; //错误
	int const *p1 = nullptr; //p1指针变量可以重新赋值,*p1常量,不能变,不能出现*p1=
	p1 = &a;
	//*p1 = 5;//错误
	int * const p2 = &b; //p2指针常量,不能出现p2=,*p2属于变量可变
	//p2 = &a;//错误
	*p2 = 3; //int * const p2 = nullptr未给初值这行会报错
	const int const *const p3 = &a;
}

值传递,指针传递,引用传递

//函数原型/声明
int Max(int, int);//int Max(int a, int b);

int main()
{
	int a1 = 3, b1 = 4;
	cout << "Max=" << Max(3, 4) << endl;//值传递
	cout << "Max=" << Max(a1, b1) << endl;//值传递

	system("pause");
	return 0;
}
//值传递:
//1.实参值复制一份给形参
//2.形参会有自己的空间
//3.实参传给形参,单向传递
int Max(int a, int b)
{
	return a > b ? a : b;
}

指针传递

//函数原型/声明
int* Max(int*, int*);
int main()
{
	int a1 = 3, b1 = 4;
	cout << "Max=" << *Max(&a1, &b1) << endl;//指针传递

	system("pause");
	return 0;
}
//指针传递:形参3个存放地址的空间
int* Max(int *a, int *b)
{
	return *a > *b ? a : b;
}

引用传递

int &Max(int &, int&);

int main()
{
	int a1 = 3, b1 = 4;
	cout << Max(a1, b1) << endl;

	system("pause");
	return 0;
}

//引用传递,形参不申请任何空间
int &Max(int &a, int& b)//int&a=a1;
{
	return a>b ? a : b;
}
	int arr[10] = { 1, 2 };
	int (&p)[10] = arr;
	cout << p[0] << endl;
int max(int *, int n);
int &max1(int(&p)[5], int n);

int main()
{
	int a[5] = { 2, 6, 3, 4, 8 };
	cout << max(a, 5) << endl;
	cout << max1(a, 5) << endl;
	system("pause");
	return 0;
}

int max(int *p, int n)
{
	int a = *p;
	for (int i = 1; i < n; i++)
	{
		if (a < *(p+i))
			a = *(p+i);
	}
	return a;
}

int &max1(int(&p)[5], int n)
{
	int a = p[0],j = 0;
	for (int i = 1; i < n; i++)
	{
		if (a < p[i])
		{
			a = p[i];
			j = i;
		}
	}
	return *(p+j);
}
//指针讲究的是指向问题
//默认参数,必须是在函数调用前给定  声明用int add(int,int)  函数用int add(int a,int b=3)报错,只能int add(int a,int b)
//默认参数,必须从右往左连续给定,不能有间隔,可以int add(int,int=3,int=4);不能int add(int,int=3,int);
int add(int, int, int = 4);

函数重载

//函数重载:函数名相同
//条件
//1.参数个数不同
//2.参数类型不同
//3.参数个数和参数类型均不同
//注意:只有返回值不能判定函数重载,比如int add(); double add();这两个不能重载
int add(int, int, int = 4);
int add(int);//与上一行构成重载函数

内联函数

//内联函数内部不存在结构化语句,使用时是直接替换,没有进行函数调用
//与函数调用相比,不会有保护现场,恢复现场的情况,使用时是直接替换
inline int add()//类似于define
{
	return 1 + 2;
}
class Base{
	//数据->数据成员  属性
	int x;
public:
	//数据处理->成员函数  方法
	//设置
	void setX(int i){x = i;}
	//获取
	int getX()const{ return x; }
};

6.10

// 赋值运算operator=();
// 类外函数要使用类中成员(非静态成员)必需通过对象,而且通过对象能使用的自由公有函数
class Dog{ // Dog是类类型   //typedef class Dog{ }ddd;  //class Dog{ }ddd;ddd是Dog类型所定义的对象
	// private权限下的成员只能本类成员直接用。其他要使用该成员必须通过本类对象(友元),或者本类公有函数
private: // 私有权限
	int x;
	// 属性
	// 本类成员可以直接用,派生类成员也可以直接用(要看继承方式),类外不能直接用,也不能通过对象使用
protected: // 保护权限
	int y;
	// 类中成员可以直接用,派生类成员也可以直接用,类外需要通过对象使用
public: // 公有权限
	void setX(int a);
	void SetY(int b);
	int getX()const;
	int getY()const;
};
class Dog{
private: // 私有权限
	int x;

protected: // 保护权限
	int y;

public: // 公有权限
	void setX(int a);
	void SetY(int b);
	int getX()const;
	int getY()const;
}ddd;           //

void Dog::setX(int a)
{
	x = a;
}
void Dog::SetY(int b)
{
	y = b;
}
int Dog::getX()const
{
	return x;
}
int Dog::getY()const
{
	return y;
}
int main()
{
	Dog d;
	d.setX(3);
	ddd.setX(3);
	cout << "d.x=" << d.getX() << "   ddd.x=" << ddd.getX() << endl;

	system("pause");
	return 0;
}

构造函数,析构函数

在return后设置断点,不然运行不会出现析构函数效果

/*构造函数
构造函数名与类名相同
构造函数没有返回值类型(void也不存在)
对象创建时由系统自动调用
构造函数放在public下面
构造函数可以写出内联函数形式
构造函数可以重载
在类中没有显示定义构造与析构,系统会提高默认无参构造与析构
*/

/*析构函数
析构函数名与类名相同,并且加~
析构函数没有返回值类型(void也不存在)
对象结束时由系统自动调用
析构函数放在public下面
析构函数可以写出内联函数形式
每个类只有一个析构
在类中没有显示定义构造与析构,系统会提高默认无参构造与析构
*/

class Dog{
private: // 私有权限
	int x;

protected: // 保护权限
	int y;//*y  Dog(int a=0){ y = new int(a); }   //*y=3错误  先给地址,再拿值
	
public: // 公有权限
	/*只要类中显示写出任意一个构造,系统都不会再提供默认构造函数*/
	//Dog() = default; //系统默认无参构造
	Dog(int a, int b){ x = a; y = b; } //构造函数的作用是给成员赋初值
	Dog(int a=0){ x = a; } //Dog();Dog(int);
	~Dog(){ cout << "Distruce " << x << endl; }
};
//先构造,后析构

int main()
{/*构建怎样的对象就应该拥有怎样的构造函数*/
	Dog d, d1(3);//对象d创建时系统自动调用无参函数
	Dog d2(2, 3);

	system("pause");
	return 0;
}

拷贝构造

/*什么时候调用拷贝构造?
1.对象给新对象赋初值
2.对象作为函数参数
3.对象作为返回值
*/
class Dog{
private: // 私有权限
	int x;

protected: // 保护权限
	int y;//*y  Dog(int a=0){ y = new int(a); }   //*y=3错误  先给地址,再拿值
	
public: // 公有权限
	//构造函数只要参数与系统默认不同,就不会覆盖,系统仍会提供
	Dog(int x=3){ this->x = x; y = 4; }
	Dog(Dog&d, int n = 2){ x = n; cout << "copy construct!" << x << endl; }//拷贝构造
	~Dog(){ cout << "Distruce " << x << endl; }

};
void test(Dog d)//函数参数
{

}
Dog test1(Dog d)
{
	return d;//拷贝
}

int main()
{
	Dog d;
	Dog d1(d, 1);//调用拷贝构造函数
	test(d);//对象成员作为函数参数
	test1(d);//拷贝
	//system("pause");
	return 0;
}
class B{};

class Base{
private: 
	Base *b1; //Base b;错误
	Base &b2;
	B b3,*b4,&b5;
	//auto d;//错误
	int a;
	const int c2;
	decltype(a) b6; //获取a的类型递给b6,b6与a的类型一样
	static int b7;
	//extren int c1;//错误
	//constexpr int c3;//错误

public://构造函数一定现实写出:成员里面拥有带参的对象成员,常成员
	Base(int a1):a(a1){}

};
	auto a = 2;//数据什么类型,自动给什么类型,不能放类中
	decltype(a) b;//获取a的类型递给b
class B{
	int b;
public:
	B(int b = 8){ this->b = b; cout << "con" << b << endl; }
};

class Base{
private: //由声明的顺序决定构建顺序
	B b3, &b2;
	int a;
	//Base &b1;
	const int c2, c3;

public://构造函数一定现实写出:成员里面拥有带参的对象成员,常成员
	//如果拥有常量成员,必须用初始化列表形式给其赋初值
	//如果拥有对象成员,拥有无参构造,可以不写初始化列表
	//如果该类没有无参构造,必须在该类中显示写出构造函数用初始化列表进行给其初始化
	//对象的引用要通过初始化列表赋初值
	Base(int a1) :c2(a1),c3(5), b2(b3), b3(a1){}
	Base() :c2(2), c3(5), b2(b3), b3(3){ cout << "con" << c2 << endl; }

};
int main()
{
	Base b;//基类先构造->对象成员->派生类构造


	//system("pause");
	return 0;
}

深拷贝,浅拷贝

//深拷贝,浅拷贝
struct AString{
private:
	int *p;
public:
	AString(){ p = new int(3); }//p=new int;*p=3;
	AString(AString&);
	//如果构造出现new,那么就得显示写出析构delete
	~AString(){ delete p; }

};
//对象给新对象赋初值,对象做参数,对象做返回值
AString::AString(AString&s1)//浅拷贝,拷贝值和空间
{
	p = s1.p;//存在多次析构同一个地址问题
}

int main()
{
	AString s;//AString()
	AString s1(s);//Astring(Astring&)

	//system("pause");
	return 0;
}
AString::AString(AString&s1)//深拷贝
{
	p = new int;//只拷贝值,空间自己解决,解决了浅拷贝存在多次析构同一个地址的问题
	*p = *s1.p;
}
struct AString{
private:
	char *str;
public:
	AString(const char*s = " ");//构造
	AString(AString&);//拷贝
	AString& operator=(AString&);//赋值运算符函数

	AString(AString&&);//移动拷贝构造
	AString& operator=(AString&&);//移动赋值运算符函数

	//如果构造出现new,那么就得显示写出析构delete
	~AString(){ delete []str; }

};
AString::AString(const char*s = " ")//构造
{
	str = new char[strlen(s) + 1];//根据传入参数的大小,分配相应的空间
	strcpy(str, s);//将传入参数值赋给成员变量
}
AString::AString(AString&s)//拷贝
{
	str = new char[strlen(s.str)+1];
	strcpy(str, s.str);
}
AString& AString::operator=(AString&s)//赋值运算符函数
{
	//先判定是够是自赋值情况
	if (this == &s)return *this;
	//不是自赋值情况下,先清除自己的空间,申请相应空间存放所需要存放数据
	delete []str;
	str = new char[strlen(s.str) + 1];
	strcpy(str, s.str);
	return *this;
}
AString::AString(AString&&s)//移动拷贝构造
{
	str = new char[strlen(s.str) + 1];
	strcpy(str, s.str);
}
AString& AString::operator=(AString&&s)//移动赋值运算符函数
{
	//先判定是够是自赋值情况
	if (this == &s)return *this;
	//不是自赋值情况下,先清除自己的空间,申请相应空间存放所需要存放数据
	delete[]str;
	str = new char[strlen(s.str) + 1];
	strcpy(str, s.str);
	return *this;
}
int main()
{
	AString s("abcd");
	AString s1;
	//当类中出现构造或者构造拷贝,那么系统不会提供移动构造
	s1 = s;
	s1 = move(s);//AString& operator=(AString&&);

	int a = 3;
	int &&b = move(a);

	//system("pause");
	return 0;
}
//怎么通过指针使用类中成员
class B{

public:
	int i, j;
	void setI(int a){ i = a; }
	void setJ(int b){ j = b; }
	int getI()const{ return i; }
	int getJ()const{ return j; }
};

int main()
{
	int B::*p;
	void (B::*t)(int);
	int (B::*q)()const;
	t = &B::setI;
	p = &B::i;
	q = &B::getI;
	B b;
	b.*p = 2;//b.i=2;
	cout << (b.*q)() << endl;//b.getI()

	//system("pause");
	return 0;
}

静态成员static

//static
//静态成员初始化
//静态成员属于类,不属于对象
class DemoStatic{
public:
	//int i;
	static int a;
	int getA()const{ return a; }

};
//int DemoStatic::i = 2; //错误,普通成员只能通过对象
//int DemoStatic::a;//静态成员初始化,默认值为0
int DemoStatic::a = 2;//静态成员初始化,默认值为2

int main()
{
	cout << DemoStatic::a << endl;
	DemoStatic v1;
	v1.a = 77;
	cout << DemoStatic::a << endl;
	DemoStatic::a = 111;
	cout << DemoStatic::a << endl;

	cout << DemoStatic::getA << endl;
	//system("pause");
	return 0;
}

友元函数friend->属于类外函数

普通函数作为类中友元函数

class DemoFriend{
	int x;
public:
	DemoFriend(int a = 3){ x = a; }
	friend int add(DemoFriend&);//普通函数定义为友元函数->类外函数
};

int add(DemoFriend&d)//友元函数在类外定义不需要使用类名::函数名
{
	return d.x + 3;//友元函数可以使用类中所有成员,但是必须通过对象
}

int main()
{
	DemoFriend d1;
	cout << add(d1) << endl;
	
	return 0;
}

扩展:

class DemoFriend{
	int x;
public:
	DemoFriend(int a = 3){ x = a; }
	int add();//类中成员函数
};
int DemoFriend::add()//类中成员函数在类外,需要使用类名::函数名
{
	return x + 3;//成员函数用私有成员直接用
}

void add()//普通函数
{
	DemoFriend d(4);
	cout << "成员:" << d.add() << endl;
	cout << "友元:" << add(d) << endl;
}

int main()
{
	DemoFriend d1;
	cout << d1.add() << endl;
	add();

	return 0;
}

成员函数作为另一个类的友元函数

class DemoFriend;
class C{
	int y;
public:
	C() :y(11){}
	int add(DemoFriend&);//C类的成员函数
};
class DemoFriend{
	int x;
public:
	DemoFriend(int a = 3){ x = a; }
	friend int C::add(DemoFriend&);//普通函数定义为友元函数->类外函数
};
//C类中成员函数为DemoFriend类的友元函数
int C::add(DemoFriend&d)
{
	return y + d.x;
}

int main()
{
	C c1;
	DemoFriend d;
	cout << c1.add(d) << endl;

	//system("pause");
	return 0;
}

一个类称为另一个类的友元

class DemoFriend;
class C{
	int y;
public:
	C() :y(11){}
	void set();
	int add(DemoFriend&);//c类的成员函数
};
class DemoFriend{
	int x;
public:
	DemoFriend(int a = 3) :x(a){}
	friend class C;//该类属于DemoFriend的友类
};
//C类中成员函数为DemoFriend类的友元函数
int C::add(DemoFriend&d)
{
	return y + d.x;
}
void C::set(){
	DemoFriend m;
	y = m.x;
}
int main()
{
	C c1;
	DemoFriend d;
	c1.set();
	cout << c1.add(d);//6
	return 0;
}

6.16

继承

/*
单继承
class 派生类名:继承权限 基类名{};

继承权限:private、protected、public

多继承
class 派生类名:继承权限 父类名1,继承权限(可省) 父类名2 ...{};
*/
class Base{
private:
	int i;
protected:
	int j;
public:
	int k;
	void setI(int a){ i = a; }
	int getI()const{ return i; }
	
};
//任何继承方式,基类的私有成员在子类当中不能直接用
//子类继承 父类,单继承
struct Derived:Base{ //public方式继承
	void print();
};
void Derived::print()
{
	j = 4;//父类当中的保护在子类担当者可以直接用
	setI(5);//父类中的私有只能通过公有函数
	cout <<"i="<< getI() << "\tj=" << j << "\tk=" << k << endl;
}

int main()
{
	Derived d;
	//d.setI(3);
	//d.j = 4;
	d.k = 5;
	d.print();
	

	return 0;
}
//继承
单继承
class 派生类名:继承权限 基类名{};

继承权限:private、protected、public

多继承
class 派生类名:继承权限 父类名1,继承权限(可省) 父类名2 ...{};
/*
公有继承:
基类的私有成员派生类中必须通过基类公有函数直接用
基类中的保护成员也是派生类的保护成员,在派生类中可以直接用
基类中的公有成员也是派生类中的公有成员,在派生类中可以直接用

私有继承:
基类的私有成员派生类中必须通过基类公有函数直接用
基类中的保护成员也是派生类的私有成员,在派生类中可以直接用
基类中的公有成员也是派生类中的私有成员,在派生类中可以直接用

保护继承:
基类的私有成员派生类中必须通过基类公有函数直接用
基类中的保护成员也是派生类的保护成员,在派生类中可以直接用
基类中的公有成员也是派生类中的保护成员,在派生类中可以直接用
*/
class Derived:Base{ //private方式继承
public:
	void print();
};

struct Derived:Base{ //public方式继承
	void print();
};
#include<iostream>
#include<stdlib.h>
#include<string>
#include<iomanip>
using namespace std;

class Base{
private:
	int i;
protected:
	int j;
public:
	int k;
	void setI(int a){ i = a; }
	int getI()const{ return i; }
};
//任何继承方式,基类的私有成员在子类当中不能直接用
//子类继承 父类,单继承
class Derived:Base{ //private方式继承
public:
	void print();
};
void Derived::print()
{
	j = 4;//父类当中的保护在子类担当者可以直接用
	setI(5);//父类中的私有只能通过公有函数
	cout <<"i="<< getI() << "\tj=" << j << "\tk=" << k << endl;
}

int main()
{
	Derived d;
	//d.setI(3);
	//d.j = 4;
	//d.k = 5;//k成为子类私有
	d.print();
	
	return 0;
}
class Base{
private:
	int i;
public:
	Base(){ cout << "Base construct" << endl; }
	~Base(){ cout << "~Base construct" << endl; }
};

class Derived:public Base{
public:
	Derived(){ cout << "Derived construct" << endl; }
	~Derived(){ cout << "~Derived construct" << endl; }
};

int main()
{
	Derived d;

	return 0;
}
class Base{
private:
	int i;
public:
	Base(int i){ this->i = i; cout << "Base construct "<< i << endl; }
	~Base(){ cout << "~Base construct " << i << endl; }
};

class Derived:public Base{
	Base b1, b2;
public:
	//所有类中的对象成员初始化,必须在列表
	Derived():Base(2), b1(3), b2(4){ cout << "Derived construct" << endl; }
	~Derived(){ cout << "~Derived construct" << endl; }
};
//基类-对象成员-派生类
int main()
{
	Derived d;
	
	return 0;
}
/*
根据声明顺序
Base construct 2
Base construct 3
Base construct 4
Derived construct
~Derived construct
~Base construct 4
~Base construct 3
~Base construct 2
*/

6.17

//1.不能将派生类对象赋给基类指针

	//静态类型和动态类型
	//静态是编译时确定
	//动态是运行时确定
	//不存在从基类向派生类隐士转换:即不存在Dri*d=new Base; 和Base b1;  Dri&d=b1;
	//对象之间不存在类型转换 Dri d1; Base b1(d1);调用拷贝构造//Base&b=d1;

class Base{
	int x;
public:
	Base() :x(3){ cout << "constructor " << endl; }
	~Base(){}
	void print(){ cout << "Base x=" << x << endl; }
};
class Dri:public Base{
	int y;
public:
	Dri() :y(6){ cout << "constructor " << y << endl; }
	~Dri(){}
	void print(){ Base::print(); cout << "Dri y=" << y << endl; }
};

int main()
{
	Dri d1, *d2 = &d1, *d3 = new Dri;
	//Dri *d4 = new Base(); //

	Base b1, *b2 = new Base(), &b3 = b1, b4[3];
	Base *b6 = &b1;
	Base &b7 = d1;
	Base *b5 = new Dri(); //基类指针可以指向派生类对象,左边基类,右边派生类
	
	return 0;
}
class Base{
	int x;
public:
	Base() :x(3){ cout << "constructor " << endl; }
	~Base(){}
	void print(){ cout << "Base x=" << x << endl; }
};
class Dri:public Base{
	int y;
public:
	Dri() :y(6){ cout << "constructor " << y << endl; }
	~Dri(){}
	void print(){ Base::print(); cout << "Dri y=" << y << endl; }
};

int main()
{
	Dri d1;
	Base *b1 = new Dri;
	b1->print();//Base
	Base &b6 = d1;
	b6.print();//Base
	d1.print();

	return 0;
}

/*
int main()
{
	Dri d1;
	Base b1(d1);

	return 0;
}
*/

静态与继承

//静态成员
//如果基类定义了一个静态成员,则整个继承体系中只存在该成员的唯一定义
class Base{
public:
	static void staticfun();
};

class Drived :public Base{
public:
	void ff(const Drived &);
};

void Drived::ff(const Drived&d)
{
	Base::staticfun();
	Drived::staticfun();
	d.staticfun();
	staticfun();
}

友元与继承

//友元与继承
//友元关系不能传递,友元函数不能继承
class Base{
private:
	int pri_number;
protected:
	int pro_number;
	friend class C;
};

class Derived :public Base{//私有
	friend void f(Derived &);//是Derived的友元
	friend void f(Base&);//是Derived的友元函数
	friend void ff(Derived&);//是Derived的友元函数
	int j;
};
//先看继承int pro_number;属于子类的保护成员
//友元函数属于类外函数
//j是Derived的私有成员,友元函数可以通过本类对象使用
//通过继承int pro_number也属于Derived的保护成员
//友元函数可以通过本类对象使用
void f(Derived&d){ d.pro_number = 4; d.j = 3; }
//void f(Base&b){ b.pro_number = 3; }//是Drived的友元函数    错误:友元关系不能传递
//void ff(Derived&d){ d.pri_number = 1; }//子类的友元函数,可以用自己的私有成员和继承的非私有,但不能用基类的私有

class C{
public:
	//f1是Base的友元函数,可以通过Base对象用Base的所有成员
	int f1(Base d){ return d.pri_number; }
	//错误:友元不被继承,所以C中的成员函数,只是Base的友元函数,并不是Derived友元,所以不能使用Derived的私有
	//int f2(Derived d){ return d.j; }
	//f3是Base的友元函数,能使用Base的保护成员
	int f3(Derived d){ return d.pro_number; }
};

class Deri :class C{
public:
	//错误,友元函数不被继承,Base是C的友元类,Deri不会继承其友元关系
	int f(Base b){ return b.pro_number; }
};

命名冲突

//命名冲突
class A{
public:
	void f(){ cout << "A" << endl; }
};
class B:public A{
public:
	void f(){ cout << "B" << endl; }
};

int main()
{
	//派生类中有用于基类相同名的函数,会覆盖基类函数
	B b;
	b.f();//B类的
	b.A::f();//A类的

	return 0;
}
//命名冲突
class A{
public:
	void f(){ cout << "A" << endl; }
};
class B:public A{
public:
};

class C :public A{
public:
};
class D :public B,public C{
public:
};

int main()
{
	D d;
	d.B::f();

	return 0;
}
class A{
public:
	A(){ cout << "A" << endl; }
};
class B:public A{
public:
	B(){ cout << "B" << endl; }
};

class C :public A{
public:
	C(){ cout << "C" << endl; }
};
class D :public B,public C{
public:
	D(){ cout << "D" << endl; }
};

int main()
{
	D d;

	return 0;
}
A
B
A
C
D
class A{
public:
	A(){ cout << "A" << endl; }
};
class B:virtual public A{
public:
	B(){ cout << "B" << endl; }
};

class C :virtual public A{ // 虚基类解决二义性问题
public:
	C(){ cout << "C" << endl; }
};
class D :public B,public C{
public:
	D(){ cout << "D" << endl; }
};

int main()
{
	D d;

	return 0;
}
A
B
C
D

组合

class SS{};
//组合
class DD{
	SS s;//对象成员
public:
};

6.18

class B{
public:
	void print(){ cout << "B" << endl; }
};
class C:public B{
public:
	void print(int x){ cout << "C" << x << endl; }
};

int main()
{
	B*b;
	b = new C;
	C c;
	c.B::print();//通过类名::函数名,解决子类覆盖父类同名函数
	c.print(3);//C当中的
	b->print();//B类中的函数
	return 0;
}
class Base{
public:
	void who(){ cout << "Base who()" << endl; }
};
class Derived:public Base{
public:
	void who(){ cout << "Derived who()" << endl; }
};

int main()
{//联编->连接
	Derived d;
	Base *b = &d;
	b->who();//Base->静态联编
	d.who();//Derived
	d.Base::who();//Base
	((Derived*)b)->who();//强转Derived

	return 0;
}
class Base{
public:
	virtual void who(){ cout << "Base who()" << endl; }   //virtual
};
class Derived:public Base{
public:
	void who(){ cout << "Derived who()" << endl; }
};
class C :public Derived{
public:
	void who(){ cout << "C who()" << endl; }
};

int main()
{
	Derived d;
	C c;
	Base *b = &d;
	b->who();//Derived   上方有virtual
	b = &c;
	b->who();//C
	return 0;
}

一旦出现基类指针指向new出的派生类对象,那么基类中析构一定要写为虚析构

构造函数不能是虚函数

阻止继承,不能做基类继续继承

class Base final{

};

抽象类,纯虚函数

class Shape{//抽象类:拥有纯虚函数的类称为抽象类
	int x, y, z;
public:
	virtual void area(int x=5, int y=4, int z=3) = 0;//纯虚函数->只有原型,没有定义
	virtual void print() = 0;
};
//抽象类不能声明对象,抽象类一般情况作为基类
//抽象类可以是声明指针或引用

class Tri :public Shape{//只要存在一个虚函数,就是抽象类
public:
	void area(int x = 5, int y = 4, int z = 3);
	void print();//没有这一行则继承了该纯虚函数,为抽象类,有则是实体类
};

//class Tri :public Shape{//抽象类
//public:
//	void area(int x = 5, int y = 4, int z = 3);
//};

//class Tri :public Shape{//实体类
//public:
//	void area(int x = 5, int y = 4, int z = 3);
//	void print();
//};

6.21

运算符重载

//运算符重载:成员函数和友元函数
//默认存在:默认构造,析构,拷贝构造,赋值构造
//双目运算符用的是友元,单目运算符用成员函数
class A{
	int n, m;
public:
	A(){ n = 2; m = 3; }
	//operator 运算符<<、>>一般情况下用友元
	friend void operator<<(ostream&os,A &a);
	friend void operator>>(istream&os, A &a);
};

void operator<<(ostream&os, A &a)
{
	os << a.m << " " << a.n;
}
void operator>>(istream&is, A &a)
{
	is >> a.n >> a.m;
}

int main()
{
	A a;
	operator>>(cin, a);
	operator<<(cout, a);//等于cout << a;

	return 0;
}
class A{
	int n, m;
public:
	A(){ n = 2; m = 3; }
	//operator 运算符<<、>>一般情况下用友元
	friend ostream& operator<<(ostream&os,A &a);
	friend istream& operator>>(istream&os, A &a);
};

ostream& operator<<(ostream&os, A &a)
{
	os << a.m << " " << a.n;
	return os;
}
istream& operator>>(istream&is, A &a)
{
	is >> a.n >> a.m;
	return is;
}

int main()
{
	A a;
	operator>>(cin, a);
	operator<<(cout, a);//等于cout << a;

	return 0;
}
class A{
	int n, m;
public:
	A(){ n = 2; m = 3; }
	//operator 运算符<<、>>用成员函数
	ostream& operator<<(ostream&os);
	istream& operator>>(istream&is);
};

ostream&A::operator<<(ostream&os)
{
	os << m << " " << n;
	return os;
}
istream&A::operator>>(istream&is)
{
	is >> n >> m;
	return is;
}

int main()
{
	A a;
	a >> cin;// a.operator>>(cin); 
	a << cout;//a.operator<<(cout);

	return 0;
}

在这里插入图片描述

前置后置++

class A{
	int n, m;
public:
	A(){ n = 2; m = 3; }
	//成员函数
	void operator++();    // 前置++
	A operator++(int); // 后置++

	//友元
	friend ostream& operator<<(ostream&os, A &a);
	friend istream& operator>>(istream&os, A &a);
};
void A::operator++() //A&
{
	++n;
	++m;
}   //return *this;

A A::operator++(int)
{
	A a;
	a.n = this->n++;
	a.m = this->m++;
	return a;
}
ostream& operator<<(ostream&os, A &a)
{
	os << a.m << " " << a.n;
	return os;
}
istream& operator>>(istream&is, A &a)
{
	is >> a.n >> a.m;
	return is;
}

int main()
{
	A i;
	cout << i << endl;//operator<<(cout,i);
	++i;//i.operator++();//前置++
	cout << i << endl;
	cout << i++ << endl;
	cout << i << endl;

	return 0;
}
friend int operator+(A&,A&);
int operator+(A&a1, A&a2)
{
	a1.n = a1.n + a2.n;
	return a1.n;//return a1.n + a2.n;
}

A b1, b2;
int a = b1 + b2;
cout << a;
friend A operator+(A&,A&);
A operator+(A&a1, A&a2)
{
	A a;
	a.n = a1.n + a2.n;
	a.m = a1.m + a2.m;
	return a;
}

A b1,b2;
A a=b1+b2;
cout << a;
A& operator+(A&a1, A&a2)
{
	a1.n = a1.n + a2.n;
	a1.m = a1.m + a2.m;
	return a1;
}

A b1,b2;
cout << b1+b2;
class B{
public: virtual void f(){ cout << "B:f()" << endl; }
};
class D1:public B{
public:void f(){ cout << "D1:f()" << endl; }
};
class D2 :public B{
public:
	void f(){ cout << "D2:f()" << endl; }
	void g(){ cout << "D2:g()" << endl; }
};
void accessB(B* pB)
{//if(D2*p=(D2*)pB)
	if (D2 *p = dynamic_cast<D2*>(pB))
		p->g();
	else
		pB->f();
}
/*
void accessB(B* pB)
{
	try{
		D2 &p = dynamic_cast<D2&>(*pB);
		p.g();}
	catch (bad_cast){//处理转型失败
		pB->f();}
}
*/
int main()
{
	B b;
	accessB(&b);//B
	//B:f()
	D1 d1;
	accessB(&d1);//D1
	//D1:f()
	D2 d2;
	accessB(&d2);//D2:f()
	return 0;
}

6.22

模板函数

//T,K,V
template <typename T>//每次写都不能省
//template <class T>
T add(T, T);

int main()
{
	add<int>(2, 4);//add(2, 4);//int可省
	add<double>(2.4, 3.6);//double可省

	return 0;
}
template <typename T>//每次写都不能省
T add(T a, T b)
{
	return a + b;
}
//T,K,V
template <typename T, typename T1>//每次写都不能省
//template <class T>
T add(T, T1);

int main()
{
	add<int, double>(2, 4.5);

	return 0;
}
template <typename T, typename T1>//每次写都不能省
T add(T a, T1 b)
{
	return a + b;
}
/*
class A{
	int i, j;
public:
	A(int i, int j){ this->i = i; this->j = j; }
};
class B{
	double i, j;
public:
	B(double i, double j){ this->i = i; this->j = j; }
};
*/
// 简化
template<typename T>
class A{
	T i, j;
public:
	A(T i, T j){ this->i = i; this->j = j; }
};
template<typename T>
class A{
	T i, j;
public:
	A(T i, T j);
};
template<typename T>
A<T>::A(T i, T j)
{
	this->i = i; this->j = j;
}
template<typename T,typename T1>
class A{
	T i;
	T1 j;
public:
	A(T i, T1 j);
};
template<typename T,typename T1>
A<T, T1>::A(T i, T1 j)
{
	this->i = i; this->j = j;
}

int main()
{
	A<int, double> a1(2, 3.5);

	return 0;
}

lambda函数

//lambda函数:函数式编程也是与命令式编程,面向对象编程并列的一种编程泛型
//[capture](parameters)mutable->T{statement};
//[]捕捉列表
//()参数列表
//mutable:可选择的修饰符
//->T:返回值类型
//statement:函数体

//lambda:最简形式:[]{}
int main()
{
	int dogs = 5, cats = 6;
	auto totalAnimal = [](int x, int y)->int{return x + y; };//lambda函数  返回值为int类型(->int)
	cout << totalAnimal(dogs, cats) << endl;

	return 0;
}
//[var]//以值传递方式捕捉var
//[=]//以值传递方式捕捉外围作用域的所有值(包括this)
//[&var]以引用方式捕捉var
//[&]以引用方式捕捉外围作用域的所有值(包括this)
//[this]以值传递方式捕捉当前的this指针
void f()
{
	[]{};//最简lambda,不做任何事情
	int a = 3, b = 4;
	[=]{return a + b; };//省略参数和返回值,可推断出返回值为int
	auto f1 = [&](int c){b = a + c; };//省略返回值类型
	auto f1 = [=,&b](int c)->int{return b = a + c; };
}

阻止隐士转换

//3.explicit构造函数阻止隐士转换
class A{
	int i;
public:
	A(int a) :i(a){}//explicit A(int a) :i(a){}则a=100报错
};
int main()
{
	A a(100);
	a = 100;

	return 0;
}
//2.隐式转换的隐患
class A{
	char *str;
public:
	A(int size){ cout << "A:size" << endl; }//1
	A(const char*s = NULL){ cout << "A:char*" << endl; }//2
};
int main()
{
	A a = 'a';//A:size
	int b = static_cast<int>('a');//显示转换
	return 0;
}

6.23

容器

#include<functional>
#include<list>
#include<algorithm>
using namespace std;

void print_member(int element)
{
	cout << element << endl;
}
void(*ptr)(int) = print_member;
const int N = 4;
int main()
{
	int a1[N] = { 1, 2, 3, 4 };
	list<int> Intlist(a1, a1 + 4);//给链表初始化
	for_each(Intlist.begin(), Intlist.end(), ptr);
	Intlist.push_back(0);//尾部插入
	for_each(Intlist.begin(), Intlist.end(), ptr);
	Intlist.remove_if(bind2nd(modulus<int>(), 2));//除去不能被2整除的数
	for_each(Intlist.begin(), Intlist.end(), ptr);
	return 0;
}
void test(int*a1)
{
	list<int> Intlist(a1, a1 + 4);//给链表初始化
	for_each(Intlist.begin(), Intlist.end(), ptr);
	Intlist.push_back(0);//尾部插入
	for_each(Intlist.begin(), Intlist.end(), ptr);
	Intlist.remove_if(bind2nd(modulus<int>(), 2));//除去不能被2整除的数
	for_each(Intlist.begin(), Intlist.end(), ptr);
}

int main()
{
	int a1[N] = { 1, 2, 3, 4 };
	test(a1);
	return 0;
}
void test()
{
	list<char> charlist;
	//"a-z"
	for (char c = 'a'; c <= 'z'; ++c)
	{
		charlist.push_back(c);
	}
	list<char>::iterator iter;//迭代器

	for (iter = charlist.begin(); iter != charlist.end(); ++iter)
	{
		cout << *iter << "\t";
	}
}
#include<vector>
void test()
{
	vector<int> vec;
	for (int i = 0; i < 5; i++)
		vec.push_back(i + 1);
	vector<int>::iterator iter;
	for (iter = vec.begin(); iter != vec.end(); ++iter)
		cout << *iter << "\t";
}
void test()
{
	vector<int> vec;
	for (int i = 0; i < 5; i++)
		vec.push_back(i + 1);
	for (int i = 0; i < 5; i++)
		cout << vec[i] << "\t";
}
//计算个数
void test()
{
	string s = "agerg";
	int count=0;
	for (auto c : s)count++;
	cout << count << endl;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

QT

6.28

QWidget

按钮

#include<QPushButton>

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    /*
    QPushButton *btn=new QPushButton();
    //btn->show(); // 在界面上方弹出新的控件
    btn->setParent(this);
    btn->setText("第一个按钮");
*/
    /*
    QPushButton *btn=new QPushButton("第一个按钮", this); // 同上
*/

    // 用此构造函数创建,其窗口大小与控件大小一致
    QPushButton *btn=new QPushButton("第一个按钮", this);

    setFixedSize(600, 400);  // 设置窗口大小,不可修改
    //QSize q(600,400);
    //resize(q); // q或(600,400)  设置窗口大小,可修改
    setWindowTitle("应用程序");  // 设置标题
}

按钮重合

    QPushButton *btn=new QPushButton();
    btn->setParent(this);
    btn->setText("第一个按钮");

    QPushButton *btn1=new QPushButton();
    btn1->setParent(this);
    btn1->setText("第二个按钮");

    btn->move(300,0); // 按钮位置移动, 解决两个按钮位重合覆盖

自己创建类创建控件
mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QPushButton>

class MyButton : public QPushButton
{
    Q_OBJECT
public:
    explicit MyButton(QWidget *parent = nullptr);
    ~MyButton();

signals:

};

#endif // MYBUTTON_H

mybutton.cpp

#include "mybutton.h"
#include<QDebug>
MyButton::MyButton(QWidget *parent) : QPushButton(parent)
{
    qDebug()<<"MyButton constructor";
}

MyButton::~MyButton()
{
    qDebug()<<"MyButton Destructor";
}

mywidget.cpp

#include "mywidget.h"
#include<QPushButton>
#include"mybutton.h"
#include<QDebug>

MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
{
    MyButton *btn=new MyButton;
    btn->setParent(this);
    btn->setText("第三个按键");
}

MyWidget::~MyWidget()
{
    qDebug()<<"MyWidget Destructor";
}

信号可以和信号连接,信号和槽连接
信号函数的参数与槽函数的参数:信号的参数可以多于槽函数,槽函数参数不能多于信号函数

信号与槽——关闭窗口

    QPushButton *btn=new QPushButton("第一个按钮", this);
    // 信号发送者,按下信号(信号函数),接收者,信号处理函数(槽函数)
    connect(btn,&MyButton::clicked,this,&MyWidget::close); //  点击按钮关闭窗口
    //connect(btn,&QPushButton::clicked,this,&QWidget::close); // 同上

信号与槽——按钮点击时间处理

Teacher类,hunger函数teach在Teacher中定义Teacher *teach
Student类,treat函数stu在Student中定义Student stu

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //创建对象
    teach= new Teacher(this);
    stu = new Student(this);
    
    //连接
    //信号和槽
    //connect(teach,&Teacher::hungry,stu,&Student::treat);
    //下课了
    //classIsOver();
    
    //信号和信号
    QPushButton *btn=new QPushButton("点击",this);
    resize(600, 400);
    connect(btn,&QPushButton::clicked,stu,&Student::treat);
}
    void (Teacher::*p)(QString)=&Teacher::hungry;
    void (Student::*q)(QString)=&Student::treat;
    connect(teach,p,stu,q);
	//int data=[=]()->int{return 5;}();
	//qDebug()<<data;
    connect(btn,&QPushButton::clicked,teach,[=](){
        emit teach->hungry("fush");
    });

6.29

QMainWindow

menu菜单栏
#include "mainwindow.h"
#include<QMenuBar>
#include<QToolBar>
#include<QPushButton>
#include<QStatusBar>
#include<QLabel>
#include<QDockWidget>
#include<QTextEdit>

    setWindowTitle("应用程序");
    resize(600,400);

    //菜单栏  #include<QMenuBar>  最多一个
    QMenuBar* menuBar=new QMenuBar(this);
    setMenuBar(menuBar);
    //在菜单栏加menu
    QMenu* fileMenu = menuBar->addMenu("文件(F)");
    QMenu* editMenu = menuBar->addMenu("编辑(E)");
    //在menu中添加action
    fileMenu->addAction("新建");
    fileMenu->addSeparator();//添加分隔符
    fileMenu->addAction("打开");

    //工具栏  #include<QToolBar>  可以有多个
    QToolBar* toolBar = new QToolBar(this);
    //在界面中添加工具栏
    addToolBar(toolBar);
    addToolBar(Qt::LeftToolBarArea,toolBar);//位置
    toolBar->addAction("工具");
    //设置停靠位置
    toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
    //禁止移动
    //toolBar->setMovable(false);
    //禁止浮动
    toolBar->setFloatable(false);
    QPushButton*btn=new QPushButton(this);
    btn->setText("按钮");
    toolBar->addWidget(btn);  //添加按钮

    //状态栏  #include<QStatusBar>
    QStatusBar*stBar = new QStatusBar(this);
    setStatusBar(stBar);
    //添加小部件
    QLabel* label = new QLabel("提示信息",this);
    stBar->addWidget(label);
    //添加小部件
    QLabel* label1 = new QLabel("右边提示信息",this);
    stBar->addPermanentWidget(label1);
    //可添加按钮

    //浮动框  #include<QDockWidget>
    QDockWidget*docw = new QDockWidget("浮动框",this);
    addDockWidget(Qt::BottomDockWidgetArea,docw);

    //添加中心部件  #include<QTextEdit>  中心部件只能有一个
    QTextEdit* edit = new QTextEdit(this);
    setCentralWidget(edit);

资源文件

#include<QMenuBar>
    resize(600,400);
    //创建菜单栏
    QMenuBar* menuBar=new QMenuBar(this);
    setMenuBar(menuBar);
    //添加菜单menu
    QMenu* fileMenu = menuBar->addMenu("文件");
    fileMenu->addAction(QIcon(":/Image/Luffy.png"),"新建");

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDialog>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->actionnew->setIcon(QIcon(":/Image/Luffy.png"));
    ui->actionopen->setIcon(QIcon(":/Image/Frame.jpg"));

    connect(ui->actionnew,&QAction::triggered,this,[=](){
        //模态
        QDialog dia;
        dia.show();
        dia.exec();  //防止闪退
??????????????????????????????????????????
        //非模态
        //QDialog *dia=new QDialog(this);
        //dia->resize(200, 200);
        //dia->show();
        //dia->exec();
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}
    connect(ui->actionnew,&QAction::triggered,this,[=](){
        //模态
        /*QDialog dia;
        dia.resize(300,200);
        dia.exec();  //防止闪退
        qDebug()<<"模态情况";*/


        //非模态
        QDialog *dia=new QDialog(this);
        dia->resize(200, 200);
        dia->show();   // 隐藏该句为模态
        //自动销毁窗口类对象
        //dia->deleteLater();//函数设置对话框关闭时,自动销毁对话框
        dia->setAttribute(Qt::WA_DeleteOnClose);//在当前事件
        qDebug()<<"非模态情况";

        //#include<QMessageBox>
        //错误信息对话框  静态成员函数:基类,QString title,Qstring 信息内容
        //QMessageBox::critical(this, "critical", "错误");
        //消息对话框
        //QMessageBox::information(this, "info", "信息");
        //问题对话框
        //if (QMessageBox::Save == QMessageBox::question(this, "question", "问题",QMessageBox::Save|QMessageBox::Cancel,QMessageBox::Cancel))//最后一个参数默认初始选择在哪个选项即Cancel
        //    qDebug()<<"是一个保存按钮";
        //else
        //    qDebug()<<"是一个取消按钮";
        //警告对话框
        //QMessageBox::warning(this, "warning", "警告");

        //字体对话框  #include<QFontDialog>
        //bool flag;
        //QFont col = QFontDialog::getFont(&flag,QFont("仿宋", 24));
        //qDebug()<<"字体类型:"<<col.family().toUtf8().data()<<"是否加粗"<<col.bold();
        //颜色对话框  #include<QColorDialog>
        QColor color = QColorDialog::getColor(QColor(255, 0, 0));
        qDebug()<<"r="<<color.red()<<" g="<<color.green()<<" b="<<color.blue();



    });

在这里插入图片描述

    ui->setupUi(this);
    ui->btn1->resize(80,40);
    ui->btn1->setText("open");
    connect(ui->btn1, &QPushButton::clicked,[=](){
        QDialog*dlog=new QDialog(this);
        dlog->resize(300,300);
        dlog->show();
        dlog->setAttribute(Qt::WA_DeleteOnClose);
    });

在这里插入图片描述
在这里插入图片描述

    void (QSpinBox::*spsignal)(int)=&QSpinBox::valueChanged;
    connect(ui->spinBox,spsignal,ui->horizontalSlider,&QSlider::setValue);
    //Slider变化->spinBox变化
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);

在这里插入图片描述在这里插入图片描述

	connect(ui->pushButton,&QPushButton::clicked,[=](){
        qDebug()<<ui->widget->GetValue();
    });
    connect(ui->pushButton_2,&QPushButton::clicked,[=](){
        ui->widget->SetValue(50);
    });

在这里插入图片描述

SmallWidget::SmallWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::SmallWidget)
{
    ui->setupUi(this);
    //spinBox变化->Slider变化
    void (QSpinBox::*spsignal)(int)=&QSpinBox::valueChanged;
    connect(ui->spinBox,spsignal,ui->horizontalSlider,&QSlider::setValue);
    //Slider变化->spinBox变化
    connect(ui->horizontalSlider,&QSlider::valueChanged,ui->spinBox,&QSpinBox::setValue);
}
//设置SpinBox的值
void SmallWidget::SetValue(int val)
{
    ui->spinBox->setValue(val);
}
//获取spinBox的值
int SmallWidget::GetValue()
{

    return ui->spinBox->value();
}

在这里插入图片描述
在这里插入图片描述

#include<QEvent>

void eventWidget::enterEvent(QEvent *event)
{
    qDebug()<<"鼠标进入";
}
void eventWidget::leaveEvent(QEvent *)
{
    qDebug()<<"鼠标离开";
}

在这里插入图片描述

#include<QMouseEvent>

//鼠标按下
void eventWidget::mousePressEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标按下";
}
//鼠标释放
void eventWidget::mouseReleaseEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标释放";
}
//鼠标移动
void eventWidget::mouseMoveEvent(QMouseEvent *ev)
{
    qDebug()<<"鼠标移动";
}
void eventWidget::mousePressEvent(QMouseEvent *ev)
{
    if(ev->button()==Qt::RightButton)//鼠标右键按下
    {
        qDebug()<<"鼠标按下 ";
    }
    QString str=QString("鼠标按下的坐标:x=%1,y=%2").arg(ev->x()).arg(ev->y());
    qDebug()<<"鼠标按下 "<<str;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//计时器
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    startTimer(1000);//时间1s
}
void Widget::timerEvent(QTimerEvent *event)
{
    static int num = 1;
    ui->label->setText(QString().number(num++));
}
    QTimer *time=new QTimer(this);
    time->start(3000);//3秒变化一次
    connect(time,&QTimer::timeout,[=](){
        static int num = 1;
        ui->label->setText(QString().number(num++));
    });
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    id1 = startTimer(1000);
    id2 = startTimer(2000);
    
}
void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerID()==id1){
        static int num = 1;
        ui->label->setText(QString().number(num++));
    }
    if(event->timerID()==id2){
        static int num = 1;
        ui->label->setText(QString().number(num++));
    }
    
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值