您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > 数据结构中用到的-C语言基本知识
《数据结构》中必要的C语言基本知识有必要将数据结构所必须使用的C语言语法在此做简单介绍。根据多年教学实践,学生完成上机实验练习时遇到的主要问题是,不能正确的输入数据,结构体概念陌生,函数的传址调用概念不清,指针与链表有的没有学过。由于篇幅所限,这里仅对前三个问题加以介绍。如果学生基础好,可以越过这一部分内容不看。一、基本输入和输出对于重要的数据结构算法,均要求进行上机实验。而上机实践中离不开数据的输入/输出。看起来简单的输入/输出,往往是上机实验最容易出错的地方,尤其是输入。对于一个算法程序,如果数据不能正确输入,算法设计得再好也无法正常运行。1.输入C语言的输入是由系统提供的scanf()等函数实现,在程序的首部一般要求写入:#includestdio.h因为标准输入/输出函数都存在于头文件stdio.h之中,现将其包含进来方可使用这些常用的输入/输出函数。有的系统允许不使用上述包含语句,可以直接使用标准输入/输出函数。函数scanf()的功能很丰富,输入格式也是多种多样,这是大家较为熟悉的知识,这里不做详细介绍。在使用中需要注意以下几个问题。(1)一条scanf()语句有多个变量、并且都是数值型(int,float,double)时,在输入数据时应该在一行之内键入多个数据,数据之间空格分隔。例如:intn;floatx;scanf(“%d%f”,&n,&x);正确的输入应是:整数空格实数回车。例如:就是在两个数据之间使用空格键为分隔符,最后打回车键。如果语句中在%d和%f之间有一个逗号:scanf(“%d,%f”,&n,&x);正确的输入应是:整数逗号实数回车。例如:(2)在需要字符型变量或字符串输入时,要单独写一条输入语句,这样不易出错。如果在同一条scanf()语句中将字符型和数值型混合输入常常会出错。因为键盘输入时在数值型数据之间‘空格键’起‘分隔符’作用,但是在字符或字符串之间,‘空格’会被当做一个字符,而不能起到‘分隔符’的作用。所以将它们混在一起容易出错。(3)在scanf()语句中变量写法应该是该变量的地址,这一点常被忽视。请看下列程序:1:viodmain()2:{charname[10],ch;3:intnum;floatx;4:printf(“\n请输入姓名:”);scanf(“%s”,name);5:printf(“\n请输入性别:”);scanf(“%c”,&ch);6:printf(“\n请输入学号和成绩:”);scanf(“%d%f”,&n,&x);1003.14100,3.14……;}为了方便说明问题程序中加了行号,运行时当然不允许行号。一般情况下在scanf()语句中的变量名之前要加上求地址符&,上述程序第5,6行之中就是这样。为什么第4行的name前面不加&呢?因为name代表字符串,即是一维字符数组,一维数组名本身就是一个地址,是该数组的首地址,所以name前面不加&。在本程序中把字符串、字符、数值型变量分别写入不同的scanf()语句,输入数据的具体形式如下:请输入姓名:ZhangHua请输入性别:v请输入学号和成绩:10190.5请考虑如果姓名输入成:ZhangHua,会出现什么现象?那样只会读入Zhang做姓名,而Hua被忽略,还会影响后面的输入语句无法正确读入数据。因此,应该充分重视数据的输入技术。2.输出C语言的输出是由系统提供的printf()等函数来实现,在程序的首部一般要求写入:#includestdio.h因为标准输入/输出函数都存在于头文件stdio.h之中,现将其包含进来方可使用这些常用的输入/输出函数。有的系统允许不使用上述包含语句,可以直接使用标准输入/输出函数。输出函数printf()的语法一般容易掌握,这里强调的是怎样合理巧妙的使用它。1.在连续输出多个数据时,数据之间一定要有间隔,不能连在一起。intn=10,m=20,p=30;printf(“\n%d%d%d”,n,m,p);printf(“\n%6d%6d%6d”,n,m,p);//提倡使用的语句第一行输出是:102030第二行输出是:1020302.在输入语句scanf()之前先使用printf()输出提示信息,但是在printf()最后不能使用换行符。intx;printf(“\nx=?”);//句尾不应使用换行符scanf(“%d”,&x);这样使光标与提示信息出现在同一行上,光标停在问号后边:X=?□。3.在该换行的地方,要及时换行。inti;printf(“数据输出如下:\n”);//需要换行for(i=0;i8;i++)printf(“%6d”,i);//几个数据在同一行输出,不能换行4.在调试程序时多加几个输出语句,以便监视中间运行状况。程序调式成功后,再去掉这些辅助输出语句。二、函数与参数传递函数的设计和调用是程序设计必不可少的技能,是程序设计最重要的基础。一些初学者之之所以感到编程难,就是忽视了这个基础。在传统的面向过程的程序设计中,往往提倡模块化结构化程序设计,不论BASIC、FONFTRAN、PASCAL还是其他高级语言,最终要涉及到子函数的设计和使用。C语言的源程序是由一个主函数和若干(或零个)子函数构成,函数是组成C语言程序的基本单位。函数具有相对独立的功能,可以被其他函数调用,也可调用其他函数。当函数直接或间接的调用自身时,这样的函数称为递归函数。是否能够熟练的设计和使用函数,是体现一个人程序设计能力高低的基本条件。因此有必要回顾和复习C语言函数的基本概念。1函数的设计函数设计的一般格式是:类型名函数名(形参表){函数体;}函数设计一般是处理一些数据获得某个结果,因此函数可以具有返回值,上面的类型名就是函数返回值的类型,可以是int,float…..等。例如:floatfunx(形参表){函数体;.}函数也可无返回值,此时类型是void。例如:voidfuny(形参表){函数体;}而函数体内所需处理的数据往往通过形参表传送,函数也可以不设形参表,此时写为:类型名函数名(void){函数体;}例1.2设计一个函数计算三个整数之和,再设计一个函数仅输出一条线。设计主函数调用两个函数。#includestdio.hintsumx(inta,intb,intc)/*计算三个整数之和的函数*/{ints;s=a+b+c;returns;}voiddisplay(void)/*输出一条线的函数*/{printf(”----------------------\n“);}voidmain(){intx,y,z,sa;x=y=z=2;display();/*画一条线*/printf(“\nsum=%d”,sumx(x,y,z));/*在输出语句中直接调用函数sumx()*/printf(“\n%6d%6d%6d”,x,y,z);display();x=5;y=6;z=7;sa=sumx(x,y,z);/*在赋值语句中调用函数sumx()*/printf(“\n“sum=%d”,sa);printf(“\n%6d%6d%6d”,x,y,z);display();}/*程序结束*/运行结果:----------------------sum=6222----------------------sum=48151617----------------------2.关于函数的参数传递函数在被调用时,由主调程序提供实参,将信息传递给形参。在调用结束后,有时形参可以返回新的数据给主调程序。这就是所谓参数传递。各种算法语言实现参数传递的方法通常分为传值和传址两大类。在上例中函数sumx()的设计和主函数对它的调用,就是传值调用。第一、第二次调用,带入的实参均是三个整型变量。调用函数返回后,在主程序中输出实参的值仍与调用之前相同。传值调用的主要特点是数据的单向传递,由实参通过形参将数据代入被调用函数,不论在调用期间形参值是否改变,调用结束返回主调函数之后,实参值都不会改变。在不同的算法语言中,传址调用的语法有所不同。在PASCAL语言中用变参实现传址。在C语言中采用指针变量做形参来实现传址。传址调用的主要特点是可以实现数据双向传递,在调用时实参将地址传给形参,该地址中的数据代入被调用函数。如果在调用期间形参值被改变,也即该地址中的数据发生变化,调用结束返回主调函数之后,实参地址仍然不变,但是该地址中的数据发生相应改变。这就是数据的双向传递。现看一例题:例1.3设计一个函数实现两个数据的交换,在主程序中调用。#includestdio.hviodswap(int*a,int*b);/*函数原型声明*/voidmain(){intx=100,y=800;printf(“\n%6d%6d”,x,y);/*输出原始数据*/swap(&x,&y);/*调用交换数据的函数swap()*/printf(“\n%6d%6d”,x,y);/*输出交换后的数据*/}viodswap(int*a,int*b){intc;c=*a;*a=*b;*b=c;}运行结果:100800800100实践证明x,y的数据在调用函数前后发生了交换变化。形参是指向整形的指针变量a和b,在函数体内需要交换的是指针所指的存储单元的内容,因此使用*a=*b;这样的写法。在调用时,要求实参个数、类型位置与形参一致。因为实参应该是指针地址,所以调用语句swap(&x,&y)中,实参&x,和&y代入的是整型变量x,y的地址。在函数体内交换的是实参地址中的内容,而作为主函数变量x,y的地址仍然没有改变。从整数交换的角度看,本例题实现了双向数据传递。若从指针地址角度看,调用前后指针地址不变。现在回过头来看P5页[复数ADT实现的面向过程C语言源程序]的创建复数的函数:voidcreat(complex*c){…….;c-x=x1;c-y=y1;}在函数体中人们容易认识和习惯的写法c.x和c.y,也必须写成c-x和c-y。在调用该函数时,还必须将结构体变量a求地址做实参:creat(&a)。初学者应该特别注意这一点。如果需要在函数体中改变指针的地址,这就需要在原指针基础之上再加一级指针:voidfunz(int**a){/*改变*a*/…}函数调用返回后**a仍然不变,而*a发生了变化。由此可以看出C语言的传址调用比较复杂。不如PASCAL的变量参数简便,也不如C++的引用调用方便。三、结构体及运用数据结构课程所研究的问题均运用到“结构体”。在C语言中结构体的定义、输入/输出是数据结构程序设计的重要语法基础。定义结构体的一般格式:struct结构体类型名{类型名1变量名1;//数据子域类型名2变量名2;……类型名n变量名n;};其中struct是保留字。结构体类型名由用户自己命名。在使用时必须声明一个具体的结构体类型的变量,声明创建一个结构体变量的方法是:struct结构体类型名结构体变量名;例如:structElemType/*定义结构体*/{intnum;charname[10];};structElemTypex;/*声明结构体变量x*/另外有一种方法使用typedef语句定义结构体,在声明结构体变量时可以不写struct,使得书写更加简便。例如:typedefstruct{intnum;charname[10];}ElemType;ElemType就是一个新的类型名,并且是结构体类型名。声明变量x的语句是:ElemTypex;一个结构体中可以包含多个数据子域。数据子域的类型名一般指基本数据类型(intchar等),也可是已经定义的另一结构体名。数据子域变量名可以是简单变量,也可以是数组。它们也可以称为结构体的数据成员。通过“结构体变量名.数据子域”可以访问数据子域。例1.6设计Student结构体,在主程序中运用。#includestdio.h#includestring.htypedefstruct/*定义结构体Student*/{longnum;/*学号*/intx;/*成绩*/charname[
本文标题:数据结构中用到的-C语言基本知识
链接地址:https://www.777doc.com/doc-8558474 .html