- 3.1数组
- 数组大小为常量
- x++ 与 ++x
- 比较大的数组要在main函数外声明!
- 函数:memcpy()
- 例一:开灯问题
- 初始化的重要性
- 函数:memset()
- 取反( ! )符号妙用
- 避免输出多余空格的技巧
- 例二:蛇形填数
- C语言简洁的优势
- 先判断,再移动!
- 避免非法访问内存!
- 3.2 字符数组
- 例三:竖式问题
- scanf("%s" , s)
- printf("%5d") 与 printf("%05d")
- sprintf()
- 函数:strlen()
- 函数:strchr()
- 3.3 竞赛题目选讲
- 例3-1:TeX中的引号
- 字符串的输入
- 三目运算符
- 例3-2 WERTYU
- “重构字典新定义法”
- 例3-3 回文词
- 函数: isalpha()
- 例3-4 猜数字的提示
- 例3-5 生成元
- 例3-6 环状序列
- 3.4 注解与习题
对于新手而言,最容易犯的错误就是:在定义数组时,将数组的范围定义成了变量。
错误示范:
int num ; cin >> num ; int a[num] ;//错啦!数组范围不能为变量!
但我们偶尔也会利用宏定义来设定数组范围。
什么是“宏定义”?
就是对于整个程序中,给一个常量起个名字,例如:
#define maxn 1010 //将1010起名字叫maxnx++ 与 ++x
简单来说,对于“x++”,记住:
** 先工作,再加薪! **
也就是说,对于
y = x++ ;
来说,先将x的值赋给y再自己加一 也就是等于
y = x ; x = x + 1 ;
而对于“++x” ,则是:
** 先加薪,再工作! **
y = ++x ;
等于
x = x + 1 ; y = x ;比较大的数组要在main函数外声明! 函数:memcpy()
作者在讲述两个数组a , b之间互相复制的关系时引入了函数memcpy(),并给出了相关操作:
memcpy(b , a , sizeof(int) * k) ; //将数组 a复制 k 个元素到数组 b memcpy(b , a , sizeof(a)) ; //直接取等
还可以推广到 double 类型变量。
该函数的头文件为:
#include
接下来作者引入了一道例题。
例一:开灯问题一道纯种模拟题。我们可以从中学到很多。
初始化的重要性作者在一开始就提到了初始化的重要性,尤其是在多组输入之中,我们要格外注意。
函数:memset()那么,我们应该如何解决初始化操作呢?尤其是多维数组,用n个for 嵌套循环实在是太麻烦了。
由此,引入了第二个函数: memset() 。
用法如下:
memset(a , 0 , sizeof(a)) ;
作用:把数组a清零。后面还会有“把数组a全部命名为-1”的操作。我们后续再说。
头文件:
#include取反( ! )符号妙用
一般来说,我们只会在布尔(bool)类型中使用到取反。
作者将他推广到了 int 类型 :
当 int a = 0 时 ,
进行 a = !a 操作就可以使 a = 1
设置标志变量 first ,记录只在第一行前不输出空格
很好理解的技巧,不多赘述。
先判断,再移动!可以利用C语言简洁的语法,但前提是保持代码的可读性。
而不是走一步以后发现越界了再退回来。这不是强制性要求,但养成良好习惯十分必要。
避免非法访问内存!通过短路运算符“&&”来保证不会访问非法内存。
3.2 字符数组本节开篇引入了一个例题来讲解字符数组。
例三:竖式问题 scanf("%s" , s)作者引入了一个新概念 scanf("%s" , s) 。
他会读入一个不含 空格 、 TAB 、 回车符 的字符串,存入数组s。
由于 s 为字符型数组,直接表示指针,因此可不用"&"(取地址符)。
printf("%5d") 与 printf("%05d")对于一个数按5位打印,如果小于五位数,前者补空格,后者补0 。
sprintf()sprintf(buffer , "%d%d%d" , x , y , z) ; //表示把x , y , z三个数字连在一起输出到字符串buffer //最后的结果是 buffer 为字符串类型 // 例如 :x = 10(int) , y = 20(int) , z = 30(int) // buffer = 102030(string)
由此引入了 fprintf(输出到文件) 、printf(输出到屏幕)、sprintf(输出到字符串) 之间的区别。
函数:strlen()作用:获取字符串实际长度。
| 下标 | 实际长度 |
|---|---|
| 0 | 1 |
| 1 | 2 |
| 2 | 3 |
| … | … |
| 25 | 26 |
strchr(str , a) ; //在 str 字符串中找 a 字符 //头文件: #include
推广到
strcpy(a , b) ;//赋值b到a strcmp(a , b) ;//比较,若相同返回false strcat(a , b) ;//连接(放到a中)3.3 竞赛题目选讲
每一道例题都能学到很多知识。
例3-1:TeX中的引号 字符串的输入作者共介绍了3种输入方法:
| 函数名称 | 用法 |
|---|---|
| fgetc(fin) | 读取打开的文件fin,返回一个int值,要去除EOF符 |
| scanf("%s" , s) | 遇到空格、换行就会停下 |
| str = getchar() | 需要特判EOF符 |
| fgets(buf , maxn , fin) | 读取文件中的一行,最多读取maxn-1个字符,一个字符没读到就返回NULL |
这里没有提到gets()因为他已经删去了。
三目运算符a : b ? c表示
当条件a为真时执行b反之执行c
最好不要用。
这里讲述了一种新的算法,他类似于将答案提前写在一个常数数组中,便于我们输出或使用。有点类似于搜索算法中把x y值的增减提前封装到一个数组中,是打表法的低配版。
本题中作者直接将键盘的格式封装到了数组s之中,之后每次调用只需要找数组的前一位即可。
后边还会用到他的思想。
又是一道“字典法”的题!
补充一下数组 msg[m*2+p]的含义是:
作者将数组分成了两个板块(就像是图书馆分成小说区、科普区…)m可以决定他是否是镜像类,当是镜像类时,m=1,此时直接去镜像区[2,3]去找答案。反之,m=0,去非镜像区找答案。而p决定着图书所在的排数。
综上就可以精准的定位答案的位置。
isalpha() ;//检查是否为字母 isdigit() ;//检查是否为数字 isprint() ;//检查是否为可打印字符 toupper() ;//转大写 tolower() ;//转小写 //头文件: #include例3-4 猜数字的提示
小心格式!!!!
每个数对前有空格!
c++中 无穷大的表示方法为:
#define INF 0x3f3f3f3f例3-6 环状序列
很好的模拟题。
输出字符(串):
putchar() ;3.4 注解与习题
另发题解,请关注~



