用循环的方式解决问题叫做递推,递归函数解决问题的方式叫递归。递归函数内部要分两组情况编写代码,一组是最后一步的处理,这组代码必须是可以直接解决问题的,另外一种是处理所有复杂情况的代码,这组代码要转换成递归调用来解决。转换的原则是参数变化但是结果一致。
变量有生命周期和作用域这两个重要特征,生命周期表示变量在什么时间范围内有效,作用域表示变量在代码的什么范围内可以被使用。
全局变量的生命周期是整个程序运行期间,作用域是所有代码。
局部变量的生命周期是声明它的函数内部,作用域是函数内部变量声明语句后面的代码。
块变量是声明在语句块内部的变量(例如if,for,while语句)。块变量的生命周期是语句块的运行时间段,作用域是语句块内部在变量声明语句之后的代码。
不同层次的变量可以重名,在使用重名变量的时候采用就近原则。
如果有一组数据的使用方式是先获得的数据后处理则我们可以使用栈来对他们进行管理。向栈中放置数据的操作叫做入栈,从栈中获取数据的操作叫出栈。栈的操作特点称为后进先出。
sleep函数可以让程序休眠指定的妙数,参考练习10clock.c。
程序段(代码段)用来存储语句。这个段落在运行的时候不可以修改。
程序中的数据被分散放置在不同的段落里。栈和堆是程序中两个用来放置数据的段落。所有的局部变量和函数形参都是放置在栈里的。
函数在运行过程中都会在栈中分配一段区域,这个区域里存放了函数的所有形参和局部变量。当函数运行结束的时候这个区域被释放,内部的所有内容不保证还继续有效。
堆用来管理编写代码时不知道数量或者数量非常巨大的数据。堆中变量的生命周期由程序员编写程序控制。堆中变量一旦使用完成后必须编程释放。
static和const都是可以用来修饰变量的关键字,参考练习11key.c。
auto关键字也可以修饰变量,所有局部变量都是auto类型的变量,不需要特别说明
register关键字可以修饰寄存器变量,这种变量会单独占据一个寄存器。编译器可以自己决定。
volatile关键字也可以修饰变量,这种变量同时被很多程序或硬件使用,他们的数值随时会改变。
/*
扫雷练习
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void plant(int map[10][10], int row_num, int col_num) {
int num = 0;
while (num < 10) {
int row = rand() % row_num;
int col = rand() % col_num;
if (!map[row][col]) {
map[row][col] = 1;
num++;
}
}
}
void show(int map[10][10], int row_num, int col_num) {
int loop = 0, loop_1 = 0;
for (loop = 0; loop <= (row_num - 1); loop++) {
for(loop_1 = 0; loop_1 <= (col_num - 1); loop_1++) {
printf("%d ", map[loop][loop_1]);
}
printf("\n");
}
}
int main() {
int map[10][10] = {0};
srand(time(0));
plant(map, 10, 10);
show(map, 10, 10);
return 0;
}
/*
递归练习
*/
#include <stdio.h>
void love(int times) {
if (1 == times) {
printf("我爱你\n");
}
else {
printf("我爱你\n");
love(times - 1);
}
}
int main() {
int loop = 0;
love(5);
return 0;
}
/*
阶乘的计算练习
*/
#include <stdio.h>
/*int mul(int res, int cur, int limit) {
if (cur == limit) {
return res * cur;
}
else {
return mul(res * cur, cur + 1, limit);
}
}*/
int mul(int res, int cur) {
if (1 == cur) {
return res;
}
else {
return mul(res * cur, cur - 1);
}
}
int main() {
int value = 0, loop = 0, value_1 = 1;
printf("请输入一个数字:");
scanf("%d", &value);
/*for (loop = 1; loop <= value; loop++) {
value_1 = mul(value_1, loop);
}*/
//value_1 = mul(1, 2, value);
value_1 = mul(1, value);
printf("结果是%d\n", value_1);
return 0;
}
/*
汗诺塔练习
*/
#include <stdio.h>
void han(int num/*盘子的个数*/, char from/*开始柱子的编号*/, char mid/*中转柱子的编号*/, char dest/*目标柱子编号*/) {
if (1 == num) {
printf("%d:%c-->%c\n", num, from, dest);
}
else {
//首先把num - 1个盘子从开始柱子移动到中转柱子上
han(num - 1, from, dest, mid);
//把编号为num的盘子从开始柱子移动到目标柱子
printf("%d:%c-->%c\n", num, from, dest);
//最后把num - 1个盘子从中转柱子移动到目标柱子
han(num - 1, mid, from, dest);
}
}
int main() {
int num = 0;
printf("请输入盘子的个数:");
scanf("%d", &num);
han(num, 'a', 'b', 'c');
return 0;
}
/*
费式数列的计算练习
*/
#include <stdio.h>
/*int fei(int shu, int shu_1, int bian_hao, int zui_da) {
if (bian_hao == zui_da) {
return shu_1;
}
else {
return fei(shu_1, shu + shu_1, bian_hao + 1, zui_da);
}
}*/
int shu[100] = {0}; //全局变量
int fei1(int bian_hao) {
//int shu[100] = {0}; //局部变量
if (bian_hao <= 1) {
return 1;
}
else {
if (!shu[bian_hao]) {
shu[bian_hao] = fei1(bian_hao - 2) + fei1(bian_hao - 1);
}
return shu[bian_hao];
}
}
int main() {
int shu = 1, shu_1 = 1, bian_hao = 0, xun_huan = 0;
printf("请输入数字编号:");
scanf("%d", &bian_hao);
/*for (xun_huan = 2; xun_huan <= bian_hao; xun_huan++) {
shu_1 += shu;
shu = shu_1 - shu;
}*/
//shu_1 = fei(1, 1, 1, bian_hao);
printf("结果是%d\n", fei1(bian_hao));
return 0;
}
/*
变量声明周期和作用域练习
*/
#include <stdio.h>
int shu; //全局变量,自动被初始化成0
void f1() {
int shu_1; //局部变量
printf("%d\n", shu_1);
shu_1 = 4;
}
void f2() {
int shu_1 = 3;
int shu_2 = 5;
int shu_3 = shu_1 + shu_2;
int shu_4 = 7;
}
int main() {
int shu_1 = 0; //局部变量
{
int shu_2 = 0; //块变量
}
//printf("%d\n", shu_2); //超出了shu_2的作用域
f1();
f2();
f1(); //打印结果不是第一次执行f1函数时赋值的4,因为局部变量的生命周期只限于函数执行期间
return 0;
}
/*
变量练习
*/
#include <stdio.h>
int shu;
int main() {
printf("%d\n", shu); //打印全局变量
int shu = 2;
printf("%d\n", shu); //打印局部变量
{
int shu = 3;
printf("%d\n", shu); //打印块变量
}
printf("%d\n", shu); //打印局部变量
return 0;
}
/*
栈练习
*/
#include <stdio.h>
int main() {
int shu[10] = {0}, shu_zi = 0, ge_shu = 0, xun_huan = 0;
printf("请输入一个数字:");
scanf("%d", &shu_zi);
do {
shu[ge_shu] = shu_zi % 10;
ge_shu++;
shu_zi /= 10;
} while (shu_zi);
for (xun_huan = ge_shu - 1; xun_huan >= 0; xun_huan--) {
printf("%d ", shu[xun_huan]);
}
printf("\n");
return 0;
}
/*
栈练习
*/
#include <stdio.h>
int shu[10];
int ge_shu; //栈中有效数据的个数
//向栈中放置一个数据
void push(int shu_zi) {
shu[ge_shu] = shu_zi;
ge_shu++;
}
//从栈中获取一个数据
int pop() {
ge_shu--;
return shu[ge_shu];
}
//判断栈是否空了
int is_empty() {
return 0 == ge_shu;
}
//判断栈是否满了
int is_full() {
return 10 == ge_shu;
}
/*int main() {
int shu[10] = {0}, shu_zi = 0, ge_shu = 0, xun_huan = 0;
printf("请输入一个数字:");
scanf("%d", &shu_zi);
do {
push(shu_zi % 10);
shu_zi /= 10;
} while (shu_zi);
while(!is_empty()) {
printf("%d ", pop());
}
printf("\n");
return 0;
}*/
int main() {
int shu_zi = 0;
do {
printf("请输入一个数字:");
scanf("%d", &shu_zi);
push(shu_zi);
} while(0 != shu_zi);
while (!is_empty()) {
printf("%d ", pop());
}
printf("\n");
return 0;
}
/*
秒表练习
*/
#include <stdio.h>
#include <time.h>
#include <unistd.h>
int main() {
int miao = time(0), pre = miao;
while (1) {
//while(pre == time(0));
sleep(1); //让程序休眠指定的妙数,时间不精确
pre++;
printf("%3d\r", pre - miao);
fflush(stdout);
}
return 0;
}
/*
修饰变量的关键字练习
*/
#include <stdio.h>
int f1() {
static int shu = 4; //静态局部变量的生命周期被扩展成整个程序运行期间,只会被初始化一次
printf("%d\n", shu);
shu = 7;
}
int main() {
const int shu_zi = 3; //const变量只能用初始化赋值
//shu_zi = 7; const变量不可以被赋值
f1();
f1();
return 0;
}