人人都能学会的编程入门课
胡光
原百度高级算法研发工程师
19410 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 38 讲
开篇词 (1讲)
人人都能学会的编程入门课
15
15
1.0x
00:00/00:00
登录|注册

05 | 数组:一秒钟,定义 1000 个变量

你好,我是胡光,咱们又见面了。通过前几节的学习,你已经了解了基本的程序结构。我们来简单总结一下,其中第一种结构就是顺序结构,它指的是我们所写的按照顺序执行的代码,执行完上一行,再执行下一行这种的。第二种就是分支结构,主要是用 if 条件分支语句来实现,主要特征是根据表达式的真假,选择性地执行后续代码。最后一种就是循环结构,用来重复执行某段代码的结构。
如果把程序比喻成工厂的话,现在你的工厂中已经有了各种各样的流水线,但这个工厂只是能生产产品还不行,还需要有存储的空间。今天,我们来学习的就是如何创建和使用工厂中的库房,本节之后,你的程序工厂就可以开工了!

今日任务

先来看看今天这 10 分钟的小任务吧。今天的任务是这样的,程序中读入一个整数 n,假设 n 不会大于 1000,请输出 1 到 n 的每一个数字二进制表示中的 1 的个数。
我举个例子哈,当 n 等于 7 的时候,我们把 1 到 7 的每个数字的二进制表示罗列出来,会得到下表所示内容:
表1:1到7的二进制表示
根据表 1 中的内容,如果你的程序编写成功的话,程序应该分别输出 1、1、2、1、2、2、3,这些输出内容分别代表每个数字二进制表示中 1 的数量。
对于这个任务,你想写出来一个可行的程序不难,例如:我们可以循环 n 次,每次计算一个数字二进制中 1 的数量。怎么计算一个数字二进制中 1 的数量呢?这个问题,你可能想采用如下程序来进行实现:
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文深入介绍了计算机内存存储和地址的概念,通过生动的示例和通俗易懂的语言,帮助读者深入理解了计算机内存存储和地址的概念,以及如何在程序设计中应用这些概念。文章首先从字节和地址的概念入手,解释了计算机中数据存储的基本单位和内存地址的作用。通过示例程序演示了如何使用 sizeof 运算符来获取数据类型所占用的字节数以及如何输出变量的内存地址。接着,讲解了数组元素在内存中的连续存储特性,以及数组名代表整个数组的首地址的等价关系。进一步探讨了 scanf 函数的使用,强调了向 scanf 函数传递变量地址的重要性。最后,给出了一个设计程序的思考题,要求读者设计一个去掉倍数的程序,展示了实际应用的技术挑战。通过今天的任务,读者会发现,有了数组以后,可以记录一些计算结果,这些计算结果可能对后续的计算有帮助,从而提高程序的执行效率。读者可以通过本文快速了解计算机内存存储的基本原理和相关技术应用,对于日后学习指针相关知识,会有很大的帮助。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《人人都能学会的编程入门课》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(35)

  • 最新
  • 精选
  • 罗耀龙@坐忘
    茶艺师学编程: 思考题:去掉倍数设计一个去掉倍数的程序, 要求如下: 首先读入两个数字 n 和 m,n 的大小不会超过 10,m 的大小都不会超过 10000; 接下来读入 n 个各不相同的正整数,输出 1 到 m 中,有哪些数字无法被这 n 个正整数中任意的一个整除。 我卡在这道题快10多天了,踩了不少的坑。 1、没有想好核心算法 一看到“整除”,我反射性想到“%(取模,是否等于0)”。这想法在处理单个被除数还行,但是这里要处理复数的被除数,如果接着用“&&”,程序不会算出结果。 2、没有理解透彻“数组” ·我曾经试着给第二次输入的数用数组,问题是这里是在循环内这样做是没有意义,就算是输入成数组了,但我也不能拿一堆数字直接除以该数组获得结果 ·我也试过给要输出的结果存进数组,幻想过能不能在数组里直接计算(剔除重复的、其他的可被整除数) 3、同样的,我也没有真的理解“循环” 看似要用“数组”,其实循环就能直接解决了······· 交作业: # include <stdio.h> int sum[20005] = {0} ; //创建用来存放计算结果的数组sum int main(){ int n, m, num, i, j; //创建变量n,m(题目的第一次输入)num(第二次输入),i,j(循环用的变量) printf("请输入要计算的两个数组:\n(注意:第一个数字请不要超过10,第二个请不要超过10000)\n"); scanf( "%d%d" , &n, &m); //第一次输入 if( n <= 10 && m <= 10000){ for( i = 0 ; i < n ; i++ ){ scanf( "%d" , &num ); //第二次输入,按照n的数量输入n个数字 for ( j = num ; j <= m ; j += num ){ //核心part1:在数组sum上标记输入的整数的倍数 sum[j] = 1; //方法为只要是在数组sum上第(输入的整数的倍数)位,对应的值为1 } } for( i = 1 ; i <= m ; i++ ){ //核心part2:再开循环,在数组sum上一个个检查,看哪个位置的值为1 if( sum[i] == 1 )continue; //下面是循环输出数字,continue是“跳出循环”,对应的条件就是“在XX位置上的值为1” printf( "%d\t" , i ); //换句话说,就是在数组sum上的值为1的对应标号i就不与输出 } } else printf("同学,超纲啦!"); return 0 ; } //其结果,就是通过循环(嵌套循环)、加法、数组标记、筛选(选择不输出)就到达了目的。

    作者回复: 整个思考过程很完整,很棒!尤其代码中的 j+=sum 很得循环精髓!d(^_^o)

    2020-05-10
    2
    3
  • 学写代码的猪
    感觉老师课程的步子跨度还是比较大的,真的小白如果不花几倍的时间吸收消化,还真容易扯着蛋的,哈哈。

    作者回复: d(^_^o)所以给大家推荐了三本书。资料比较多的内容,专栏里面就很少会讲,专栏里主要讲阻碍大家学习编程的部分。否则,32讲,可能才讲完语言。

    2020-01-15
    3
    3
  • 为什么scanf(“%d”,&a);是用%d整数占位符替换的&a的地址,不应该是%p吗?

    作者回复: 后面讲到指针的时候,你就明白了。&a传入的是a的地址,这样scanf才能把处理结果放到变量a里面。

    2020-01-16
    2
  • Jinlee
    老师,您给的示例代码中,10能被5整除,为啥也输出了呢

    作者回复: 啊,sorry,笔误,多写上去的!赞!👍

    2020-01-15
    2
    2
  • 行问
    以二进制数字 110 为例,末尾是 0,计数量 cnt 不进入计算;然后 110 除以 2,即去掉最后一位的 0,变成了 11,此时末尾是 1,计数量 cnt 就加 1;11 再除以 2,变成了 1,此时末尾是 1,计数量 cnt 再次加 1 。最后的 n 等于 1,再除以 2,n 变成了 0,循环结束。 这个段落的叙述、逻辑,让初学者直接挂掉了。110 除以 2,即去掉最后一位的 0, 变成了 11。我在大脑、拿纸笔,反复的推算,它都不成立。以二进制除法?十进制除法?

    作者回复: 二进制除法

    2020-01-14
    4
    2
  • Noya
    // 求二进制中 1 的个数 #include <iostream> using namespace std; int n; int cnt; int main(void) { scanf("%d", &n); for (int i = 1; i <= n; i++) { int t = i; while (t) { if (t & 1) cnt++; t >>= 1; } printf("%d ", cnt); cnt = 0; } return 0; }

    作者回复: 不错!基本实现了功能!d(^_^o)

    2020-04-30
    1
  • 梅利奥猪猪毛丽莎肉酱
    嗯还是相对比较基础的,对于萌新来说建议老师在图5种补充一个y=*****000000,这样萌新会看的更加轻松,和x做对比的确就差个1,至于前面的*号为什么一致,也是因为与的运算,因为1&1=1, 0&0=0,然后在结合下面的程序看,一看就看懂了

    作者回复: (。ì _ í。)好的,谢谢你的建议,d(^_^o)

    2020-01-14
    2
    1
  • 徐洲更
    如果题目求的并不是1-n的1的数,而是n的1的数量,利用递推的解决方法的时间复杂度是不是就比最开始的方法高呢

    作者回复: 对的,如果单纯的只是求n中二进制表示1的数量的话,那么直接求就好了,用不着递推。前后是两种性质完全不同的题目。

    2020-01-14
    3
    1
  • 草帽Plasticine
    思考题:去掉倍数,第一次没看答案没看底下的评论,完全自己想的写出来还能符合题意太激动了啊啊啊 老师讲得太棒了! #include <stdio.h> #include <stdlib.h> int main() { int n, m, num[10000], temp[10000]; scanf("%d", &n); scanf("%d", &m); // 读入用户输入的n个数字 for (int i=0; i<n; i++) scanf("%d", &num[i]); // 创建一个 1 ~ m 的数组 for (int i=0; i<m; i++) temp[i] = i+1; // 让 1 ~ m 的数字分别判断是否能整除读入的n个数字 for (int i=1; i<=m; i++) { for (int j=0; j<n; j++) { if (i%num[j]==0) temp[i-1] = 0; } } // 打印符合条件的值 for (int i=0; i<m; i++) { if (temp[i] != 0) printf("%d ", temp[i]); } return 0; }

    作者回复: 没毛病!d(^_^o)

    2020-05-12
  • 小风
    按位与不应该用&&计算吗,一个&可以?

    作者回复: 两个&&,这个是【条件与】, (a && b) 这个条件与表达式的值只有 0 或者 1 而 & 才是我们所说的位运算,按位与,(a & b) 这个表达式的值,是 a 和 b 的二进制表示按位做与运算以后的结果,是一个整数范围的值。

    2020-05-02
    2
收起评论
显示
设置
留言
35
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部