“做中学”之关于我的系列调查

此篇文章包含了博主技能、C语言、JAVA、公文写作四个板块的自我调查。

博主技能小调查

如果要列举的话,博主有什么技能是比较好的呢?

如果一定要列举出一个的话,算来算去,能符合要求的也就是我的柔韧度了,现在我能够维持压腿时上身紧贴大腿的程度,最好的是侧身压的时候,其次是正面压。

现在的我能够保持以前小学初中上舞蹈课的柔韧程度,除了偶尔想刻意练习一下的请况以外,最主要的因素还是来自于自己的身体原因:如若缺乏运动,我的腿将进入长期不舒服的状态(非心理因素),躺着坐着的感受最为明显,而唯一暂时缓解办法是压腿。拉伸韧带的感觉能大大缓解我腿不舒服的状况。因为这样那样的原因,我保持了随时压腿的习惯,这也让我的柔韧度维持在了一个不错的水平上。

我认为我之所以能够保持自己的柔韧,原因在于我拥有一个“刺激源”,一个能够每天不断提醒我并促使我做出相应练习的“源”。如若没有需要压腿的需求的话,或许我的柔韧度就达不到这么高了。所以,如果要学好一门技术,关键在于找到那个能让你不断奋进,一提起来就精神百倍的事物来,可以是你的某个兴趣点,也可以是某个“压力点”,当然,后者如果加入一点自己的兴趣的话效果会更佳。

你的经验又与他人有什么共通之处么?

读了娄老师的“做中学”系列博客,其中让我印象最深刻的是《优秀的学习方法--做中学(Learning By Doing)》和《「做中学(Learning By Doing)」之乒乓球刻意训练一年总结》这两篇文章,里面提及的“做中学”,“刻意训练”等概念给我留下了很深的印象,其中“刻意训练”里面的“走出舒适区”这一项,令我想起了在网易公开课上看到的TalBen Shahar教授《哈佛大学公开课:幸福课》的第一集(也只看了第一集,不过现在又有动力继续看下去了),里面也曾提及过要走出自己的舒适区这一言论,当时自己内心就很震动,觉得,嗯?我是不是在自己的“舒适区”里待的太久了,都没有学习的动力之类的。如今再次看到这个词,发现我可以做的更好去达到老师所说的“摆脱‘舒适区’,进入‘学习区’学习,要循序渐进,不能进入‘恐慌区’”这个要求。

言归正传,与老师有共通之处的大概有以下几点:

  1. 都有一个能够激励自己的方法;
  2. 走出“舒适区”,进入“学习区”;
  3. “一万小时”:每天坚持不动摇。

C语言

学习C语言的方法

在上《程序设计基础》那门课时,老师有提供一个叫“高级语言程序设计能力训练平台”的网站,我是通过“每天”在做上面的题目前复习预习教材的内容,再在上面做题的方法学习的。当时正是因为在前半段时间,我兴致勃勃地在那上面做了大量的基础的题,看了一遍又一遍的书及笔记,给我的C语言打下了坚实的基础,再以后老师讲课的时候,对C的热情也越来越盛。比较遗憾的是我中间有一段时间没有上那个网站做题,因为前面有不错的基础后面还能较好的融会贯通,渡过了那段时期,但还是成为了我的遗憾,做一件事最重要的还是坚持。

留存代码行数

在电脑里有关C的文件一共有117个,如果按照每个最低有20行的话(大多超过这个数,有的超过了200行数),我共写了超过2340行的代码。

对C理解程度

当时我能够比较好的理解老师所提及的所有知识点,也曾尝试深入理解实践链表、文件等具体编程方法,现在我所能记得的主要是指针以前的主要内容,现在较常用数组及一维指针(基本编程:顺序、选择、循环、函数等当然也包括在内)。现在所涉及的有关C语言编程的实验都是我自己独立编出来的。当然,也因为只用了C语言前半部分的内容,编的程序比较初级。

数组指针与指针数组、函数指针与指针函数的区分

关于数组指针与指针数组、函数指针与指针函数的区分我还是大致能分清的:

数组指针与指针数组

数组指针,例如int (*p)[10];,指的是指针变量指向了一个类型为int型的数组,数组里面每个元素都是int型的,不是指针。

指针数组,例如int *p[10];,指的是数组p中每个元素都是指针,而这些指针所指向的类型是int型,相当于定义了10个指向int型的指针变量。

函数指针与指针函数

函数指针,例如int (*fx)(int a[], int n);,指的是指针指向了一个返回值为int型的函数,定义的是一个指针变量。

指针函数,例如int *fx(int a[], int n);,指的是定义了一个返回值为int型指针的函数,定义的是一个函数。

文件与流、文本文件与二进制文件

文件与流

查了一下相关教材与PPT,其中提及文件与流的有这些内容:

  • 综上所述,无论一个C语言文件的内容是什么,它一律把数据看成是由字节构成的序列,即字节流。对文件的存取也是以字节为单位的,输入/输出的数据流仅受程序控制而不受物理符号(如回车换行符)的控制。所以,C语言文件又称为流式文件。
  • ANSI C进一步对I/O的概念进行了抽象。就C程序而言,所有的I/O操作只是简单地从程序移进或移出字节的事情。因此,毫不惊奇的是,这种字节流便被称为流(stream)。
  • 文件是由许多个字节数据组成的数据流。

-- 分别引用自《 C语言程序设计(第3版)》、《C和指针》、课堂PPT

网上对于流以及文件的解释分别为(摘取):

  • 流(stream)是一个理想化的数据流,实际输入或输出映射到这个数据流。
  • 电脑外设控制,磁盘文件输入输出,只要是输入或者输出所产生的数据都是流。
  • 流是由输入输出产生的,是用于数据交换或转换的统一的标准(特指这一类的数据)。
  • 流可以想象水从水管里出来,这就是一股水流。c语言中流动的不再是水,而是有顺序的,有排列结构的数据。比如100001111100001(二进制)。
  1. 文件
  • 存储在外部介质上数据的集合。
  • C语言将文件看作是一个字符(字节)的序列,即一个一个字符(字节)的数据顺序组成。

-- 分别引用自知乎百度知道1百度知道1百度知道2百度百科

如此看来,在C语言中,流是指输入输出所产生的数据,而文件是指由字节构成的序列,也即是数据流。所以说,两者的联系是文件是一种数据流。

文本文件与二进制文件

区分

文本文件是数字中的每一位都以ASCII码值的形式存储,而二进制文件是数字作为一个整体以二进制的形式存储。

例如“12”,用文本文件的形式存储就是“00110001 00110010 0001”('1'所对应的ASCII码值位00110001,'2'所对应的ASCII码值00110010),用二进制文件形式存储就是“00000000 00001100”(12所对应的二进制形式为1100)。

编程操作

两者编程的基本程序是:

文本文件 二进制文件
打开文件 文件后缀名为.txt 文件后缀名为.bin
打开文件 文件打开方式为"r"、"w"、"a"等 文件打开方式为"rb"、"wb"、"ab"等
读写文件中的文本 按字符读写(字符/字符串)、按格式读写、按数据块读写 同左
其他操作 搜索等 同左

面向过程程序设计

什么叫面向过程程序设计?其解决问题的方法又是什么?

个人印象

对于这个问题,我知道的主要是它区别于面向对象程序设计,其基本原则是“自顶向下,逐步求精,模块化,限制使用goto语句”。

资料总结

查阅了一下相关资料,对此的解说总结如下:
面向过程程序设计是一种以过程为中心的编程思想,具体说就是分析出解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,它是通过主函数来调用一个个子函数,其方法由顺序、选择和循环这三种基本控制结构来表达。

-- 参考资料:

《全国计算机等级考试二级教程---公共基础知识(2016年版)》 高等教育出版社

百度知道:什么是面向过程的程序设计?

百度知道:面向对象的编程和面向过程的编程有什么区别?

模块与源文件

在C语言里面,什么是模块?

在C语言里面模块指的是一个一个函数,一个函数就代表一个模块。

你写过多个源文件的程序吗?

如果多个源文件的程序指的是一个程序里调用多个自己编写的.c文件的话,我并没有写过,我调用的都是C里面本身自带的头文件。

高内聚,低耦合

学过了C语言,你知道什么是“高内聚,低耦合”吗?

知道,指的是一个函数里面的联系紧密,而函数与函数之间的联系不大(除了一个函数调用了另一个函数的时候)。并不会有因为一个函数的内部变化导致连锁反应,其他函数都变了的这种情况。

这个原则如何应用到高质量程序设计中?

在一个程序中,不同的任务尽量用不同的子函数来编写,即将一个大型任务分成一小块一小块,分模块进行,这样能较好的维护调试程序。

数组的复制、查找与排序

  1. 数组的复制:元素逐个复制;
  2. 数组的查找:遍历数组中元素进行查找;
  3. 数组的排序:交换法排序、选择法排序、冒泡法排序等,主要是通过查找及交换来实现。

程序

#include <stdio.h>
#include <windows.h>
#define N 40
void Copy(int a[N], int b[N], int n);
void Search(int a[N], int n);
void Sort(int a[N],int n);
int main(void)
{
    int i,n,ret;
    int a[N],b[N];
    printf("How many elements do you want to input:");
    ret = scanf("%d",&n);
    if(n<=0 || ret!=1)
    {
        printf("Wrong! Please input a positive integer.\n");
        return 0;
    }
    printf("Please input a[N]:\n");
    for(i=0;i<n;i++)
    {
        scanf("%d",&a[i]);
    }
    Copy(a,b,n);
    Search(a,n);
    Sort(a,n);
    system("pause");
    return 0;
}
/*函数功能:数组复制*/
void Copy(int a[N], int b[N], int n)
{
    int i;
    for(i=0;i<n;i++)
    {
        b[i] = a[i];
    }
    printf("result of copy:\n");
    printf("a[N]:\t");
    for(i=0;i<n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
    printf("b[N]:\t");
    for(i=0;i<n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}
/*函数功能:数组元素查找*/
void Search(int a[N], int n)
{
    int i,flag=0;
    for(i=0;i<n;i++)
    {
        if(a[i]==5)
        {
            flag = 1;
            break;
        }
    }
    printf("\nresult of searching:\n");
    if(flag)  printf("Found 5.\n");
    else    printf("Not found 5!\n");
}
/*函数功能:数组排序(交换法排序)*/
void Sort(int a[N], int n)
{
    int i,j,k;
    for(i=0;i<n-1;i++)
    {
        k = i;
        for(j=i+1;j<n;j++)
        {
            if(a[j]>a[k]) k = j;  //由大到小排序,如果想由小到大排序的话,将“>”变为“<”
        }
        if(k!=i)
        {
            a[i] = a[i]^a[k];
            a[k] = a[k]^a[i];
            a[i] = a[i]^a[k];
        }
    }
    printf("\nresult of sorting:\n");
    for(i=0;i<n;i++)
    {
        printf("%d\t",a[i]);
    }
    printf("\n");
}

程序截图

统计代码行数

完成版

思路

用_findfirst、_findnext、_findclose函数查找硬盘E下的所有.c文件(留存代码都在E盘有备份)。

大致思路展示

注意

代码中的空白、制表符、注释不计入代码行,也即代码中的空白行、注释行不计入代码行部分。

程序

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<io.h>
#include<windows.h>
#define DOUBLE 2
#define N 260
const char *head_name="E:";             //搜索硬盘E下所有文件
void Sumc(char name[N], int *count);
int Searchdotc(char a[N]);
void Deepsearch(int *count, char name[N], char search_name[N], char search_namedd[N], long handle, struct _finddata_t fileinfo);
void Judge(int *count, char name[N], char search_name[N], char search_namedd[N], long *handle, struct _finddata_t *fileinfo);
int main(void)
{
    int count=0;
    char name[N];            //文件目录名
    char search_name[N];    //搜索目录名,不加后缀
    char search_namedd[N];    //搜索目录名,加后缀
    long handle;
    struct _finddata_t fileinfo;
    strcpy(search_name,head_name);   //赋初值给search_name
    strcpy(search_namedd,head_name);
    strcat(search_namedd,"\\*.*");       //搜索目录名,加后缀
    if((handle=_findfirst(search_namedd,&fileinfo))!=-1L)   //第一个目录下的查询
    {
        if((fileinfo.attrib==16 || fileinfo.attrib==32 || fileinfo.attrib==17)
               && (strcmp(fileinfo.name,".")!=0 && strcmp(fileinfo.name,"..")!=0))    //排除一切"."和".."文件夹所带来的影响
        {
            strcpy(name,search_name);    //将文件目录名整理后赋给name
            strcat(name,"\\");
            strcat(name,fileinfo.name);
            if(Searchdotc(fileinfo.name))  //如果是.c文件的话,统计行数
            {
                Sumc(name,&count);     //根据文件目录名name统计文件代码行数
            }
            else if((fileinfo.attrib==16 || fileinfo.attrib==17)
               && (strcmp(fileinfo.name,".")!=0 && strcmp(fileinfo.name,"..")!=0))   //如果是文件夹则深入到它的子目录继续调查
            {
                _findclose(handle);              //结束这个目录的句柄
                Deepsearch(&count,name,search_name,search_namedd,handle,fileinfo);
            }
            //if-else区域结束
        }
        while(_findnext(handle,&fileinfo)==0)//继续搜索这个目录的下一个文件名
        {
            if((fileinfo.attrib==16 || fileinfo.attrib==32 || fileinfo.attrib==17)
               && (strcmp(fileinfo.name,".")!=0 && strcmp(fileinfo.name,"..")!=0)) //简化运算,搜索范围在文件属性是文件夹+正常、存档+正常、文件夹+正常+只读
            {
                strcpy(name,search_name);    //将文件目录名整理后赋给name
                strcat(name,"\\");
                strcat(name,fileinfo.name);
                Judge(&count,name,search_name,search_namedd,&handle,&fileinfo);
            }
        }
        _findclose(handle);            //第一个目录查询结束
    }
    printf("The total lines is %d\n",count);
    system("pause");
    return 0;
}
/*统计一个.c文件的代码行数(去掉注释、空白行的影响)*/
void Sumc(char name[N], int *count)
{
    int k=0,flag=0,begin1=0,begin2=0,blank=0,c=0;    //c判断是否为行头
    char ch[DOUBLE]={'0','0'};  //初始化
    FILE *fp;
    //printf("%s\n",name);   可用作查找展示
    if((fp=fopen(name,"r"))==NULL)
        {
            printf("Failure to open %s!\n",name);
            exit(0);
        }
    while((ch[k]=fgetc(fp))!=EOF)
    {
        if(ch[k]==' ')        //**防空格,制表符也防了,因为在文本文件中,制表符相当于4个空格(已试验)**
        {
            ch[k]='\n';      //忽略空格和制表符,将之改为'\n',使得下面判断/*是否在行头提供便利
            blank = 1;      //但为了防止与后面的防空白行判断相冲,加一个改动标志,并在后面每个分支里加一个消除改动标志的语句,这样改动标志的有效期就变为了一个循环时间
        }
        else if(ch[k]=='/' && c==0) //判断/是否在行头!!!编程需注意有多种情况
        {
            begin1 = 1;      //判断/(/*)行头标志
            blank = 0;
        }
        else if(ch[k]=='*' && ch[!k]=='/' && begin1==1)
        {
            flag = 1;        //防/*注释标志
            begin1 = 0;      //取消/(/*)行头标志
            blank = 0;
        }
        else if(ch[k]=='/' && ch[!k]=='/' && begin1==1)
        {
            begin2 = 1;      //判断//行头标志
            begin1 = 0;      //取消/(/*)行头标志
            blank = 0;
        }
        else if(ch[k]=='/' && ch[!k]=='*' && flag==1)
        {
            flag = 2;        // /**/型注释结束,但不取消防/*注释标志flag
            blank = 0;
        }
        else if(ch[k]=='\n' && ch[!k]!='\n' && blank==0 && flag==0 && begin2==0)  //防空白行
        {
            *count = *count+1;
            flag = 0;
            //blank = 0;
        }
        else blank = 0;
        if(flag==2 && ch[k]=='\n') flag = 0;   //取消防/(/*)注释标志,下一行可开始继续计数
        if(begin2==1 && ch[k]=='\n') begin2 = 0;//取消防//注释标志,下一行可开始继续计数
        if(ch[k]=='\n' && blank==0) c = 0;//c等于0表明下一个字符在行头
        else            c++;             //c不等于0表明下一个字符不在行头
        k = !k;
    }
    fclose(fp);
}
/*搜索倒数两个是否为“.c”,是则返回1,不是则返回0*/
int Searchdotc(char a[N])
{
    int n;
    n = strlen(a);
    if(n!=1 && a[n-2]=='.' && a[n-1]=='c') return 1;
    return 0;
}
/*子目录查询*/
void Deepsearch(int *count, char name[N], char search_name[N], char search_namedd[N], long handle, struct _finddata_t fileinfo)
{
    long handle1;
    struct _finddata_t fileinfo1;
    char name1[N],search_name1[N],search_namedd1[N];
    handle1 = handle;
    fileinfo1 = fileinfo;
    strcpy(name1,name);
    strcpy(search_name1,search_name);
    strcpy(search_namedd1,search_namedd);

    strcpy(search_name1,name1);   //赋初值给search_name
    strcpy(search_namedd1,name1);
    strcat(search_namedd1,"\\*.*");       //搜索目录名,加后缀
    if((handle1=_findfirst(search_namedd1,&fileinfo1))!=-1L)   //这个子目录下的查询
    {
        if(strcmp(fileinfo1.name,".")==0 || strcmp(fileinfo1.name,"..")==0) ;  //空目录下需排除"."和".."文件夹,否则会无限循环,但为什么?"."和".."又是什么?
        else if(fileinfo1.attrib==16 || fileinfo1.attrib==32 || fileinfo1.attrib==17)
        {
            strcpy(name1,search_name1);    //将文件目录名整理后赋给name
            strcat(name1,"\\");
            strcat(name1,(fileinfo1).name);
            if(Searchdotc(fileinfo1.name))  //如果是.c文件的话,统计行数
            {
                Sumc(name1,count);     //根据文件目录名name统计文件代码行数
            }
            else if((fileinfo1.attrib==16 || fileinfo1.attrib==17)
               && (strcmp(fileinfo1.name,".")!=0 && strcmp(fileinfo1.name,"..")!=0))       //如果是文件夹则深入到它的子目录继续调查
            {
                _findclose(handle1);              //结束这个目录的句柄
                Deepsearch(count,name1,search_name1,search_namedd1,handle1,fileinfo1);  //除count外其他变量不混用
            }
            //if-else区域结束
        }
        while(_findnext(handle1,&fileinfo1)==0)//继续搜索这个目录的下一个文件名
        {
            if((fileinfo1.attrib==16 || fileinfo1.attrib==32 || fileinfo1.attrib==17)
               && (strcmp(fileinfo1.name,".")!=0 && strcmp(fileinfo1.name,"..")!=0))
            {
                strcpy(name1,search_name1);    //将文件目录名整理后赋给name
                strcat(name1,"\\");
                strcat(name1,(fileinfo1).name);
                Judge(count,name1,search_name1,search_namedd1,&handle1,&fileinfo1);
            }
        }
        _findclose(handle1);            //这个子目录查询结束
    }
}
/*判断这个文件是.c还是文件夹*/
void Judge(int *count, char name[N], char search_name[N], char search_namedd[N], long *handle, struct _finddata_t *fileinfo)
{
    strcpy(name,search_name);    //将文件目录名整理后赋给name
    strcat(name,"\\");
    strcat(name,(*fileinfo).name);
    if(Searchdotc((*fileinfo).name))  //如果是.c文件的话,统计行数
    {
        Sumc(name,count);     //根据文件目录名name统计文件代码行数
    }
    else if(((*fileinfo).attrib==16 || (*fileinfo).attrib==17)
               && (strcmp((*fileinfo).name,".")!=0 && strcmp((*fileinfo).name,"..")!=0)) //如果是文件夹则深入到它的子目录继续调查
    {
        Deepsearch(count,name,search_name,search_namedd,*handle,*fileinfo);
    }
}

截图

(因为硬盘中有比较多的.c文件是以全注释的形式存在(程序都在注释里,这些文件的原存放地址在练习网站上,以注释的形式保存在E盘里),所以去掉注释的话代码行数较少。)

体会

为了写这个程序,我有以下收获:

  1. 初步掌握如何使用_findfirst、_findnext、_findclose函数;
  2. 回顾基本文件操作编程方法;
  3. 尝试遍历硬盘文件;
  4. 了解文本文件;
  5. 尝试编写如何让空白行、注释行不计入代码行数;
  6. 借助网络学习掌握新的知识。

不足

编写的程序还是有点繁琐,有待改进。

参考资料

断点

你知道什么叫断点吗?给出自己调试程序的例子。

断点的意思是在某行代码处设置断点的话,调试程序时会直接从头运行到你所设置的地方停止,方便调试之后的程序。

例子

几乎每一个较长的程序我都单步调试过。

1.设置断点

鼠标左键点击红点所在位置,出现红点。

2. 调试程序

点击Run to cursor键 ,黄色三角形光标将出现在红点处。

Tip1:初次运行这个软件的话,需要先点击,选择下拉列表里的Watches,显示变量变化过程。

Tip2:注意如果想实现这一步的话,需一开始将文件创建在没有中文名的目录下,否则不能实现,如果想创建在有中文名的目录下又想单步调试的话,可以跳过这一条直接执行下一个步骤。

3. 继续调试

点击 程序运行到下一行,点击 进入到子函数里面。

JAVA

学习目标

具体目标

每天能够坚持学习又或是编写一点JAVA。

如何通过刻意训练提高程序设计能力和培养计算思维

  1. 刻意培养自己的学习氛围,通过塑造良好的学习氛围推动自己走出“舒适区”,进入“学习区”;
  2. 每天练习一小部分;
  3. 与他人进行有效的沟通,促使自己不断前进。

如何通过“做中学”实现你的目标

  1. 实践与理论相结合,既不能一味编程,也不能只读书本;
  2. 及时反馈问题;
  3. 进行大量基础练习。

公文写作

我的写作能力

我的写作能力如果是认真完成一项公文的话,还是可以的,不过还需要磨练。

所以,若要提高我的公文写作能力,当务之急是多积累见识,涉猎面广了,兴趣自然也就上来了,不至于面对一项工作而茫然不知,感到“前途漫漫而远之,吾将上下而求索”。

posted @ 2016-12-16 21:10  protectmonarch  阅读(394)  评论(5编辑  收藏  举报