C++程序设计
一、绪论
在集成开发环境写代码练习
涉及的数据结构一般是顺序表、树,对应的c语法是数组和结构体
涉及的算法包括枚举、模拟、分治、搜索,对应的c语法是循环和递归
备考策略:
先把例题和基本知识点学会
充分挖掘和反思每一道习题
先掌握编程工具的使用,最后再进行考前环境模拟
第一章 枚举和模拟
1、枚举
●例题一
描述
设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。
输入描述:
题目没有任何输入。
输出描述:
请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。
提交网址:http://t.cn/E9WMRTE
循环
固定范围的循环for
和 while 一样,for 循环也是一个顶部驱动的循环,但是它包含了更多的循环逻辑,如下所示:for ([表达式1];[表达式2];[表达式3])
语句
在一个典型的 for 循环中,在循环体顶部,下述三个动作需要执行:
(1) 表达式 1:初始化(可以不止存在一个值)
只计算一次。在计算控制表达式之前,先计算一次表达式 1,以进行必要的初始化,后面不再计算它。
(2) 表达式 2:控制表达式(逻辑表达式)
每轮循环前都要计算控制表达式,以判断是否需要继续本轮循环。当控制表达式的结果为 false,结束循环。
(3) 表达式 3:调节器(可以不止一个值变化)
调节器(例如计数器自增)在每轮循环结束后且表达式 2 计算前执行。即,在运行了调节器后,执行表达式 2,以进行判断。
选择结构
选择结构if-else
选择结构switch
switch 语句格式
switch(表达式){
case 常量 1:语句组 1
case 常量 2:语句组 2
┇
case 常量 n:语句组 n
default:语句组 n+1
}
break:中断命令
功能:
终止 switch 语句,使程序立即执行 switch 语句的后续语句
case 的语句组允许为空
switch 表达式通常为整型值或字符型值,case 的常量类型应与之相应
case 的“常量”位置允许是常数表达式,但不允许是变量表达式
void main() {
char result;
scanf ("%c",&result);
switch(result) {
case 'A':
case 'B':
case 'C':
printf ("Good!\n"); break;
case 'D':
case 'E':
printf ("Bad!\n"); break;
default:
printf ("Error!\n");
}
}
输出
printf("%d %d %d\n",a,b,c);
printf()是 C 语言的格式化输出函数, 用于向标准输出设备/显示器、按规定格式输出信息。
格式:printf(“格式化字符串”,表达式列表);
说明:
格式化字符串:输出信息的格式
以“%”开始的格式控制符:规定输出数据的类型及格式
普通字符或转义字符:普通字符直接输出,转义字符输出其转义后的形式。
表达式列表:以“,”分隔的一系列待输出其值的表达式列表
注:
输出表达式的个数必须与格式化字符串说明的输出参数个数相同
顺序要与格式串中要求输出的内容一一对应
void main() {
int a,b;
a=8;
b=10;
printf("%d+%d=%d\n",a,b,a+b);
}
“%”和格式控制符之间的数字,表示输出数据的宽度
%6d:整数,宽度为 6,位数不足时,右对齐显示
%06d :整数,宽度为 6,位数不足时,高位填 0
%8.2f :实数,宽度为 8,保留 2 位小数,整体长度不足 8 位时,右对齐显示
%8s:字符串,宽度为 8,位数不足时,右对齐显示
输入
scanf() 从标准输入设备为变量输入数据。
格式: scanf(“格式控制字符串",变量地址表);
“格式控制字符串”:约定输入数据的类型和格式
格式控制参数的个数必须与变量地址的个数一致
格式控制参数之间可以不使用任何分隔符号,也可用分隔符
不使用任何分隔符:输入的数据之间用空格、TAB、回车分隔
使用分隔符:输入数据之间必须使用约定分隔符
“变量地址表”:以逗号“, “分隔的、输入数据变量地址序列
scanf%c可以读取空白字符(空格和换行),scanf %d %f %o 忽略空白字符
在编写代码时,如果前面有空格,则忽略空白字符
简单变量地址为 &简单变量名
void main() {
int a,b,sum;
printf(“Please input two integers: ");
scanf("%d,%d",&a,&b);
sum=a+b;
printf("%d+%d=%d\n",a,b, sum);
}
●例题二 反序数
描述
设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321)
求N的值
输出描述:
输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开。
提交网址:http://t.cn/E9WBrut
●reverse()函数
int Reverse(int n){
int reserve=0;
int a;
while (1) {
a=n%10;
reserve=reserve*10+a;
n=n/10;
if (n==0){
break;
}
}
return reserve;
}
int main(){
for (int i=1000; i<=9999; i++) {
int reserve=Reverse(i);
if (i*9==reserve) {
printf("%d\n",i);
}
}
return 0;
}
●例题三 对称平方数
描述
打印所有不超过256,其平方具有对称性质的数。如2,11就是这样的数,因为22=4,1111=121
输入描述:
无任何输入数据
输出描述:
输出具有题目要求的性质的数。如果输出数据不止一组,各组数据之间以回车隔开。
提交网址:
关键:判断对称数————>本身与逆序数相同
规范一:=赋值、==判断相等
规范二:不要省略花括号
2、模拟
2.1图案打印问题
数据结构:数组、二维数组
●例题1 输出梯形
输入一个高度为h,输出一个高度为h,上底边长度为h
思路:统计有多少个空格和星号
int h;
scanf("%d",&h);
for (int i = 0; i < h; ++i) {
for (int j = 0; j < 2*h-2-2*i; ++j) {
printf(" ");
}
for (int j = 0; j < h+2*i; ++j) {
printf("*");
}
printf("\n");
}
}
○用while循环实现不确定范围的输入
EOF(-1)
scanf的返回值是一个int,返回读取内容的个数
Ctrl+d文件终止符,End of file
○使用二维数组解决图案模拟问题
先计算二维数组的大小
arr[0][0]------->arr[h-1][3h-3] //尽量定义固定大小的数组
利用断点调试,定位问题
//将全部区域填上空格
int h;
while(scanf("%d",&h) !=EOF) {
for (int i = 0; i < h; ++i) {
for (int j = 0; j < 3 * h - 3; ++j) {
arr[i][j] = ' ';
}
}
//填充梯形区域,从下往上填充
int beg =0;
for (int i = h-1; i >= 0; --i) {
for (int j = beg; j < 3*h-2; ++j) {
arr[i][j]='*';
}
beg=beg+2;
}
for (int i = 0; i < h; ++i) {
for (int j = 0; j < 3*h-2; ++j) {
printf("%c",arr[i][j]);
}
printf("\n");
}
}
}
○c风格的字符串设计
字符串是用字符数组来处理的,定义数组时要比字符串的内容多1
读取一个十进制整数:
读取一个字符串%s
scanf("%s",str);
用字符串数组处理,打印时直接以字符串打印
○总结:图案打印问题的一般思路
1、申请二维数组(固定大小,放在全局变量的位置)
2、根据条件从任意方向开始设置二维数组
3、把图案的每一行的便捷的最后一个位置使用\0,赋值
4、使用printf %s 配合循环,打印每一行
●知识点——数组
一维数组
一组具有相同的数据类型的数据的有序集合
int a[10];
int a[10]={1,2,3,4,5,6,7,8,9};
不能用变量说明数组的大小
定义和初始化不能分开,例如不能写成
a[10]={1,2,3,4,5,6,7,8,9};
计算数组长度sizeof(a)
计算数组个数sizeof(a)/sizeof(int)(后面具体要看数组的类型)
数组的访问越界与数组的传递
越界访问会导致访问异常,循环数组的边界没有设置好会造成访问越界
数组的传递,在主函数中max(a)即可,不要写成max(a[5]),数组仅传递数组名
在子函数中,int max(a[]),中数组的长度无法传递,因此不需要写数字
数组传递到子函数后,子函数的形参接收到的不是数组是数组的起始地址,若要传递数组的长度,可以在设置一个形参,
int max(a[],int length);
在子函数中改变数组的值,主函数中也将改变
字符数组
初始化:char a[10]=“Iamhappy”
使用%s输出一个字符串,直接把字符数组名放到printf的位置
printf(“%s”,a);
若是一个一个定义的则必须在最后一个位置加上\0,否则会出现乱码,也要小心访问越界
输出字符串乱码是,要去查看字符数组中是否存储了\0
scanf读取字符串
scanf(“%s”,c);
scanf读取字符串的操作,结束会放置一个结束符
在scanf读取字符串时,自动忽略空格,将空格看做终止符,因此想读两个单词时,可以使用
scanf(“%S%S”,a,b);
gets和puts函数
gets函数:一次读取一串字符串
gets(c);
gets中放入字符数组的数组名即可,空格也可以输出遇到换行符结束,与scanf一样也会在最后加上\0
puts函数:只能输出字符串
puts=printf(“%s\n”,c)
puts的参数只能是字符数组名
str系列字符串操作函数
#include <string.h>
strlen©//统计字符串长度,通过找结束符统计数组的长度,也可以放字符串常量
strcat(c,d)//把d中的字符串拼到c的后面
strcopy(c,d)//把d中的内容拷贝到c中
strcmp(c,d)//看c和d是否相等
//字符串比较大小,根据ASCII码比较,c大于d返回正值,c小于d返回负值,c等于d返回0
c风格的字符串函数,可以使用c++
●例题2 叠筐
思路:
二维数组的长度要是固定的
其实坐标pattern[n/2][n/2],填框的过程是填外边框的过程
找中心、找起点
图案问题:用二维数组、找数字规律、列循环的变化过程
int n;
char inner,outter;
char pattern[80][80]={'\0'};//在定义二维数组时可以初始化
//while(scanf("%d %c %c",&n,&inner,&outter)!=EOF){
// scanf %c可以读取空白字符
// 如果有空格,则可以忽略空白字符
//定义二维数组时,可以初始化
scanf("%d %c %c",&n,&inner,&outter);
int init =n/2;//第一个点的下标
int length=1;//外框的长度
int x,y;//横坐标和纵坐标
char col=inner;
for (length = 1,x=n/2,y=n/2; length <=n ; length=length+2,--x,--y){
//x和y是起点的下标,length从1开始,x和y的下标从n/2开始,起点坐标每次减一,长度每次加二
for(int i=x, j=y;j<y+length;++j){
pattern[i][j]=col;
}
for (int i = x, j=y+length-1; i <x+length ; ++i) {
pattern[i][j]=col;
}
for (int i = x, j=y; i<x+length ; ++i) {
pattern[i][j]=col;
}
for (int i = x+length-1, j=y ; j <y+length ; ++j) {
pattern[i][j]=col;
}
if(n!=1){
pattern[0][0]=' ';
pattern[0][n-1]=' ';
pattern[n-1][0]=' ';
pattern[n-1][n-1]=' ';
}
if(col==inner){
col=outter;
}
else{
col=inner;
}
}
for (int i = 0; i < n; ++i) {
printf("%s\n",pattern[i]);
}
//}
return 0;
}