A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 徐荘 中级黑马   /  2016-8-6 00:08  /  1130 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

#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背包问题
   
   
   
   
   

2 个回复

正序浏览
顶一下,之后会用到
回复 使用道具 举报
kakam 来自手机 中级黑马 2016-8-6 22:20:16
沙发
顶,支持一下!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马