C 语言 - 循环嵌套、函数
1. 循环嵌套
1.1 作用
循环 套 循环。
1.2 使用
需求1:
打印以下图形:
* * * * * * * * * * * * * * * *
代码:
1、使用循环打印
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 0; i < 4; i++){printf("* * * *\n");}return 0; }
2、循环嵌套打印
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 0; i < 4; i++) //外层控制行数{for (int j = 0; j < 4; j++) //内层控制每一行的样式{printf("* ");}printf("\n");}return 0; }
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){if (j <= i){printf("* ");}}printf("\n");}return 0; }
小结:
i 0 * 1 * * 2 * * * 3 * * * *0 1 2 3 j
外层
控制行数
内层
控制每一行的样式
需求2:
打印以下图形
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
代码:
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 0; i < 9; i++){for (int j = 0; j < 9; j++){if (j <= i){printf("* ");}}printf("\n");}return 0; }
优化:
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 0; i < 9; i++){for (int j = 0; j <= i; j++){printf("* ");}printf("\n");}return 0; }
需求3:
打印9*9乘法表
#include <stdio.h> int main(int argc, char const *argv[]) {for (int i = 1; i < 10; i++){for (int j = 1; j <= i; j++){// 1 * 1 = 1printf("%d * %d = %d\t", i, j, i*j);}printf("\n");}return 0; }
结果如下:
1.3 案例
例1:
百文百鸡
- 中国古代,有一个人去市场买鸡
- 公鸡3文钱一只
- 母鸡2文钱一只
- 小鸡1文钱三只
- 这个人有100文钱,要求买100只鸡
- 请问他可以有多少中买法,每种每种买法可以可以公鸡多少只,母鸡多少只,小鸡多少只
数学思路假设:公鸡x只母鸡y只小鸡100-x-y只3 * x + 2 * y + (100 -x -y) / 3 = 100;x + y + (100 - x - y) = 100; 代码思路:公鸡取值范围:0~33母鸡取值范围:0~50小鸡取值范围:0~100遍历
代码:
#include <stdio.h> int main(int argc, char const *argv[]) {int num = 0;for (int g = 0; g < 34; g++){for (int m = 0; m < 51; m++){int x = 100 - g - m;if (3 * g + 2 * m + x / 3 == 100 && x % 3 == 0){printf("公鸡:%d只,母鸡:%d只,小鸡:%d只\n", g, m, x);num++;}}}printf("共有%d种买法\n", num);return 0; }
输出结果:
公鸡:0只,母鸡:40只,小鸡:60只 公鸡:5只,母鸡:32只,小鸡:63只 公鸡:10只,母鸡:24只,小鸡:66只 公鸡:15只,母鸡:16只,小鸡:69只 公鸡:20只,母鸡:8只,小鸡:72只 公鸡:25只,母鸡:0只,小鸡:75只 共有6种买法
例2:
鸡兔同笼
养殖户将鸡与兔子放在同一个笼中
该养殖户无法数清鸡的数量与兔的数量
但是该养殖户数出了腿的数量与头的数量
腿60
头20请您帮助养殖户计算鸡兔个几何
数学思想:设:兔子有t只,鸡有j只4 * t + 2 * j = 60;t + j = 20;t = 20 - j;4 * (20 -j ) + 2j = 60;80 -4j + 2j = 60;80 - 2j = 60;80 - 60 = 2j;20 = 2j;j = 10;t = 10; 代码思想:鸡的取值范围:0~20兔的取值范围:0~15
代码:
#include <stdio.h> int main(int argc, char const *argv[]) {int tag = 0;for(int j = 0; j <= 20; j++){for(int t = 0; t <= 15; t++){if(j + t == 20 && 4 * t + 2 * j == 60){tag = 1;printf("鸡有:%d只,兔有:%d只\n",j,t);}}}if(tag){printf("输入的头与腿数量正确\n");}else{printf("此题无解,头腿数量有误\n");}return 0; }// 输出:鸡有:10只,兔有:10只
2. 函数
2.1 作用
封装一段代码,使其便于使用。
注意:
- 一个功能可以封装一个函数
- 定义函数的时候一切
以功能为目的
,根据功能
去定义函数的参数
和返回值
。
2.2 分类
1、库函数 (c 库实现的)
- 不能直接操作内核
2、系统调用 (操作系统实现的函数)
- 可以直接操作内核
3、自定义函数 (程序员自己实现的函数)
- 定义
- 调用
2.3 使用步骤
① 声明(可有可无)
语法:
extern 返回值类型 函数名(形参列表);
注意:
- 在函数外声明
- 声明函数时可以忽略形参的变量名不写
② 定义
语法:
返回值类型 函数名(形参列表)
{函数体
}
解释:
返回值类型
:返回值的数据类型,当函数没有返回值
,返回值类型为void(空类型)
函数名
:标识符,自定义的
形参列表
:根据实际情况,可有可无,多个参数之间使用逗号隔开,每个参数有数据类型变量名编写
函数体
:封装的代码return:结束当前函数
return xxx:结束当前函数并返回xxx,xxx就是返回值
注意:
一个函数
最多只能有一个返回值
同一个源文件
中函数名不能重复
(c语言不支持重载)- 函数不能定义在函数中
例1:定义函数计算10+1的结果
voild add01()
{int x = 10 + 1;printf("x=%d\n",x);
}
例2:定义一个函数计算两数之和
void add02(int x,int y)
{int sum = x + y;printf("sum=%d\n",sum);
}
例3:定义一个函数计算 1 + 2的结果,并将结果返回给调用处
int add03()
{int x = 1 + 2;return x;
}
例4:定义一个函数判断是否成年,成年返回1,未成年返回0
int iscN(int age)
{if(age >= 18){return 1;} else{return 0;}
}
③ 调用
语法:
- 调用
无返回值
的函数
- 函数名(实参列表);
- 调用
有返回值
的函数
- 函数名(实参列表);
- 变量名 = 函数名(实参列表);
注意:
实参列表
要与形参列表
一致 (长度一致,顺序一致,数据类型一致)- 一个函数可以被调用无数次
- 只能在函数中调用
例:
add01();add02(1,2);
add02(5,10);int a = 1;
int b = 9;
add02(a,b);add03();
int x = add03();iscN(19);
int y = iscN(20);
int age = 17;
int z = iscN(age);
2.4 特殊情况
① 多重调用
在函数A中调用函数B,在B中调用c,c中调用....
例:
#include <stdio.h>
extern void funA();
extern void funB();
extern void func();
void funA()
{printf("A开始\n");funB();printf("A结束\n");
}void funB()
{printf("B开始\n");func();printf("B结束\n");
}
void func()
{printf("c开始\n");printf("c结束\n");
}
int main(int argc, char const *argv[])
{funA();return 0;
}
② 递归
在函数中调用该函数,会形成循环
例:
#include <stdio.h>
void test(int num)
{printf("num=%d\n",num);if (num >= 0){num--;test(num);}
}
int main(int argc, char const *argv[])
{test(2);return 0;
}
③ 多文件编译,跨文件调用函数
-
文件1:05_codeA.c
#include <stdio.h> extern void test05(); extern int num; int main(int argc, char const *argv[]) {test05();printf("05_codeB\tnum=%d\n",num);return 0; }
-
文件2:05_codeB.c
#include <stdio.h> int num = 20; void test05() {printf("测试\n"); }
-
编译:
gcc 05_codeA.c 05_codeB.c
-
结果:
3. 变量的存储类别
-
程序是一个文件,
-
一个正在进行的程序称为一个进程
-
一个进程系统会为其分配一片运行内存
-
在32位系统下,每个进程的寻址范围是4G
3.1 数据存储分类
1)、堆
在动态申请内存的时候,在堆里开辟内存。
2)、栈
主要存放局部变量。
3)、静态全局区
未初始化的静态全局区
- 静态变量(定义变量的时候,前面加 static 修饰),或全局变量 ,没有初始化的,存在此区
初始化的静态全局区
- 全局变量、静态变量,赋过初值的,存放在此区
4)、代码区
存放咱们的程序代码
5)、文字常量区
存放常量的
3.2 函数相关
① 普通成员函数(全局函数)
语法:返回值类型 函数名(形参列表){函数体}
特点:
可以在当前
.c 文件
(源文件)中使用,也可以在其他.c文件
中使用
② 静态成员函数(静态全局函数)
语法:static 返回值类型 函数名(形参列表){函数体}
特点:
只能在当前
.c文件
(源文件)中使用
3.3 变量相关
① 局部变量
定义位置:当前函数中
作用域:所
声明的代码块中
生命周期:调用所在函数时生成,随着所在
代码块的执行完毕
而销毁默认值:随机数
② 成员变量(全局变量)
定义位置:在函数外
作用域:当前程序中
生命周期:随着所在进程的执行而生成,随着
所在进程的结束
而结束默认值:0
③ 静态局部变量
定义位置:当前函数中
作用域:所声明的代码块中
生命周期:第一次调用所在函数时生成,随着
所在进程的执行完毕
而销毁,只会定义一次默认值:0
例:
#include <stdio.h>
void test()
{static int x = 10;x++;printf("x=%d\n",x);
}int main(int argc, char const *argv[])
{test();test();test();return 0;
}
输出结果:
x=11
x=12
x=13
④ 静态成员变量(静态全局变量)
定义位置:在函数外
作用域:当前源文件中
生命周期:随着所在进程的执行而生成,随着
所在进程的结束
而结束默认值:0
4. const
const 修饰的变量值不能被修改