首页 理论教育 学习材料对编程质量提高的影响实验材料

学习材料对编程质量提高的影响实验材料

时间:2022-10-23 理论教育 版权反馈
【摘要】:附录3学习材料对编程质量提高的影响实验材料解题思路学习材料下面提及的语法规则和编程思想是解决C语言程序编程题“用筛选法求100以内的素数”所需要用到的,请你花15分钟的时间仔细学习。给定的条件称为循环条件,反复执行的程序段称为循环体。表达式3通常可用来修改循环变量的值,一般是赋值语句。注意:单精度实数的有效位数一般为7位,双精度为16位。

附录3 学习材料对编程质量提高的影响实验材料

解题思路学习材料

下面提及的语法规则和编程思想是解决C语言程序编程题“用筛选法求100以内的素数”所需要用到的,请你花15分钟的时间仔细学习。

用筛选法求100以内的素数。(素数就是质数。它除了能表示为它自己和1的乘积以外,不能表示为任何其他两个整数的乘积。例如,15=3*5,所以15不是素数;又如,12=6*2=4*3,所以12也不是素数。另一方面,13除了等于13*1以外,不能表示为其他任何两个整数的乘积,所以13是一个素数。)

一、语法规则

1.输入输出函数:printf,scanf

printf一般格式:printf(格式控制,输出表列)

scanf一般格式:scanf("<格式化字符串>",<地址表>);

2.循环结构是程序中一种很重要的结构。其特点是,在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。C语言提供了多种循环语句,可以组成各种不同形式的循环结构。

(1)while语句:

while语句的一般形式为:while(表达式)语句;其中表达式是循环条件,语句为循环体。

while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句。

(2)for语句

for语句是C语言所提供的功能更强,使用更广泛的一种循环语句。其一般形式为:

for(表达式1;表达式2;表达3)

语句;

表达式1 通常用来给循环变量赋初值,一般是赋值表达式。也允许在for语句外给循环变量赋初值,此时可以省略该表达式。

表达式2 通常是循环条件,一般为关系表达式或逻辑表达式。

表达式3 通常可用来修改循环变量的值,一般是赋值语句。

这三个表达式都可以是逗号表达式,即每个表达式都可由多个表达式组成。三个表达式都是任选项,都可以省略。

一般形式中的“语句”即为循环体语句。

3.指针是一种数据类型,与其他的数据类型不同的是指针是一种“用来存放地址值的”变量。

指针的定义:类型说明符*指针变量名

4.编译预处理别于其他高级程序设计语言的特征之一,它属于C语言编译系统的一部分。C程序中使用的编译预处理命令均以#开头,它在C编译系统对源程序进行编译之前,先对程序中这些命令进行“预处理”。

编译预处理:

宏定义的一般格式:#define标识符字符串

文件包含处理格式:格式1:#include<filename>

         格式2:#include"filename"

5.数组的定义:类型说明符数组名[常量表达式]

6.函数定义:类型标识符函数名(形式参数表列)

img84

二、编程思想

解决此编程题的中心思想有两个,一是循环,二是标志法。筛选法就是利用循环和判断语句去掉那些不符合题意的条件,以得到最终结果。

该题需要用到的原理是:如果一个数是素数,那么它只能被1和它本身整除。按照这个定义,判断一个数i是否为素数,就可以用一个数j对它进行测试,如果i%j==0,而j又不是1或它本身,那么这个数就不是素数;如果i%j!=0,那么j一直增加下去,看j能不能有一个值可以整除i,如果j是一个素数,那么j可以一直增加到i为止,这样就可以看出它是不是素数了。

在程序实现上,我们首先应该确定需要筛选的集合。该集合就是{0,1,2…100},可以用数组来表示a[101]。其次就是确定筛选的条件,在这里筛选的条件就是循环的控制条件。该题需要一个2重循环,外层循环用来控制对整个数组的遍历,内层循环用来控制测试数的遍历。根据原理,我们能很快确定外层循环控制条件for(i=2;i<N;i++)和内层循环条件for(j=1;j<N;j++)。运用数学原理对程序进行的一种优化,内层循环条件可以缩小到for(i=2;i<sqrt(N);i++)。

程序实现的最后一点就是循环体了(对应于筛选法的筛选操作)。在程序中如何体现筛选这个操作呢?方法就是根据某种条件(判断语句),把满足条件(判断条件)的数组元素打上标识。如何打上标识呢?很简单,就是令满足条件的元素为0或者1!输出结果的时候,不为0(或者1)的元素就是我们所要找的素数。

语法学习材料

下面提语法是解决C语言程序编程题“用筛选法求100以内的素数”所需要用到的,请你花15分钟的时间仔细学习。

一、输入输出函数:printf,scanf

(一)printf一般格式

printf(格式控制,输出表列)

例如:printf("i=%d,ch=%c\n",i,ch);

说明:

A“格式控制”是用双撇号括起来的字符串,也称“转换控制字符串”,它包括两种信息:

①格式说明:由“%”和格式字符组成,它的作用是将输出的数据转换为指定的格式输出。

②普通字符,即需要原样输出的字符。

B“输出表列”是需要输出的一些数据,可以是表达式

C printf函数的一般形式可以表示为:

printf(参数1,参数2……参数n)

功能是将参数2~参数n按参数1给定的格式输出

格式字符(9种)

(1)d(或i)格式符。用来输出十进制整数,有以下几种用法:

①%d,按整型数据的实际长度输出。

②%md,m为指定的输出字段的宽度。如果数据的位数小于m,则左端补以空格,若大于m,则按实际位数输出。

③%ld(%mld也可),输出长整型数据。

例如:long a=123456;

   printf("%ld",a);

(2)o格式符,以八进制数形式输出整数。格式:%o,%mo,% lo,%mlo都可。

(3)x(或X)格式符,以十六进制数形式输出整数。格式:% x,%mx,%lx,%mlx都可。

(4)u格式符,用来输出unsigned型数据,即无符号数,以十进制数形式输出。格式:%u,%mu,%lu都可。

(5)c格式符,用来输出一个字符。格式:%c,%mc都可。

(6)s格式符,用来输出一个字符串。格式:%s,%ms,%-ms,%m.ns,%-m.ns都可。

(7)f格式符,用来输出实数(包括单、双精度),以小数形式输出。格式:%f,%m.nf,%-m.nf都可。注意:单精度实数的有效位数一般为7位,双精度为16位。

(8)e(或E)格式符,以指数形式输出实数。格式:%e,%m.ne,%-m.ne都可。

(9)g(或G)格式符,用来输出实数,它根据数值的大小,自动选f格式或e格式(选择输出时占宽度较小的一种)。

补充说明:除了X、E、G(用大写字母表示)外,其他格式字符必须用小写字母;“格式控制”字符串内可以包含转义字符;如果想输出字符“%”,则应该在“格式控制”字符串中用连续两个%表示,如:printf("%f%%",1.0/3);格式字符表参见下表

img85

(二)函数名:scanf

功能:执行格式化输入

用法:int scanf(char*format[,argument,...]);scanf()函数是通用终端格式化输入函数,它从标准输入设备(键盘)读取输入的信息。可以读入任何固有类型的数据并自动把数值变换成适当的机内格式。其调用格式为:scanf("<格式化字符串>",<地址表>);scanf()函数返回成功赋值的数据项数,出错时则返回EOF。

其控制串由三类字符构成,即格式化说明符;空白符;非空白符;

1.格式化说明符

格式字符说明

%a     读入一个浮点值(仅C99有效)

%A     同上

%c     读入一个字符

%d     读入十进制整数

%i     读入十进制,八进制,十六进制整数

%o     读入八进制整数

%x     读入十六进制整数

%X     同上

%c     读入一个字符

%s     读入一个字符串

%f     读入一个浮点数

%F     同上

%e     同上

%E     同上

%g     同上

%G     同上

%p     读入一个指针

%u     读入一个无符号十进制整数

%n     至此已读入值的等价字符数

%[]    扫描字符集合

%%     读%符号

2.空白字符

空白字符会使scanf()函数在读操作中略去输入中的一个或多个空白字符,空白符可以是space,tab,newline等等,直到第一个非空白符出现为止。

3.非空白字符

一个非空白字符会使scanf()函数在读入时剔除掉与这个非空白字符相同的字符。

二、循环

循环结构是程序中一种很重要的结构。其特点是,在给定条件成立时,反复执行某程序段,直到条件不成立为止。给定的条件称为循环条件,反复执行的程序段称为循环体。C语言提供了多种循环语句,可以组成各种不同形式的循环结构。

while语句:

while语句的一般形式为:while(表达式)语句;其中表达式是循环条件,语句为循环体。while语句的语义是:计算表达式的值,当值为真(非0)时,执行循环体语句。

统计从键盘输入一行字符的个数。

img86

本例程序中的循环条件为getchar()!='\n',其意义是,只要从键盘输入的字符不是回车就继续循环。循环体n++完成对输入字符个数计数。从而程序实现了对输入一行字符的字符个数计数。

使用while语句应注意以下几点:1.while语句中的表达式一般是关系表达或逻辑表达式,只要表达式的值为真(非0)即可继续循环。2.循环体如包括有一个以上的语句,则必须用{}括起来,组成复合语句。3.应注意循环条件的选择以避免死循环。

for语句

for语句是C语言所提供的功能更强,使用更广泛的一种循环语句。其一般形式为:

for(表达式1;表达式2;表达3)

语句;

表达式1 通常用来给循环变量赋初值,一般是赋值表达式。也允许在for语句外给循环变量赋初值,此时可以省略该表达式。

表达式2 通常是循环条件,一般为关系表达式或逻辑表达式。表达式3 通常可用来修改循环变量的值,一般是赋值语句。这三个表达式都可以是逗号表达式,即每个表达式都可由多个表达式组成。三个表达式都是任选项,都可以省略。

一般形式中的“语句”即为循环体语句。for语句的语义是:

1.首先计算表达式1的值。

2.再计算表达式2的值,若值为真(非0)则执行循环体一次,否则跳出循环。

3.然后再计算表达式3的值,转回第2步重复执行。在整个for循环过程中,表达式1只计算一次,表达式2和表达式,3则可能计算多次。循环体可能多次执行,也可能一次都不执行。

img87

本例for语句中的表达式3为n++,实际上也是一种赋值语句,相当于n=n+1,以改变循环变量的值。

三、指针

1.指针 指针是一种数据类型,与其他的数据类型不同的是指针是一种“用来存放地址值的”变量。举一个简单的例子:

如果定义了一个整型变量,根据整型变量的特点,它可以存放的数是整数。

如:int a;a=100;这样就把整型常量赋给了变量a。但是如果写成这样:a=123.33;就会出问题,最后输出变量a的值结果是123。现在说到指针,其实地址值也是一个整型数,如某某变量的地址值为36542,说明这个变量被分配在内存地址值为36542的地方。能不能这样进行推理,既然地址值也是整型数,整型变量正好可以用来存放整型数,那不是一个整型变量可以用来存放地址的值吗。程序写成下面这样:

int a,b;

  a=&b;

很明显,这样写是错误的。原因在于不能简单地把地址理解为整型数。应有这样的对应关系:地址值<--->指针;整型数<--->int型变量。

所以有这样的说法:“指针就是地址”(指针就是存放地址值的一种数据类型)

下面是一段正确的程序:

int a,*p;

  p=&a;/*把变量a的地址值赋给指针p*/

2.指针相互加减。但是一定要作有意义的运算。当二个指针指向同一个数组的时候,它们相加减是有意义的。如果二个指针分别指向二个不同的数组,那么指针之间的相加减就没有什么意义。指向同一个数组时,其相加减的结果为二个指针之间的元素数目。

在c中数组的指针就是数组的起始地址(也就第一个元素的地址),而且标准文档规定数组名代表数组的地址(这是地址数值层面的数组表示)。例如:

int a[10];int*p;

p=&a[0]//和p=a是等价的:

因为a是数组名,所以他是该数组的地址,同时因为第一个元素为a[0],那么&a[0]也代表了该数组的地址。但是我们是不是就说一个数组名和该数组的第一个元素的&运算是一回事呢?在一维的时候当时是的,但是在高维的时候,我们要考虑到维数给数组带来的影响。

a[10]是一个数组,a是数组名,它是一个包含10个int类型的数组类型,不是一般的指针变量噢!(虽然标准文档规定在c++中从int[]到int*直接转换是可以的,在使用的时候似乎在函数的参数为指针的时候,我们将该数组名赋值没有任何异样),a代表数组的首地址,在数字层面和a[10]的地址一样。这样我们就可以使用指针变量以及a来操作这个数组了。

所以,我们要注意以下问题:

(1)p[i]和a[i]都是代表该数组的第i+1个元素;

(2)p+i和a+i代表了第i+1个元素的地址,所以我们也可以使用*(p+I)和*(a+I)来引用对象元素;

(3)p+1不是对于指针数量上加一,而是表示从当前的位置跳过当前指针指向类型长度的空间,对于win32的int为4byte;

四、编译预处理

编译预处理别于其他高级程序设计语言的特征之一,它属于C语言编译系统的一部分。C程序中使用的编译预处理命令均以#开头,它在C编译系统对源程序进行编译之前,先对程序中这些命令进行“预处理”。本章的知识点是编译预处理命令的三种不同形式:宏定义,文件包含和条件编译。

下面看一个简单例题,增加对编译预处理的感性认识

【例】计算圆的周长和面积的程序

#define PI 3.1415926/*定义不带参数的宏名PI*/

#define CIRCUM(r)(2.0*PI*(r))/*定义带参数的宏名CIRCUM*/

#define AREA(r)(PI*(r)*(r))/*定义带参数的宏名AREA*/

img88

上面的程序中没有定义函数,但通过宏定义,同样能够计算圆的周长和面积,程序中用到的知识点是不带参数和带参数的宏定义。

(一)宏定义

宏定义是用预处理命令#define实现的,分为带参数的宏定义与不带参数的宏定义两种形式。

字符串的宏定义也叫不带参数的宏定义,它用来指定一个标识符代表一个字符串常数。它的一般格式:

#define标识符字符串

其中标识符就是宏的名字,简称为宏,字符串是宏的替换正文,通过宏定义,使得标识符等同于字符串。如:

#define PI 3.1415926

PI是宏名,字符串3.1415926是替换正文。预处理程序将程序中凡以PI作为标识符出现的地方都用3.1415926替换,这种替换称为宏替换,或者宏扩展。

这种替换的优点在于,用一个有意义的标识符代替一个字符串,便于记忆,易于修改,提高程序的可移植性。

1.宏名一般用大写字母,以便与程序中的变量名或函数名区分.当然宏名也可以用小写字母,但不提倡初学者这样做.宏名是一个常量的标识符,它不是变量,不能对它进行赋值.如例6.1中定义的PI和例6.2中定义的N均为宏名,如果用赋值语句对它们重新赋值是错误的。

2.宏替换是在编译之前进行的,由编译预处理不占用程序的运行时间。在替换时,只是作简单的替换,不作语法检查.只有当编译系统对展开后的源程序进行编译时才可能报错。

3.宏定义不是C语言的语句,不需要使用语句结束符“;”,如果使用了分号,则会将分号作为字符串的一部分一起进行替换。

4.字符串可以是一个关键字,某个符号或为空,如果字符串为空,表示从源文件中删除已定义的宏名。

(二)文件包含处理

预处理程序中的“文件包含处理”是一个源文件可以将另外一个源文件的全部内容包含进来,即将另外的文件包含到本文件之中,包含文件的命令格式有如下两种:

格式1:#include

格式2:#include"filename"

格式1中使用尖括号是通知预处理程序,按系统规定的标准方式检索文件目录。例如,使用系统的PACH命令定义了路径,编译程序按此路径查找filename,一旦找到与该文件名相同的文件,便停止搜索。如果路径中没有定义该文件所在的目录,即使文件存在,系统也将给出文件不存在的信息,并停止编译。

格式2中使用双引号""是通知预处理程序首先在原来的源文件目录中检索指定的文件filename;如果查找不到,则按系统指定的标准方式继续查找。

预处理程序在对C源程序文件扫描时,如遇到#include命令,则将指定的filename文件内容替换到源文件中的#include命令行中。

包含文件也是一种模块化程序设计的手段.在程序设计中,可以把一些具有公用性的变量,函数的定义或说明以及宏定义等连接在一起,单独构成一个文件。使用时用#include命令把它们包含在所需的程序中。这样也为程序的可移植性,可修改性提供了良好的条件。例如在开发一个应用系统中若定义了许多宏,可以把它们收集到一个单独的头文件中(如:user.h)。假设user.h文件中包含有如下内容:

#include"stdio.h"

#include"string.h"

#include"malloc.h"

#define BUFSIZE 128

#define FALSE 0

#define NO 0

#define YES 1

#define TRUE 1

#define TAB'\t'

#define NULL'\0'

当某程序中需要用到上面这些宏定义时,可以在源程序文件中写入包含文件命令:

#include"user.h"

学习材料样例

下面是一个关于言程序的编程例题,请你花15分钟的时间仔细学习。

用筛选法求100以内的素数。(素数就是质数。它除了能表示为它自己和1的乘积以外,不能表示为任何其他两个整数的乘积。例如,15=3*5,所以15不是素数;又如,12=6*2=4*3,所以12也不是素数。另一方面,13除了等于13*1以外,不能表示为其他任何两个整数的乘积,所以13是一个素数。)

img89

int i,j,line,a[N];/*line用于打印的时候控制每行打印的数字的个数*/

img90

img91

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈