美文网首页技术苦心孤诣IT控
21天C语言代码训练营(第一天)

21天C语言代码训练营(第一天)

作者: 天花板 | 来源:发表于2015-11-18 21:52 被阅读12361次

    为了配合专题C语言从零开始,今天开始一个新的专题《21天C语言代码训练营》。这个专题重点针对从零开始系列进行练习题讲解。以21天为一个周期,为大家提供编程方面的实例讲解。

    最近,越来越多的初学者朋友在给我的邮件中提出这样的问题:我在文章中讲的东西他们都看懂了,但具体到自己写代码的时候却完全不知道从何入手。其实看懂知识点例程和真正学会写代码之间相差了好几条街,我一再强调,学编程没有捷径,只有老老实实地敲代码。对于文章中的例子,大家一定要达到自己能够完整的敲出来才行。当然,这里并不是要求大家死记硬背,要求的是在懂得设计思路和程序语法的基础上,经过自己的二次加工后重新实现的过程。

    在这个专题中,我们以练习为主,讲解为辅,力求寻找出一种帮助大家快速提高编码能力的新玩法。也希望朋友们紧跟我的更新速度坚持每天做练习,大家共同进步。

    欢迎大家每天前来打卡~


    训练营规则

    • 每天出一道练习题,请大家自己完成编码
    • 第二天的文章中会告诉大家一种或几种经典解决方法
    • 完成练习的同学,欢迎大家把代码贴在留言中
    • 如果有问题,也请留言,我会找机会集中解答

    希望这种手把手的方式能够帮助大家尽快掌握C语言编程。


    1. 例题

    今天我们先来讲解一道C语言的经典例题,也是从零开始系列中的一道课后练习题。

    请用控制台程序绘制如下图案。

    循环经典例题

    2. 分析

    这个题目是要求打印30行"*",每行打印的个数不同。通过这个信息,我们应该立刻反映出运用循环来完成。那么我们想想,在循环部分我们都学到了什么。

    关于循环,我首先会想到一些例题:

    2.1 例题1

    打印30个"*",每个"*"占一行。

    int i;
    for (i = 0; i < 30; i++)
    {
        printf("*\n");
    }
    

    2.2 例题2

    打印一行"*",个数为30

    int i;
    for (i = 0; i < 30; i++)
    {
        printf("*");
    }
    

    这两个题目的代码只差一个\n,结果却完全不同。掌握了这两个例题,我们自然能够完成下面这个例题了。

    2.3 例题3

    打印一个由"*"组成的30行30列的矩阵。

    int main()
    {
        int i, j;
        for (i = 0; i < 30; i++)
        {
            for (j = 0; j < 30; j++)
            {
                printf("*");
            }
            printf("*\n");
        }
    
        return 0;
    }
    

    执行结果如下:

    30*30矩阵

    我们再把例3的要求改一改,要求如下

    2.4 例题4

    打印30行“*”。第一行打印1个“*”,第二行打印3个“*”,第三行打印5个“*”,... ,第三十行打印59个“*”。

    在前面的程序中,我们用变量i控制行的循环,变量j控制列的循环。i的范围029,j的范围029。那么在例题4中,i和j有什么样的关系呢?

    找规律
    第一行 i = 0; j循环1次
    第二行 i = 1; j循环3次
    第三行 i = 2; j循环5次
    ... ... ...
    第三十行 i = 29; j循环59次

    于是得到这样一个关系:

    规律
    第n行 i = n - 1; j循环2i + 1次

    那么如何实现循环2i + 1次呢,就是让j从0到2i + 1。

    按照这个思路,可以得到下面的代码:

    #include <stdio.h>
    
    #define LINE 30
    
    int main()
    {
        int i, j;
        for (i = 0; i < LINE; i++)
        {
            for (j = 0; j < 2 * i + 1; j++)
            {
                printf("*");
            }
            printf("\n");
        }
    
        return 0;
    }
    

    执行结果如下:

    例题4

    这里要说一个问题,其实for循环有两种常见形式:

    for (i = 0; i < n; i++)
    

    for (i = 1; i <= n; i++)
    

    这种写法执行的次数相同,可以相互代替。大部分C语言程序员喜欢第一种方式,因为数组的下标访问是从0开始的,这样写更方便。目前大家可以选择自己喜欢的方法。

    好了,回到例题中来。现在我们的代码距离目标输出已经很接近了,缺少的是在每行“*”之前需要输入不同数量的空格。我们分析i和空格数量,可以得到如下关系:

    每行输出LINE - i个空格

    于是,我们得到了最终的实现程序。

    3. 答案

    #include <stdio.h>
    
    #define LINE 30
    
    int main()
    {
        int i, j;
        for (i = 0; i < LINE; i++)
        {
            for (j = 0; j < (LINE - i); j++)
            {
                printf(" ");
            }
    
            for (j = 0; j < 2 * i + 1; j++)
            {
                printf("*");
            }
            printf("\n");
        }
    
         return 0;
    }
    

    运行一下这段代码,你会看到打印结果就是最前面的那张图。

    4. 课后练习

    自己编写代码,打印出下面这张图。

    菱形

    明天会讲解这个程序,请大家先做练习。欢迎将自己的程序贴在留言中。

    我是天花板,让我们一起在软件开发中自我迭代。
    如有任何问题,欢迎与我联系。


    下一篇:21天C语言代码训练营(第二天)

    相关文章

      网友评论

      • He_ed2c:#include<stdio.h>

        #define LINE 10
        int main()
        {
        int i,j;
        for(i=0;i<LINE;i++)
        {
        for(j=0;j<(LINE-i-1);j++)
        {
        printf(" ");
        }
        for(j=0;j<2*i+1;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        for(i=0;i<LINE;i++)
        {
        for(j=0;j<i+1;j++)
        {
        printf(" ");
        }
        for(j=0;j<2*(LINE-i-1)-1;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        return 0;
        }
      • 西夜晖:#include "stdio.h"
        int main()
        {
        int i,j;
        for(i=0;i<60;i++)
        {
        if(i<30)
        {
        for(j=0;j<30-i;j++)
        {
        printf(" ");
        }
        for(j=0;j<2*i+1;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        else
        {
        for(j=0;j<i-28;j++)
        {
        printf(" ");
        }
        for(j=0;j<-2*i+117;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        }
        return 0;
        }:joy:
      • 8adafd09129a:int i,j;
        for(i=1;i<32;i++)
        {
        if(i==16)
        {
        for(j=0;j<2*16-1;j++)
        {
        printf("%c",42);
        }
        printf("\n");
        }
        else if (i<16)
        {
        for(j=i;j<16;j++)
        {
        printf("%c",32);
        }
        for(j=1;j<=2*i-1;j++)
        {
        if(j==2*i-1)
        {
        printf("%c\n",42);
        }
        else
        {
        printf("%c",42);
        }
        }
        }
        else if(i>16)
        {
        for(j=1;j<=i-16;j++)
        {
        printf("%c",32);
        }
        for(j=1;j<=2*(32-i)-1;j++)
        {
        if(j==2*(32-i)-1)
        {
        printf("%c\n",42);
        }
        else
        {
        printf("%c",42);
        }

        }
        }

        }
      • printfkxm:#include <stdio.h>
        #define LINE 30
        int main()
        {
        int i, j;
        for (i = 0; i < LINE; i++)
        {
        for (j = 0; j < (LINE - i); j++)
        {
        printf(" ");
        }
        for (j = 0; j < 2 * i + 1; j++)
        {
        printf("*");
        }
        printf("\n");
        }
        for (i = LINE; i > 0; i--)
        {
        for (j = 0; j < (LINE - i); j++)
        {
        printf(" ");
        }
        for (j = 0; j < 2 * i - 1; j++)
        {
        printf("*");
        }
        printf("\n");
        }
        return 0;
        }
      • f6ce45b087da:想问下不用自减运算怎么实现菱形效果
      • SecI302:看不懂还没教学就做题目有点太牵强了把
        天花板:@座叹赏北窗 教学已经有了,去看http://www.jianshu.com/p/1fba7db78b51
      • 864fbc7200d1:例题三中
        printf("*\n"); 是不是多打了一列,应该是 printf("\n");
        你那样打出来的是30行*30列
      • 下里巴人vs斌:i++什么意思
        天花板:@下里巴人vs斌 具体报错内容是啥?
        下里巴人vs斌: @wdq1994 为什么我把你的程序在c++条件下执行一直存在错误,不知道为什么
        6a2b092138de: @下里巴人vs斌 表示i=i+1;你该找本书去看看,看一下就知道
      • 下里巴人vs斌:/n什么意思
        6a2b092138de: @下里巴人vs斌 \n 表示换行,相当于 回车
      • 瘦瘦的周小胖:下面是我写的代码,1-3行打印正常,第四行不知道什么原因就多出来'空格'跟'*'
        #include <stdio.h>

        int main(int argc, const char * argv[]) {
        int countRow = 30;
        int tempCountRow = 1;
        char star = '*';
        char space = ' ';
        int starRowCount = 0;
        int spaceRowCount = 0;
        int col = 0;
        // printf("zzzz\n");
        while(countRow > tempCountRow) {
        // printf("zzzz\n");
        starRowCount = tempCountRow + (tempCountRow - 1);
        spaceRowCount = countRow-tempCountRow;
        col = starRowCount + spaceRowCount;
        char tmpCount[col];
        if(countRow < tempCountRow){
        break;
        }
        for(int i = 0;i < col;i++) {
        if(i<spaceRowCount){
        tmpCount[i] = space;
        }else{
        tmpCount[i] = star;
        }
        // printf("%d = |%c|\n",i,tmpCount[i]);

        }
        printf("%s\n",tmpCount);

        // printf("%c",tmpCount[i]);
        // }
        // printf("\n");
        tempCountRow++;
        }
        return 0;
        }
        瘦瘦的周小胖:@天花板 求大神解答
      • 24d705383459:大神,膜拜
      • 2e9bc010ac84:打印一个由"*"组成的30行30列的矩阵。

        int main()
        {
        int i, j;
        for (i = 0; i < 30; i++)
        {
        for (j = 0; j < 30; j++)
        {
        printf("*");
        }
        printf("*\n");
        }

        return 0;
        }

        例3出来的是30行31列的矩阵,而并非是30列的,应该将“ printf("*\n")”换成“ printf("\n")”
      • 阿债:/*
        21天C语言代码训练营(第一天)
        http://www.jianshu.com/p/d8a5712a9b08
        */

        #include <stdio.h>
        #include <string.h>
        #define TIMES 30

        int main()
        {
        char *star = "**", stars[2 * TIMES + 1] = "*";
        char *blank = "", format[] = "%00s%s%00s\n";
        int i = 1;
        for (; i <= TIMES; i++) {
        format[1] = format[7] = (TIMES - i) / 10 + 48; /*十位*/
        format[2] = format[8] = (TIMES - i) % 10 + 48; /*个位*/
        printf(format, blank, stars, blank);
        strcat(stars, star); /*每行增加两个*/
        }
        return 0;
        }
      • 阿债:很不错,常来挑战
      • 末途唯独行尔:例题3 printf("*\n"); 这个*应该不要吧 不然就输出30行乘31列了 不过别的还是很详细的 感谢楼主
      • 章鱼嫂:可以不加#define line 30 吗? @天花板
        天花板:@章鱼嫂 后面用立即数也可以
      • 笑呵呵啦:j的判断条件应该是LINE-1-i
        b1be555996e5: @笑呵呵啦 我也觉得应该是LINE-i-1
      • Elaine_Soong:最近在看数据结构,这道题是不是可以用栈的后进先出做出来呢?:sweat:没基础,就好奇问问
      • 524a45c8ec24:棒棒哒
      • 831a37ed18d7:例三执行结果好像是30行31列。
      • 老猫的孩子:很不错呢~
      • c493a01bb5e2:打卡第一天
      • 奔跑的小菜菜:#include <stdio.h>

        int main(int argc, const char * argv[]) {
        // insert code here...

        int kLineCount = 30;

        for (int i = 0; i < kLineCount; i++) {

        for (int j = 0; j < kLineCount - i; j++) {
        printf(" ");
        }

        for (int j = 0; j < 2 * i + 1; j++) {
        printf("*");
        }
        printf("\n");
        }

        for (int i = kLineCount; i > 0; i--) {

        for (int j = kLineCount; j > 0 + i; j--) {
        printf(" ");
        }

        for (int j = 2 * i - 1; j > 0; j--) {
        printf("*");
        }
        printf("\n");
        }
        return 0;
        }
      • 598a1a57cedb:对我有用
      • 6a1efc354bb5:好人啊
      • 4c9770ed48dc:c语音已经学过了,但还是有不懂的,写的很详细
      • 9cd83ad216e3:#include<stdio.h>
        #define LINE 15
        int main()
        {
        int i,j;
        for(i=0;i<=LINE;i++)
        {
        for(j=0;j<=(LINE-i);j++)
        {
        printf(" ");
        }
        for(j=0;j<2*i+1;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        for(i=LINE-1;i>=0;i--)
        {
        for(j=0;j<=(LINE-i);j++)
        {
        printf(" ");
        }
        for(j=0;j<2*i+1;j++)
        {
        printf("*");
        }
        printf("\n");
        }
        }
        9cd83ad216e3:@天花板 谢谢
        天花板:@9cd83ad216e3 非常好
      • Must_so:软件专业
      • Must_so:打卡第一天,同时求讲解如何打印杨辉三角
        天花板:@风停云瘦 明天博文中会解答,请继续关注
      • 500c21b004f8:我要每天打卡
      • danae99:打卡第一天
      • 922f7724a1b2:为什么输入line-i个空格:worried:
        奔跑的小菜菜:@JospehS 这个最简单的 你拿这个图形推算一下就知道、
        922f7724a1b2:我不知道哇,不理解:dizzy_face:
        天花板:@JospehS 那你觉得应该输出几个空格呢?
      • 独孤囚书:明天就考二级C,还有救么?
      • dee42a40674b:打卡打卡~
      • 夏有小凉:信息专业大一。C语言学习,打卡中。
      • 猫的世界:我要是能坚持下来就好了
      • Choco_xuan:经典
      • f00186702d3f:这个系列几天更新一次呢?
        天花板: @李波_lee 争取每天更新
      • 9cd83ad216e3:大一信管新生,题目很不错:smile:
      • 18ce9f6925e6:能贴java不?😓
      • 浅念boy:讲的跟不错。
      • 田野稻草人:良心好文,最近正打算学习一下c语言,就发现作者写的文章。谢谢作者。
      • 尔而知致:我基本都是自己在印象笔记上写,但是发现你这样的方法可以有很好的督促作用耶~~
      • 28a8ebc00c8e:很好。记得更新。
      • 萌小奇:打卡,想学习一下
      • 本慈:看看想学习一下
      • 9baae26549ef:现在正在学,我觉得很详细
      • 68e14e94b57b:自己参加一波
      • 0e42feb1e9a6:我爱学习
      • 提点九路节度使:挺好的,希望坚持下去
      • bdb27209c62e:在电脑上写出来了,粘到下面比较麻烦,就只是打个卡了!

      本文标题:21天C语言代码训练营(第一天)

      本文链接:https://www.haomeiwen.com/subject/gullhttx.html