#pragma mark - 0 知识回顾
/*
求签:
网络求签,要求用户输入5个两位数,保存到数组中
如果某一个数中同时包含8和4 那么这个数无效
如果5个数中只要出现一个含有4的数,那么属于下下签
如果5个数中没有4,也没有8那么属于中等签
如果5个数中没有4 但是有8 那么属于上上签.
请用户输入5个数,判断是哪一种签
清用输入5个两位数,保存到数组,然后挨个判断每一个数
定义一个数组 int nums[5];
2
*/
#include <stdio.h>
int main(int argc, const char * argv[]) {
// insert code here...
//1.定义数组
int nums[5];
int len = sizeof(nums)/sizeof(int);
// .2.请用户输入
for (int i = 0; i < len; i++) {
printf("请输入第%d个数:\n",i+1);
scanf("%d",&nums[i]);
}
//3.判断
// 如果某一个数中同时包含8和4 那么这个数无效
//一个旗帜变量,目的 标识这个循环到底是不是正常结束的
int flag = 0;
int flag8 = 111;
for (int i = 0; i < len; i++)
{
//nums[i]
if (nums[i] == 48 || nums[i] == 84)
{
//这个数无效
//无效:不参与下下签或者什么签的判断
continue;//下一个数
}
//如果这个数num[i],个位或者十位包含4那么就是下下签
int ge = nums[i] % 10;
int shi = nums[i] / 10;
if (ge == 4 || shi == 4)
{
//下下签
flag = 1;
break;
}
if (ge == 8 || shi == 8)
{
//有一个是8
flag8 = 888;
// break;//
//这里不能break 为什么?因为下一个数还不没判断
}
}
//程序执行到这,可能是出现了4结束的 也可能是循环正常结束的
if (flag == 1) {
printf("你个屌丝 还想娶媳妇\n");
}
if (flag == 0) {
//证明没有4
//两种情况
//1.有8
if (flag8 == 888) {
//有8
printf("您的如意郎君即将到来\n");
}else{
//没有
printf("你只能靠自己找,注册世界佳缘把\n");
}
//2.没8
}
/*
num
个位 = num % 10;
十位 = num / 10;
num == 84 || num == 48
*/
// 如果5个数中只要出现一个含有4的数,那么属于下下签
// 如果5个数中没有4,也没有8那么属于中等签
// 如果5个数中没有4 但是有8 那么属于上上签.
// 4.得出结论
#pragma mark - 0_20 [掌握]参数的值传递
1,什么叫值传递
参数的类型是 int float double char 等基本数据类型的时候
调用者传入一个实参,然后在函数中改变这个参数的值,那么调用者中的实参不会改变
int num = 10;
test(num);//在test函数中对num进行了修改
不会影响到 调用者中实参的值
#pragma mark - 0_21 [掌握]数组作为函数的参数
1.数组的元素能不能当做函数的参数?
可以,数组元素本质上就是一个普通变量
void test(int num);
int nums[] = {10,20,304};
test(nums[1]);//调用函数
数组元素作为函数参数 和普通变量 没有任何区别
2.数组可不可以作为函数的参数? 可以
函数如何声明?
void testArr(int num[]);
如何调用数组作为参数的函数
int nums[] = {1,30,20};
testArr(nums);
3,数组名代表数组的地址,数组当参数时传递的是数组名,即数组的地址
4.在函数内部无法使用sizeof计算参数数组的长度
怎么办?只能有调用者 在调用函数的时候,第一个传递一个数组,第二传递这个数组的长度
只要调用函数传递了数组 那么必须加一个参数 数组的长度
//打印数组
void printArr(int nums[],int len){
//因为调用的函数内部 无法算数组的长度
//注意:不管这个长度有没有用
//
for (int i = 0; i < len; i++) {
printf("%d",nums[i]);
}
}
//调用的时候
int main(){
int nums[] = {1,10,3,4,5};
printArr(nums,sizeof(nums)/sizeof(int));
}
#pragma mark - 0_22 [掌握]数组作为参数是地址传递
1.什么叫做值传递和地址传递
值传递:就是参数类型是普通变量
地址传递:参数类型是数组的
值传递和地址传递有什么区别?
值传递不会改变原有变量的值
地址传递会改变原有数组的值
#pragma mark - 0_23 [掌握]重要的结论
1.当数组作为函数参数的时候,在函数内部如何获取数组长度?不可以
只要数组作为函数的参数 那么这个函数必须+1个参数 就是数组的长度
2.当数组作为函数参数的时候,是地址传递.
在函数内部修改数组,会对原来的数组产生影响
#pragma mark - 0_24 [了解]产生不重复的随机数
1.判断一个数 在数组中存不存在
2.写一个函数 判断一个数 在数组中存不存在
3.随机的产生一个双色球号码
一个双色球号码包括 6个1-33随机数
包括 1个1-16随机数
思路:
1,应该将之前产生的随机数存储起来.
2,每产生1个随机数.就判断新产生的这个随机数和之前的有没有重复.如果有重新产生,如果没有下1个.
"代码,见今天的代码文件夹"
#pragma mark - 0_25 [掌握]选择排序
思路:
1.固定一个下标,与下标之后的元素相比
2.依次固定所有元素的下标
int main(int argc, const char * argv[]) {
int arr[] = {12,1,3,24,346,4,532,3,46,5};
//计算出数组的长度
int len = sizeof(arr) / sizeof(arr[0]);
for(int i = 0; i < len - 1; i++)//外层循环控制轮数. n个数,需要比较n-1轮.
{
//拿下标为i的元素 和后面的所有的元素依次进行比较.比较到最后一个元素,所以j<len
for(int j = i+1; j < len; j++)
{
if(arr[i] > arr[j])
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
}
for(int i = 0; i < len; i++)
{
printf("%d\n",arr[i]);
}
return 0;
}
#pragma mark - 0_26 [掌握]冒泡排序
1.每一轮,相邻两个数 两两之间进行比较
2.每循环一次从尾部确定一个数
3.循环n次就搞定了
int arr[] = {12,1,32,4,35,46,4,53,24,36,5,76};
//计算出数组的长度
int len = sizeof(arr) / sizeof(arr[0]);
//循环 目的:控制轮数
for (int i = 0; i < len - 1; i++) {
//每一轮 两两比较
//第i轮 比较多少次? len - 1 - i
for (int j = 0; j < len - 1 - i; j++) {
//arr[0] arr[1]
//arr[1] arr[2]
if(arr[j] > arr[j+1]){
//交换
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
#pragma mark - 0_27 [掌握]二分查找法
在1个数组中查找指定的元素的下标.
1). 从头到尾的挨个挨个的遍历. 这样找的话 效率低下.
2). 使用折半查找. 前提是:这个数组是有序
#pragma mark - 01 [掌握]数组函数模块
"见 视频中的代码文件夹 下 "Day10-字符串" 项目
#pragma mark - 02 [掌握]成绩统计作业讲解
题目
写1个程序,接收输入班级的人数, 然后依次的输入每1个学员的成绩.
将学员的成绩存储在数组之中.
输入完毕之后, 显示总成绩和平均成绩.
然后再去掉1个最高分和1个最低分, 再计算平均成绩.
"见 视频中的代码文件夹 下 "Day10-字符串" 项目
#pragma mark - 03 [掌握]作业讲解
题目1
有1个整型数组,请自己设计算法将这个数组中的元素进行翻转(此题选作*****)
比如: 有数组 int arr[5] = {10,11,3,45,6};
将元素的值设置为翻转
题目2
请用户输入10个整型的数,将其存储到数组之中. 然后将其逆序输出.
"见 视频中的代码文件夹 下 "Day10-字符串" 项目
#pragma mark - 04 [了解]二维数组的声明
1.二维数组到底是什么?
1>二维数组可以看成一维数组,这个一维数组中 每一个元素都是一个数组
2>看成一个几行几列的表格
2.格式:
数据类型 数组名称[行数][列数];
3.专业术语:
1>元素:
2>下标:每一个元素都有2个下标,行下标和列下标,从0开始
3>长度:是指数组中元素的个数
#pragma mark - 05 [掌握]如何往二维数组中存储数据
1.为二维数组元素赋值的格式
数组名[行下标][列标下] = 100;
2.赋值的时候 数据的类型 要和 元素的类型一致
如果不一致,能自动转换的 会隐式转换
3.不要越界
越界之后的结果难以预料
#pragma mark - 06 [掌握]取出二维数组的元素的值和遍历二维数组
1.如何取数据,要明确你要取出的元素的下标
printf("%d",二维数组名[行下标][列下标]);
2.不管是行下标和列下标都不能越界
3.遍历二维数组的元素
int nums[3][4];
可以看成3行4列的表格
/*
10 20 30 40
50 60 70 80
90 90 89 80
*/
for (int i = 0; i < 行数; i++) {
for (int j = 0; j < 列数; j++) {
//nums[i][j];
}
printf("\n")
}
#pragma mark - 07 [掌握]二维数组的行数列数以及默认值的问题
1.关于二维数组的行数和列数
a. 在声明二维数组的时候 必须要指定行数和列数.
b. 并且这个行数和列数: 可以是常量,变量,表达式 还可以是0或者1
但是一定不能是小数 负数
2.如果二维数组没有初始化,里面可能存的是垃圾值
#pragma mark - 08 [掌握]二维数组的初始化
1.在定义的同时初始化:静态初始化
1>全部赋值
int nums[3][4] = {{1,2,3,4},{5,6,6,8},{4,5,6,7}};
int nums[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
2>部分赋值
int nums[3][4] = {{1,2},{3,4},{5,6,7}};
/*
1 2 0 0
3 4 0 0
5 6 7 0
*/
int nums[3][4] = {1,2,3,4,5,6,7};
/*
1 2 3 4
5 6 7 0
0 0 0 0
*/
// 行可以省略 列不能省略
int nums[][4] = {1,2,3,4,5,6,7,8,9,10};
/*
1 2 3 4
5 6 7 8
9 10 0 0
*/
3>奇葩的方式
int nums[3][4] = {[0]= {1,2,3,4},[2]= {6,7,8,9}};
int nums[3][4] = {[0][1] = 10};
/*
1 2 3 4
0 0 0 0
6 7 8 9
*/
2.先定义后初始化:动态初始化,只有一种方法,挨个赋值
int nums[3][3];
nums[0][0] = 0;
只要是静态初始化,没有初始化的部分默认值是0,
int nums[3][4] = {0};
动态初始化中如果默写元素没有赋值 那么就是垃圾值
#pragma mark - 09 [掌握]二维数组的应用场景
1, 案例
某公司 有3个销售小组.每1组有4个人.
将上个月的每一个人的销售成绩保存起来.
1). 找出销售之王.
2). 求每1组的平均销售成绩.
2,什么时候要使用二维数组?
二维数组是一个有行有列的表格.
当你有类似于表格形状的数据的时候.就可以使用二维数组.
测试去掉的题目:
5.完数,一般指完全数,一个自然数如果它的所有真因子(即除了自身以外的约数)的和等于该数,那么这个数就是完全数,如:6的真因子有1 、2、3,6=1+2+3,所以6是一个完全数。
编程输出1000以内的所有完数
课外的补充:
快速排序
A*算法 A star 寻路算法
0-1背包问题
|
|