作业答疑
不是为了模块化而去模块化,所谓模块化应该是按需操作的,如果过度为过度设计 反而越难
优化代码如下
#include "stdafx.h"
void SwapNumber(int *nValue, int *nValue2)
{
int Temp = 0;
if (*nValue > *nValue2)
{
Temp =* nValue;
*nValue = *nValue2;
*nValue2 = Temp;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("请输入3个数字\r\n");
int nValue1 = 0;
int nValue2 = 0;
int nValue3 = 0;
int Temp = 0;
scanf("%d", &nValue1);
scanf("%d", &nValue2);
scanf("%d", &nValue3);
SwapNumber(&nValue1, &nValue2);
SwapNumber(&nValue1, &nValue3);
SwapNumber(&nValue2, &nValue3);
printf("%d %d %d", nValue1, nValue2, nValue3);
return 0;
}
编程习惯注意事项
变量初始化
所有变量应该初始化,如果没有初始化,那么结果是未知的(里面存留了上一次残留的数值)
在VS debug版本中 为了方便 操作者知道原因 VS自动加戏为 cccccc 值
在中文中恰好为 烫烫
匈牙利命名法
- 可读性比较强
关于类型变量 以小写的字母开头 后面接单词全拼 每个单词首字母大写
对于函数不需要类型开头 直接首字母大写就可
int n
float f
double db
long l
short s
unsigned char uch
unsigned char uint
怎么模块化
相似,重复的代码 理论上可以封装成函数
exe闪退问题
加入
scanf()
getchar ()
优化 有暂停要求 调用pause命令来暂停
#include"stdlib.h"
system("pause");
习题解答过程
判断闰年
#include "stdafx.h"
#include"stdlib.h"
void JupeYears(int nValue)
{
if (nValue % 400 == 0)
{
printf("这是闰年\r\n");
}
else if (nValue % 4 == 0)
{
if (nValue % 100 != 0)
{
printf("这是闰年\r\n");
}
}
else
{
printf("这不是闰年\r\n");
}
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("请输入你想判断的年份\r\n");
int nValue = 0;
while (1)
{
scanf("%d", &nValue);
JupeYears(nValue);
}
return 0;
}
编程语法关:想法变成算法
游戏体验:
猜数字游戏
某同学A生成一个数字,并保密,仅仅只有主持人知道。
然后给一个范围(比如1~100)。
剩下的同学,一次猜该数字。如果没猜中,则主持人更新数字的范围;如果猜中
了,则猜中的同学表演节目等。
举例:
A同学写下的数字是55.
主持人说范围是1~100.
同学猜的数字 主持人说
2 2~100
2-55
30
30-55
55 正确
- 随机数(同学说的数字)
- 判读语句
- 循环语句
- 输入输出
随机数的生成rand()
其实是伪随机数
srand((unsigned)time(NULL));
-
使用 time函数来获得系统时间,它的返回值为从 00:00:00 GMT, January 1, 1970 到现在所持续的秒数,`
然后将time_t型数据转化为(unsigned)型再传给srand函数 -
当srand()的参数值固定的时候,rand()获得的数也是固定的,所以一般srand的参数用time(NULL),因为系统的时间一直在变,所以rand()获得的数,也就一直在变,相当于是随机数了
int main(int argc, char* argv[])
{
srand((unsigned)time(NULL));
int nMinNumber = 0;
if (argc != 2)
{
printf("传参错误");
return 0;
}
int nMaxNumber = atoi(argv[1]);
int nRandNumber = rand() % nMaxNumber+1;
int nInputNumber = 0;
while (1)
{
printf("范围是 %d-%d", nMinNumber, nMaxNumber);
printf("请输入你猜想的数字\r\n");
scanf("%d", &nInputNumber);
if (nInputNumber > nRandNumber)
{
nMaxNumber = nInputNumber-1;
}
else if (nInputNumber < nRandNumber)
{
nMinNumber = nInputNumber+1;
}
else if (nInputNumber = nRandNumber)
{
printf("bingo!");
return 0;
}
}
}
控制台设计
参数获取 答案就是main的argc,和argv。
- argc 是传参个数 arc>=1 就是至少为一 就是本身
- argv 是传的字符串
彩色UI
void WriteChar(int nRow, int nCol , char* pszChar , WORD wArr);
word 地方可以用SetConsoleColor(COLOR_01,COLOR_02);前背景和后背景设置
int main(int argc, char* argv[])
{
char* str = \
"□□□□■■■■■■□□□□□□□□□□■□□□□□□□□□□□□□□□□□■□□□□□□□□□■□□□□□□□□□■■■■■■■■■■■□\n"
"□□□■□□□□□□□□□□□□□□□■□■□□□□□□□□□□□□□□□■□■□□□□□□□■□■□□□□□□□□■□□□□□□□□□□□\n"
"□□■□□□□□□□□□□□□□□□■□□□■□□□□□□□□□□□□□■□□□■□□□□□■□□□■□□□□□□□■□□□□□□□□□□□\n"
"□■□□□□□□□□□□□□□□□■□□□□□■□□□□□□□□□□□■□□□□□■□□□■□□□□□■□□□□□□■□□□□□□□□□□□\n"
"□■□□□□□□□□□□□□□□■■■■■■■■■□□□□□□□□□■□□□□□□□■□■□□□□□□□■□□□□□■■■■■■■■■■■□\n"
"□■□□□□□■■■■□□□□■□□□□□□□□□■□□□□□□□■□□□□□□□□□■□□□□□□□□□■□□□□■□□□□□□□□□□□\n"
"□■□□□□□■□□■□□□■□□□□□□□□□□□■□□□□□■□□□□□□□□□□□□□□□□□□□□□■□□□■□□□□□□□□□□□\n"
"□□■□□□□□□□■□□■□□□□□□□□□□□□□■□□□■□□□□□□□□□□□□□□□□□□□□□□□■□□■□□□□□□□□□□□\n"
"□□□■■■■■■■■□■□□□□□□□□□□□□□□□■□■□□□□□□□□□□□□□□□□□□□□□□□□□■□■■■■■■■■■■■□\n"
"□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□□\n"
"□□□□■■■■□□□□■□□□□□□□□□□□□□□□■□□□□□□■■■■■■■■■■■■■■■□□□□□□□□■□□□□■■■■□□□\n"
"□□□■□□□□■□□□□■□□□□□□□□□□□□□■□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□□□■□□□□■□□\n"
"□□■□□□□□□■□□□□■□□□□□□□□□□□■□□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□□■□□□□□□■□\n"
"□■□□□□□□□□■□□□□■□□□□□□□□□■□□□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□■□□□□□□□□□\n"
"□■□□□□□□□□■□□□□□■□□□□□□□■□□□□□□□□□□■■■■■■■■■■■■■■■□□□□□□□□■■□□□□□□□□□□\n"
"□■□□□□□□□□■□□□□□□■□□□□□■□□□□□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□\n"
"□□■□□□□□□■□□□□□□□□■□□□■□□□□□□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□\n"
"□□□■□□□□■□□□□□□□□□□■□■□□□□□□□□□□□□□■□□□□□□□□□□□□□□□□□□□□□□■□□□□□□□□□□□\n"
"□□□□■■■■□□□□□□□□□□□□■□□□□□□□□□□□□□□■■■■■■■■■■■■■■■□□□□□□□□■□□□□□□□□□□□\n";
WriteChar(10, 0,
str,
SetConsoleColor(COLOR_YELLOW, COLOR_WHITE));
}
控制台彩色UI的代码
这是我从Linux修改以后的代码
VS编译器可以直接使用
setdisplay.h
#pragma once
#include <windows.h>
#include <stdio.h>
/********控制台输出控制彩色内容*********/
/*************************************
这个彩色控制台的一个小问题:
会比设置的高度多一行(最后一行),
这一行可以输出内容,
但不要输出内容到最后一列,
否则界面会被挤下来一行,第一行会消失,
意味着在设置满屏背景的情况下,
要不最后一行全黑,
要不右下角留一个窄黑块,
测试&例子代码中第8个测试可以展示问题
**************************************/
/*********** 宽度的基本单位(整数) ***********/
// 设置为2意味着1列为2个英文宽度或1个汉字宽度
#define WIDTH_UNIT 2 // 可根据需求修改
/*************************************
颜色属性
**************************************/
#define COLOR_BLACK 0x00 // 黑色
#define COLOR_BLUE 0x01 // 蓝色
#define COLOR_GREEN 0x02 // 绿色
#define COLOR_LIGHTBLUE 0x03 // 湖蓝色
#define COLOR_RED 0x04 // 红色
#define COLOR_PURPLE 0x05 // 紫色
#define COLOR_YELLOW 0x06 // 黄色
#define COLOR_WHITE 0x07 // 白色
#define COLOR_GRAY 0x08 // 灰色
#define COLOR_THIN_BLUE 0x09 // 淡蓝色
#define COLOR_THIN_GREEN 0x0A // 淡绿色
#define COLOR_THIN_LIGHT_GREEN 0x0B // 淡浅绿色
#define COLOR_THIN_RED 0x0C // 淡红色
#define COLOR_THIN_PURPLE 0x0D // 淡紫色
#define COLOR_THIN_YELLOW 0x0E // 淡黄色
#define COLOR_LIGHT_WHITE 0x0F // 亮白色
/*******************************
功能:设置前背景色
f 前景色
b 背景色
原理:
1字节数据
低4字节为前景,高4字节为背景
********************************/
#define SetConsoleColor( f , b ) ( ( f ) + ( ( b ) << 0x04 ) )
/***********************************
测试函数 & 例子
************************************/
void TestWindowSizeAndColor();
/*************************************
函数功能:打印字符到控制台制定位置
nHigh: 高度X行,行数
nWide: 宽度Y列,列数
pszChar: 打印的字符串(一个字符也要用字符串的形式)
wArr: 打印字符的属性:颜色
可通过SetConsoleColor宏设置背景色
注意: 数据显示到界面上后会一直存在
宽度 1 列为 1 个汉字 或 两个英文,
可通过 宽度宏 WIDTH_UNIT 来控制
**************************************/
void WriteChar(int nHigh , int nWide , char* pszChar , WORD wArr);
/*************************************
函数功能: 设置窗口信息
*pszWindewTitle: 窗口名称
nHigh: 高度X行,行数
nWide: 宽度Y列,列数
成功返回值: TRUE
注意:数值设置太大会出错,尤其是高度
宽度 1 列为 1 个汉字 或 两个英文,
可通过 宽度宏 WIDTH_UNIT 来控制
*************************************/
BOOL SetWindowSize(char *pszWindowTitle , int nHigth, int nWide);
setdisplay.cpp
#include "setdisplay.h"
/*********************************
测试函数 & 例子
**********************************/
void TestWindowSizeAndColor()
{
// 1. 设置控制台标题和窗口大小
SetWindowSize("控制台颜色测试用例" , // 标题
30, // 高度 30 行 // 在1920*1080的显示器中最大值为60
30 // 宽度 30 列 // 1 列 = 1 个汉字 或 2 个英文
);
// 2. 在第一行输出一段带背景的文字
WriteChar(0 , // 第 1 行
0 , // 第 1 列
"这是一段带背景的文字0123456789ABCDEF" ,
SetConsoleColor( COLOR_BLACK , // 黑色前景
COLOR_WHITE) // 白色背景
);
// 3. 在第三行输出一行淡浅绿色
char szBuff[ MAXBYTE ] = { 0 };
// 设置一个内容为60个空格的字符串
sprintf_s(szBuff , MAXBYTE , "%60c" , ' ');
WriteChar(2 , // 第 3 行
0 , // 第 1 列
szBuff , // 60个空格
SetConsoleColor( COLOR_BLACK , // 黑色前景
COLOR_THIN_LIGHT_GREEN ) // 淡浅绿色
);
// 4. 在第五行输出一段浅绿色换行文字
WriteChar(4 , // 第 5 行
0 , // 第 1 列
"这是一段换行的白文字\n0123456789ABCDEF<--这些文字被输出到了第六行,并且支持自动换行,多余的内容会自动到下一行" ,
COLOR_THIN_GREEN
);
// 5. 在屏幕中间打印16种颜色
// 主要方法通过给空格设置背景色
for(int i = 0; i < 0x04; ++i)
{
for(int j = 0; j < 0x04; ++j)
{
WriteChar(i + 12 , // 从第13行开始
j + 12 , // 从第13列开始
" " , // 两个空格
SetConsoleColor( COLOR_BLACK , // 黑色前景
(WORD)(i * 4 + j) ) // 背景色
);
}
}
// 6. 在倒数第三行输出一段带背景的符号
WriteChar(27 , // 第 28 行
0 , // 第 1 列
"符号:§№☆★○●◎◇◆□■△▲※→←↑↓〓#@&\^_ ̄ " ,
SetConsoleColor( COLOR_THIN_BLUE , // 浅蓝前景
COLOR_LIGHT_WHITE) // 亮白色背景
);
// 7. 在最后一行输出一行亮白色
WriteChar(29 , // 第 30 行
0 , // 第 1 列
szBuff,
SetConsoleColor( COLOR_BLACK , // 黑色前景
COLOR_LIGHT_WHITE ) // 亮白色背景
);
// 8. 问题展现
// 在最后多出的一行输出内容
WriteChar(30 , // 第 31 行
0 , // 第 1 列
"无法避免的Bug描述:设置30行,但这是第31行,再多加个空格来试试 " ,
SetConsoleColor( COLOR_THIN_BLUE , // 浅蓝前景
COLOR_LIGHT_WHITE) // 亮白色背景
);
}
/*************************************
函数功能:打印字符到控制台制定位置
nHigh: 高度X行,行数
nWide: 宽度Y列,列数
pszChar: 打印的字符串(一个字符也要用字符串的形式)
wArr: 打印字符的属性:颜色
可通过SetConsoleColor宏设置背景色
注意: 数据显示到界面上后会一直存在
宽度 1 列为 1 个汉字 或 两个英文,
可通过 宽度宏 WIDTH_UNIT 来控制
*************************************/
void WriteChar(int nHigh , int nWide , char* pszChar , WORD wArr)
{
CONSOLE_CURSOR_INFO cii;
cii.dwSize = 1;
cii.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE) , &cii);
COORD loc;
loc.X = nWide * (WIDTH_UNIT);
loc.Y = nHigh;
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE) , wArr);
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE) , loc);
printf(pszChar);
}
/*************************************
函数功能: 设置窗口信息
*pszWindewTitle: 窗口名称
nHigh: 高度X行,行数
nWide: 宽度Y列,列数
成功返回值: TRUE
注意:数值设置太大会出错,尤其是高度
宽度 1 列为 1 个汉字 或 两个英文,
可通过 宽度宏 WIDTH_UNIT 来控制
*************************************/
BOOL SetWindowSize(char *pszWindowTitle , int nHight, int nWide)
{
// Title
nWide *= (WIDTH_UNIT);
// nHight -= 1;
nWide -= 1;
SetConsoleTitleA(pszWindowTitle);
HANDLE hStdin , hStdOut;
hStdin = GetStdHandle(STD_INPUT_HANDLE);
hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
// get max console window size
COORD pos = GetLargestConsoleWindowSize(hStdOut);
COORD BufferSize = { pos.X , pos.Y };
// set console buffer size
if(!SetConsoleScreenBufferSize(hStdOut , BufferSize)){
// set console buffer size FALSE
printf("buffer err(%d,%d)%d\n" , BufferSize.X , BufferSize.Y , GetLastError());
return FALSE;
}
SMALL_RECT srctWindow = { 0 , 0 , nWide , nHight };
if(!SetConsoleWindowInfo(hStdOut , TRUE , &srctWindow)){
// set console window size FALSE
printf("size err %d\n" , GetLastError());
return FALSE;
}
COORD Buffer = { nWide + 1 , nHight + 1 };
// set console buffer size
if(!SetConsoleScreenBufferSize(hStdOut , Buffer)){
// set console buffer size FALSE
printf("buffer err(%d, %d)%d\n" , BufferSize.X , BufferSize.Y , GetLastError());
return FALSE;
}
return TRUE;
}