学习基础和C语言基础调查
技能学习心得
看了15级学长学姐丰富的技能之后,我感到很惭愧。我的课外技能可以说是很糟糕。唱歌的话,小时候还可以用假声唱一下,变声之后就是高音上不去,低音下不来。体育更是差劲,打乒乓球被某云霄同学零封。打游戏吧,打了6年的英雄联盟,巅峰时期段位青铜一。
如果将比大多数人好定义为超过90%以上的人,我想除了高考的排名外,没有什么可以达到这一标准了。当然,来到电科院的同学肯定也都达到甚至远远超过这个标准了。
如果根据邹欣老师的建议,将标准定到60%的话,我想我在C语言程序的编写方面,还是可以满足这一标准的(仅限于与本校的同级学生比较)。
学习C语言过程中,兴趣是驱使我学习的最大动力。正如孔子所云:知之者不如好之者,好之者不如乐之者。通过阅读娄老师的《优秀的教学方法---做教练与做中学》等文章,我发现这与我学习C语言时的状态很相似。大量的上机训练再加上强迫自己使用新学的知识点编程,最终使我凭借这项技能取得了不错的成绩。
C语言基础调查
1. 你是怎么学习C语言的?(作业,实验,教材,其他),与你的高超技能相比,C语言的学习有什么经验和教训?
关于C语言的学习,首先是信安协会的竺文君学姐和林晶学姐传授给我一些基础知识,然后我自己通过观看腾讯课堂的免费课程《小白学编程 C语言 编程》进一步的了解了C语言的基础知识,最后是跟徐小青老师学习了《程序设计基础》这门课,并通过大量的上机编程练习,最终完成了C语言的学习。总结起来就是上课加作业和实验的练习。教材的话,说实话只是偶尔的翻阅一下,重要的知识点(如:“吃回车问题”)其实主要还是在上机编程的时候发现并解决的。
2. 目前为止估算自己写过多少行C代码?理解的情况如何?量变引起质变,如何平衡质和量?
经过自己编写的程序的计算,我已经编写了9104行代码,但这其中基础的程序占了绝大多数,所以说对于C语言的基础知识我还是掌握的比较扎实的,但是对于一些复杂的算法,我还没有掌握。
量变是质变的必要准备,质变是量变的必然结果,质量互变规律是唯物辩证法的基本规律之一。但在C语言的学习中我体会到,如果仅仅将眼光和精力放在简单的问题上,提高的仅仅是对于简单问题的解决速度,并没有获得复杂问题的解决思路。所以说要在熟悉编程语言的前提下,不断学习、探索复杂的算法,这样才会有质的飞跃。
3. 学过了C语言,你分的清数组指针,指针数组;函数指针,指针函数这些概念吗?
概念可以分清,但是到应用层面,目前只用过指针数组和指针函数,强行使用过函数指针。
数组指针:指向数组的指针。
指针数组:由指针组成的数组,在索引排序中使用过。
函数指针:指向函数的指针。
指针函数:返回值是指针的函数。
4. 学过了C语言,你明白文件和流的区别和联系吗?如何区分文本文件和二进制文件?如何编程操作这两种文件?
在学习过程中听老师提过输入输出流的概念,但是没有深入的讲解,我也没有深入的探究。经过一番查阅,我大致了解了一下。
流:数据流将整个文件内的数据看作一串连续的字符(字节),而没有记录的限制。数据流借助文件指针的移动来访问数据,文件指针目前所指的位置即是要处理的数据,经过访问后文件指针会自动向后移动。每个数据文件后面都有一个文件结束符号(EOF),用来告知该数据文件到此结束,若文件指针指到EOF便表示数据已访问完毕。
文件:“文件”是指存放在外部存储介质(可以是磁盘、光盘、磁带等)上的数据集合。操作系统对外部介质上的数据是以文件形式进行管理的。当打开一个文件或者创建一个新文件时,一个数据流和一个外部文件(可能是一个物理设备)相关联。 C语言支持的是流式文件,即前面提到的数据流,它把文件看作一个字节序列,以字节为单位进行访问,没有记录界限,即数据的输入和输出的开始和结束仅受程序控制,而不受物理符号(如回车换行符)控制。
文本文件:从物理层面讲,所有的文件都是二进制文件,因为它们都是以二进制的形式在计算机中进行存储的。如果从逻辑层面讲,文本文件是基于字符编码的文件,以ASCLL码或Unicode等编码方式将字符以文本的形式保存在文件中。字符文件没有文件头,第一个字节就是要显示的内容。如:保存10000这个数字,使用文本的方式保存,需要占5个字节。在编程过程中,使用fopen()函数打开文件,参数可以写rt+,wt+,at+。 使用fprintf()函数将数据以文本的形式写入文件。
二进制文件:二进制文件是基于值编码的文件,你可以根据具体应用,指定某个值是什么意思。二进制文件有文件头,用以表明文件的大小、类型等信息,程序在处理二进制文件时一般会先分析文件头,判断文件是否合法,也就是说,文件头后面的数据才是程序真正要处理的。打开指定的二进制文件需要使用与其对应的程序,否则无法正常读取信息。如:保存10000这个数,如果使用int类型保存的话,需4个字节。使用fopen()函数打开文件,参数可以写rb+,wb+,ab+。使用fwrite()函数将数据以二进制的形式写入文件。
5. 学过了C语言,你知道什么叫面向过程程序设计吗?它解决问题的方法是什么?
“面向过程程序设计”是一种以过程为中心思想的编程方式。它通过分析解决问题所需要的步骤,然后用函数把这些步骤一步一步实现,使用的时候依次调用来解决问题。
6. 在C语言里面,什么是模块?你写过多个源文件的程序吗?
在C语言中,模块一般指能独立完成某种任务的一段子程序,它可以与main()函数同时写在一个.c文件中;也可以将函数的实现代码写在其他的.c文件中,在同名的.h文件中写函数的声明,然后在main.c中include这个.h头文件。关于.h文件与.c文件有何区别,推荐阅读这篇文章《.h和.c文件的区别到底是什么(精确讲解)》。
在大一下学期学C语言的时候还没有写过多个源文件的程序,一般都是在main.c文件中写出自己的子程序。在这次编写统计C语言代码行数的程序中,我刻意的使用了一下这个方式,感觉很不错,这使我的main.c中的代码更加简洁、实现了模块化程序设计。
7. 学过了C语言,你知道什么是“高内聚,低耦合”吗?这个原则如何应用到高质量程序设计中?
耦合性:也称块间联系。指软件系统结构中各模块间相互联系紧密程度的一种度量。模块之间联系越紧密,其耦合性就越强,模块的独立性则越差。模块间耦合高低取决于模块间接口的复杂性、调用的方式及传递的信息。
内聚性:又称块内联系。指模块的功能强度的度量,即一个模块内部各个元素彼此结合的紧密程度的度量。若一个模块内各元素(语名之间、程序段之间)联系的越紧密,则它的内聚性就越高。
所谓高内聚是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。
对于低耦合,粗浅的理解是:一个完整的系统,模块与模块之间,尽可能的使其独立存在。也就是说,让每个模块,尽可能的独立完成某个特定的子功能。模块与模块之间的接口,尽量的少而简单。如果某两个模块间的关系比较复杂的话,最好首先考虑进一步的模块划分。这样有利于修改和组合。
参考资料:高内聚低耦合。
8. 学过了C语言,你如何把数组A的内容复制到数组B中?如何查找整数数组A中有没有数字5?如何对整数数组A进行排序(从小到大,从大到小)?写出相应的程序。
将数组A内容复制到数组B中
#include <stdio.h>
#define N 5
int main()
{
int a[N]={1,2,3,4,5},b[N]={6,7,8,9,10},i;
for(i=0;i<N;i++)
{
b[i]=a[i];
printf("%d ",b[i]);
}
return 0;
}
查找整数数组A中有没有数字5
#include <stdio.h>
#include <stdlib.h>
int main()
{
int n,i,flag=0;
int *p;
printf("请输入数据个数:");
scanf("%d",&n);
p=(int*)calloc(n,sizeof(int));
printf("请输入数据:");
for(i=0;i<n;i++)
{
scanf("%d",p+i);
}
for(i=0;i<n;i++)
{
if(p[i]==5)
{
flag=1;
break;
}
}
if(flag)
printf("该组数据中有5");
else
printf("该组数据中没有5");
return 0;
}
如何对整数数组A进行排序(从小到大,从大到小)
//正好借此机会回忆一下函数指针。
#include <stdio.h>
int ascending(int a,int b)
{
return a<b;
}
int descending(int a,int b)
{
return a>b;
}
void sort(int *a,int n,int (*p)(int a,int b))
{
int i,j,k,temp;
for(i=0;i<n-1;i++)
{
k=i;
for(j=i;j<n;j++)
{
if(p(a[j],a[k]))
k=j;
}
if(i!=k)
{
temp=a[i];
a[i]=a[k];
a[k]=temp;
}
}
}
int main()
{
int i,a[10]={5,4,8,9,6,1,2,3,7,0};
sort(a,10,ascending);
printf("升序为:");
for(i=0;i<10;i++)
{
printf("%d ",a[i]);
}
printf("
");
sort(a,10,descending);
printf("降序为:");
for(i=0;i<10;i++)
{
printf("%d ",a[i]);
}
return 0;
}
9. 写一个程序,统计自己C语言共写了多少行代码。
其实我在大一学C语言的时候就想写一个这样的程序了,但是由于其中用到了很多文件操作的知识,所以我就把这个想法搁置了。我认为这个程序的难点主要在于遍历文件夹中所有的.c文件,通过查阅网上的资料,我发现了之前从来没有使用过的windows库,其中大量的API函数使这项工作有了眉目,在此感谢微软爸爸。如果微软能公布几个源代码让大家学习就更好了,但毕竟涉及到了知识产权和商业机密的问题,肯定是不可能的了。
以下是我尝试编写的代码(程序功能:查找一个目录(包括子目录)下的所有.c文件,并统计行数(排除空行)):
#include <windows.h>
#include <stdio.h>
#include <string.h>
#define LEN 1024
int statistics(char *a);
int DirectoryList(char *Path);
int main()
{
int row;
char a[LEN];
printf("请输入您想要查找的目录:");
gets(a);
row=DirectoryList(a);
printf("您已经写了:%d行C语言代码
",row);
return 0;
}
int DirectoryList(char *Path)
{
WIN32_FIND_DATA FindData,FindC;
HANDLE hError,hC;
int row = 0;
char FilePathName[LEN];
char FullPathName[LEN];
strcpy(FilePathName, Path);
strcat(FilePathName, "\*.*");
hError = FindFirstFile(FilePathName, &FindData);
if (hError == INVALID_HANDLE_VALUE)
{
printf("搜索失败!");
return 0;
}
if((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(FindData.cFileName, ".")!=0) && (strcmp(FindData.cFileName, "..")!=0))
{
wsprintf(FullPathName, "%s\%s", Path,FindData.cFileName);
row=row+DirectoryList(FullPathName);// 深度优先递归遍历目录中所有的文件夹
}
while(FindNextFile(hError,&FindData))
{
if((FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) && (strcmp(FindData.cFileName, ".")!=0) && (strcmp(FindData.cFileName, "..")!=0))
{
wsprintf(FullPathName, "%s\%s", Path,FindData.cFileName);
row=row+DirectoryList(FullPathName);// 深度优先递归遍历目录中所有的文件夹
}
}
FindClose(hError);
strcpy(FilePathName, Path);
strcat(FilePathName, "\*.c");//遍历目录中所有的.c文件
hC = FindFirstFile(FilePathName, &FindC);
if (hC == INVALID_HANDLE_VALUE)
return row;
else
{
wsprintf(FullPathName, "%s\%s", Path,FindC.cFileName);
row=row+statistics(FullPathName);
}
while(FindNextFile(hC,&FindC))
{
wsprintf(FullPathName, "%s\%s", Path,FindData.cFileName);
row=row+statistics(FullPathName);
}
FindClose(hC);
return row;
}
int statistics(char *a) //打开文件计算行数
{
int row=0;
FILE *fp;
char b,c;
fp=fopen(a,"r");
if(fp==NULL)
{
printf("File open failed
");
return 0;
}
else
{
while(1)
{
b=fgetc(fp);
c=fgetc(fp);
(*fp)._cnt++;
(*fp)._ptr--;
if(b==EOF || c==EOF)
break;
if(b=='
' && c!='
')
{
row++;
}
}
fclose(fp);
return ++row;
}
}
程序运行效果如下:
写完这个程序之后我发现,其实最困难的不是编写算法,而是学会勇敢的面对未知的事物。这个程序中用到了课堂中没有涉及到的函数和数据类型,但是有了老师传授的基础,理解这些东西并没有想象中的那么难。
参考资料:
FindFirstFile()函数详解(百度百科中说该函数到一个文件夹(包括子文件夹)去搜索指定文件,但在实际应用中并没有到子文件夹中搜索指定文件,有待商榷。如果文件夹的名字是xx.c,它也会认为这个文件夹是一个.c文件,接着使用fopen()函数时会出现错误。)
handle句柄(看完之后概念还是有点模糊)
10. 你知道什么是断点吗?给出自己调试程序的例子。
在程序中设置断点,可以在调试程序的过程中使程序直接运行到断点处。
调试程序的例子实在是太多了,在写上面的程序的时候就使用了debug,在调试该程序的时候还出现了一个有意思的现象,将鼠标移动到Watches窗口中的FilePathName或FullPathName变量上的时候,电脑就会卡死,codeblocks未响应。
章节提问
1、Java为什么要采用字节码这种文件,使用解释器执行程序的还会使程序的运行速度降低,直接将源代码编译成机器码不可以吗?
2、Java中可否使用指针,直接对内存地址进行操作?
3、Java中的break可否跳出多层循环,(如:在三重循环的最外层循环前写下标号,在内部写break 这个标号)?
4、创建一个新的对象的时候,对象中的变量定义与构造函数之间的执行顺序是什么?
5、子类从父类得到了什么?成员函数?成员变量?
6、要不要把数据和表现进行分离?
7、如何编写java中的自定义异常类?
8、如何使用字符分析器?
9、 MVC模式各个层的具体作用?
10、如果没有关闭输入输出流会发生什么?
11、 java操作数据库的方式有哪些?
12、线程是如何创建的?
13、 java网络编程和java web有什么区别?
14、可否使用Java绘制3D图形?
15、 java集合框架中的泛型有什么优点?
学习目标
我想通过学习Java程序设计,来获得面向对象程序设计的思想,并掌握新的技术。通过大量的训练,最终能自己独立编写一款成型的软件,包括图形界面的设计,数据库的搭建,设计算法,并且可以跨平台运行。