徐州建站公司模板,建设公司设计公司网站,商务网站规划与建设,wordpress 5.2作者#xff1a;鲸90830链接#xff1a;https://www.cnblogs.com/whale90830/p/10488595.html由C到COOP第一课C语言的局限C的特点C的程序特征C程序的结构特性C程序的编辑、编译和运行⭐C对C的补充C语言的局限类型检查机制相对较弱#xff0c;使得程序中的一些错误不能在编译… 作者鲸90830链接https://www.cnblogs.com/whale90830/p/10488595.html由C到COOP第一课C语言的局限C的特点C的程序特征C程序的结构特性C程序的编辑、编译和运行⭐C对C的补充C语言的局限类型检查机制相对较弱使得程序中的一些错误不能在编译时由编译器检查出来。C语言本身没有支持代码重用的语言结构不适合开发大型程序当程序的规模达到一定的程度时程序员很难控制程序的复杂性。C的特点C继承了C的优点并有自己的特点主要有1、全面兼容CC的许多代码不经修改就可以为Cpp所用用C编写的库函数和实用软件可以用于Cpp。2、用C编写的程序可读性更好代码结构更为合理可直接在程序中映射问题空间结构。3、生成代码的质量高运行效率高。4、从开发时间、费用到形成软件的可重用性、可扩充性、可维护性和可靠性等方面有了很大提高使得大中型的程序开发项目变得容易得多。5、支持面向对象的机制可方便的构造出模拟现实问题的实体和操作。C的程序特征例1.1 输出一行字符 “This is a C program.”。程序如下#include //包含头文件iostream在运行时会在屏幕上输出以下一行信息This is a C program.用main代表“主函数”的名字。每一个C程序都必须有一个 main 函数。main前面的int的作用是声明函数的类型为整型。程序第6行的作用是向操作系统返回一个零值。如果程序不能正常执行则会自动向操作系统返回一个非零值一般为-1。函数体是由大括号{}括起来的。本例中主函数内只有一个以cout开头的语句。注意C所有语句最后都应当有一个分号。再看程序的第1行“#include”这不是Cpp的语句而是Cpp的一个预处理命令它以“#”开头以与Cpp语句相区别行的末尾没有分号。#include 是一个“包含命令”它的作用是将文件iostream的内容包含到该命令所在的程序文件中代替该命令行。文件iostream的作用是向程序提供输入或输出时所需要的一些信息。iostream是i-o-stream3个词的组合从它的形式就可以知道它代表“输入输出流”的意思由于这类文件都放在程序单元的开头所以称为“头文件” (head file)。在程序进行编译时先对所有的预处理命令进行处理将头文件的具体内容代替#include命令行然后再对该程序单元进行整体编译。程序的第2行“using namespace std;”的意思是“使用命名空间std”。Cpp标准库中的类和函数是在命名空间std中声明的因此程序中如果需要用到Cpp标准库(此时就需要用#include命令行)就需要用“using namespace std;”作声明表示要用到命名空间std中的内容。在初学C时对本程序中的第1,2行可以不必深究只需知道 如果程序有输入或输出时必须使用“#include ”命令以提供必要的信息同时要用“using namespace std;”使程序能够使用这些信息否则程序编译时将出错。例1.2 求a和b两个数之和// 求两数之和 (本行是注释行)本程序的作用是求两个整数a和b之和sum。第1行“//求两数之和”是一个注释行Cpp规定在一行中如果出现“//” 则从它开始到本行末尾之间的全部内容都作为注释。例1.3 给两个数x和y 求两数中的大者#include //预处理命令本程序包括两个函数:主函数main和被调用的函数max。程序运行情况如下:18 25 ↙ (输入18和25给a和b)max25 (输出m的值)注意输入的两个数据间用一个或多个空格间隔不能以逗号或其他符号间隔。在上面的程序中max函数出现在main函数之前因此在main函数中调用max函数时编译系统能识别max是已定义的函数名。如果把两个函数的位置对换一下即先写main函数后写max函数这时在编译main函数遇到max时编译系统无法知道max代表什么含义因而无法编译按出错处理。为了解决这个问题在主函数中需要对被调用函数作声明。上面的程序可以改写如下#include 只要在被调用函数的首部的末尾加一个分号就成为对该函数的函数声明。函数声明的位置应当在函数调用之前。C程序的结构特性一个面向对象的C程序一般由类的声明和类的使用两大部分组成。类的使用部分一般由主函数及有关子函数组成。典型的C程序结构#include //类的声明部分class A{ int x,y,z; ……fun( ){……} ……};//类的使用部分int main(){ A a; …… a.fun();return 0;}在C程序中程序设计始终围绕“类”展开。通过声明类构建了程序所要完成的功能体现了面向对象程序设计的思想。C程序的编辑、编译和运行C源程序文件的扩展名为.CPP可以用多种编译器编辑、编译和运行C对C的补充1、注释与续行注释符“/*”和“*/” 或“//” 。Cpp新增了注释语句它由“//”开始到行尾结束。例如/*This is a comment */X y z; //This is a comment续行符“\”(反斜杠)。作用是当一个语句太长时可以用该符号把它分段写在几行中。例cout n’ x2、输入输出流C中I/O操作出现的问题int i;Cpp中使用更安全更方便的方法int i;cout和cin分别是C的标准输出流和输入流。 Cpp支持重定向但一般cout指的是屏幕 cin指的是键盘。操作符“”除了具有C语言中定义的左移和右移的功能外在这里符号“”则是将标准输入流的数据赋给右方的变量。例1.4 一个完整的C程序#include 注意程序中必须包含头文件iostream.hcin和,cout和cin可以输入多个数据,但要用空白符隔开(tab空格回车)如 cin a b c;换行符‘\n’或endl如 cout “x” x endl; cout “x” x ‘\n’;使用cout和cin时也可以对输入和输出的格式进行控制比如可用不同的进制方式显示数据只要设置转换基数的操作符dec、hex和oct即可。例1.5 操作符dec、 hex和oct的使用#include输出结果为 19 25 313、灵活的变量说明定义变量的位置在程序中的不同位置采用不同的变量定义方式决定了该变量具有不同的特点。变量的定义一般可有以下三种位置(1) 在函数体内部在函数体内部定义的变量称为局部变量这种局部变量只在进入定义它的函数体时起作用离开该函数体后该变量就消失(被释放)即不再起作用。因此不同函数体内部可以定义相同名称的变量而互不干扰。(2) 形式参数当定义一个有参函数时函数名后面括号内的变量统称为形式参数。(3) 全局变量在所有函数体外部定义的变量其作用范围是整个程序并在整个程序运行期间有效。在C语言中全局变量声明必须在任何函数之前局部变量必须集中在可执行语句之前。Cpp中的变量声明非常灵活它允许变量声明与可执行语句在程序中交替出现。例如f( ){ int i; i10; int j; j25; // …}float fun(int x,int y){ for(int i0;i10;i) { int sum0; sumsumi; cout } int z0; zxy;}4、结构、联合和枚举名在C中结构名、联合名、枚举名都是类型名。在定义变量时不必在结构名、联合名或枚举名前冠以struct、union或enum。例如enum boole{FALSE,TRUE};在传统的C中定义变量时必须写成enum boole done;但是在C中可以说明为boole done;5、函数原型C语言建议编程者为程序中的每一个函数建立原型而Cpp要求为每一个函数建立原型以说明函数的名称、参数类型与个数以及函数返回值的类型。其主要目的是让C编译程序进行类型检查即形参与实参的类型匹配检查以及返回值是否与原型相符以维护程序的正确性。例如int sum(int a,int b); 函数原型语法的一般形式为返回类型 函数名(参数表)函数原型是一条语句它必须以分号结束。例1.6 函数原型的说明#include在程序中要求一个函数的原型出现在该函数的调用语句之前。说明函数原型的参数表中可不包含参数的名字而只包含它们的类型。例如 long Area(int ,int);函数定义由函数首部和函数体构成。函数首部和函数原型基本一样但函数首部中的参数必须给出名字而且不包含结尾的分号。Cpp的参数说明必须放在函数说明后的括号内不可将函数参数说明放在函数首部和函数体之间。这种方法只在C中成立。主函数不必进行原型说明因为它被看成自动说明原型的函数。原型说明中没有指定返回类型的函数(包括主函数main)Cpp默认该函数的返回类型是int如果一个函数没有返回值则必须在函数原型中注明返回类型为void主函数类似处理。如果函数原型中未注明参数Cpp假定该函数的参数表为空(void)。6、const修饰符在C中习惯使用#define定义常量。一般格式 #define 宏名 常数如#define PI 3.14C利用const定义正规常数一般格式 const 数据类型标识符 常数名常量值采用这种方式定义的常量是类型化的它有地址可以用指针指向这个值但不能修改它。说明:1、const必须放在被修饰类型符和类型名前面2、数据类型是一个可选项用来指定常数值的数据类型如果省略了该数据类型那么编译程序认为它是 int 类型。如 const int a10; 表示定义了一个初始值为10的整型常量它在程序中不可改变但可用于表达式的计算中。例2.6 #define的不安全性#include iostream.h但实际的输出是 T2 is 2const作用与#define相似但消除了#define的不安全性。如果用const取代了两个#define,就不会引起这个错误。#includeconst可以与指针一起使用(1)指向常量的指针一个指向常量的指针变量。例如const pc“efgh”; //允许(2)常指针把指针本身而不是它指向的对象声明为常量。例如char* 创建一个常指针就是创建一个不能移动的固定指针但是它所指的数据可以改变。例如:(3)指向常量的常指针这个指针本身不能改变它所指向的值也不能改变。要声明一个指向常量的常指针二者都要声明为const。例如const 这个语句的含义是声明了一个名为pc的指针变量它是一个指向字符型常量的常指针用“abcd”的地址初始化该指针。说明(1). 如果用const定义的是一个整型常量关键词int可以省略。所以下面的两语句是等价的const int bufsize200;const bufsize200;(2). 常量一旦被建立在程序的任何地方都不能再更改。(3). 与#define定义的常量有所不同const定义的常量可以有自己的数据类型这样C的编译程序可以进行更加严格的类型检查具有良好的编译时的检测性。(4). 函数参数也可以用const说明用于保证实参在该函数内部不被改动大多数C编译器能对具有const参数的函数进行更好的代码优化。例如通过函数i_Max求出整型数组a[200]中的最大值函数原型应该是int i_Max(const int* ptr);这样做的目的是确保原数组的数据不被破坏即在函数中对数组元素的操作只许读而不许写。调用时的格式可以是i_Max(a);7、void型指针void 通常表示无值但将void作为指针的类型时它却表示不确定的类型。这种void型指针是一种通用型指针也就是说任何类型的指针值都可以赋给void类型的指针变量。例如下面的程序段void pa; void型指针可以接受任何类型的指针的赋值但对已获值的void型指针对它在进行处理如输出或传递指针值时则必须进行强制类型转换否则会出错。#include 8、内联函数调用函数时系统要付出一定的开销用于信息入栈出栈和参数传递等。特别是对于那些函数体较小但调用又较频繁的函数计算机的开销相对就比较可观。在C语言中用宏替换可解决这个问题。例如有如下的函数add(用宏替换时上面的函数功能可写为#define add(x,y) xyC引进了内联函数(inline function)的概念。宏替换实质上是文字替换。内联函数与一般函数不同的是在进行程序的编译时编译器将内联函数的目标代码作拷贝并将其插入到调用内联函数的地方。例1.7 内联函数的使用#include iostream.h说明(1). 内联函数在第一次被调用前必须进行声明或定义否则编译器将无法知道应该插入什么代码。(2). C的内联函数具有与C中的宏定义#define相同的作用和类似机理但消除了#define的不安全性。(3). 内联函数体内一般不能有循环语句和开关语句。(4). 后面类结构中所有在类说明体内定义的函数都是内联函数。(5). 通常较短的函数才定义为内联函数。9、带有缺省参数值的函数在C中函数的参数可以有缺省值。当调用有缺省参数的函数时如果相应的参数没有给出实参则自动用相应的缺省参数值作为其实参。函数的缺省参数是在函数原型中给定的。例如int init(int x5, int y10);说明(1)在函数原型中所有取缺省值的参数必须出现在不取缺省值的参数的右边。int fun(int I,int j5,int k); 错误int fun(int I,int k,int j5); 正确(2)在函数调用时若某个参数省略则其后的参数皆应省略而采用缺省值。init (,20) 错误例.编写一个带有默认参数的函数使得在默认情况下显示两个整数的较大者否则显示两个整数的较小者。int main()10、函数重载(1) 什么是函数重载函数重载是指一个函数可以和同一作用域中的其他函数具有相同的名字但这些同名函数的参数类型、参数个数不同。如#include 在本例中定义了两个名称都叫whatitis的函数但它们的形参类型不同。因此这两个函数就是重载函数。(2) 为什么要使用函数重载在原有C语言中每个函数必须有其唯一的名称这样的缺点是所有具有相同功能、而只是函数参数不一样的函数就必须用一个不同的名称.而C中采用了函数重载后对于具有同一功能的函数如果只是由于函数参数类型不一样则可以定义相同名称的函数。(3) 匹配重载函数的顺序由于重载函数具有相同的函数名在进行函数调用时系统一般按照调用函数时的参数个数、类型和顺序来确定被调用的函数。具体来说按以下三个步骤的先后次序找到并调用那个函数(1)寻找一个严格的匹配即调用与实参的数据类型、个数完全相同的那个函数。(2)通过内部转换寻求一个匹配即通过(1)的方法没有找到相匹配的函数时则由C系统对实参的数据类型进行内部转换转换完毕后如果有匹配的函数存在则执行该函数。(3)通过用户定义的转换寻求一个匹配若能查出有唯一的一组转换就调用那个函数。即在函数调用处由程序员对实参进行强制类型转换以此作为查找相匹配的函数的依据。例1.8 重载例子#include 例 重载例子编写一个程序用来求两个整数或3个整数中的最大数。如果输入两个整数程序就输出这两个整数中的最大数如果输入3个整数程序就输出这3个整数中的最大数。#include (4) 定义重载函数时的注意事项重载函数间不能只是函数的返回值不同应至少在形参的个数、参数类型或参数顺序上有所不同。如void myfun(int i){………………}应使所有的重载函数的功能相同。如果让重载函数完成不同的功能会破坏程序的可读性。(5) 函数模板1) 函数模板 (function template)建立一个通用函数其函数类型和形参类型不具体指定而是一个虚拟类型。2) 应用情况凡是函数体相同的函数都可以用这个模板来代替不必定义多个函数只需在模板中定义一次即可。在调用函数时系统会根据实参的类型来取代模板中的虚拟类型从而实现了不同函数的功能。3) 一般形式- template typename T // 模板头 通用函数定义- template // 模板头 通用函数定义- template // 多个参数 通用函数定义说明 class与typename可以通用#include 函数模板说明1) 在对程序进行编译时遇到第13行调用函数max(i1,i2) 编译系统会将函数名max与模板max相匹配将实参的类型取代了函数模板中的虚拟类型T。此时相当于已定义了一个函数然后调用它。int max(int a,int b){2) 与重载函数比较用函数模板比函数重载更方便程序更简洁。但应注意它只适用于函数的参数个数相同而类型不同且函数体相同的情况。如果参数的个数不同则不能用函数模板3) main函数不能定义为模板函数。11. 作用域标示符::通常情况下如果有两个同名变量一个是全局的另一个是局部的那么局部变量在其作用域内具有较高的优先权。下面的例子说明了这个问题。#include iostream.h如果希望在局部变量的作用域内使用同名的全局变量可以在全局变量加上“::”此时::avar代表全局变量avar#include 12、无名联合无名联合是C中的一种特殊联合可以声明一组无标记名共享同一段内存地址的数据项。如union{在此无名联合中声明了变量i和f具有相同的存储地址。无名联合可通过使用其中数据项名字直接存取例如可以直接使用上面的变量i或f如i20;13、强制类型转换在C中数据类型转换的一般形式(数据类型标识符)表达式int iC支持这样的格式还提供了一种更为方便的函数调用方法即将类型名作为函数名使用使得类型转换的执行看起来好像调用了一个函数。形式为数据类型标识符 (表达式)int i以上两种方法C都接受但推荐使用后一种方式。14、动态内存分配作为对C语言中malloc和free的替换C引进了new和delete操作符。它们的功能是实现内存的动态分配和释放。动态分配new的一般形式是指针变量new 数据类型指针变量new 数据类型(初始值);int *a *b;释放由new操作动态分配的内存时用delete操作。它的一般形式是delete 指针变量;delete a;例1.9 操作符new和delete的使用#include 例1.10 将new和delete用于结构类型#include与C的内存动态分配和释放操作(malloc和free)相比C提供的动态分配有以下优点(1) new和delete 操作自动计算需要分配和释放类型的长度。这不但省去了用sizeof计算长度的步骤更主要的是避免了内存分配和释放时因长度出错带来的严重后果(2) new操作自动返回需分配类型的指针 无需使用强制类型转换(3) new操作能初始化所分配的类型变量。(4) new和delete都能可以被重载允许建立自定义的内存管理法。对使用new和delete的几点说明(1)用new分配的空间使用结束后应该用delete显示的释放否则这部分空间将不能回收而变成死空间。(2)使用new动态分配内存时如果没有足够的内存满足分配要求 new将返回空指针(NULL)。因此通常要对内存的动态分配是否成功进行检查。例1.11 对内存的动态分配是否成功进行检查#include (3) 使用new可以为数组动态分配内存空间这是需要在类型后面缀上数组大小。其语法形式为指针变量new 类型名 [下标表达式];如 int *pinew int[2][3][4];其中第一维的界值可以是任何合法的表达式如int i3; int *pinew int[ i ][2][3];例如 int *pinew int[10];这时new为具有10个元素的整型数组分配了内存空间并将首地址赋给了指针pi。使用new为多维数组分配空间时必须提供所有维的大小(4) 释放动态分配的数组存储区时可使用delete运算符其语法形式为 delete [ ]指针变量;无须指出空间的大小但老版本的Cpp要求在delete的方括号中标出数字以告诉Cpp要释放多少个元素所占的空间。例如delete []pi; delete [10]pi;(5) new可在为简单变量分配内存空间的同时进行初始化。这时的语法形式为指针变量new 类型名(初始值列表)例 1.12 new为简单变量分配内存空间的同时进行初始化#include 例 1.13 给数组分配内存空间的例子。#include 15. 引用(1) 引用的概念引用就是某一变量(目标)的一个别名这样对引用的操作就是对目标的操作。引用的声明方法 类型标识符 引用名目标变量名;int a;说明(1) 在此不是求地址运算而是起标识作用。(2) 类型标识符是指目标变量的类型。(3)声明引用时必须同时对其进行初始化。(4)引用声明完毕后相当于目标变量名有两个名称。(5)声明一个引用不是新定义了一个变量系统并不给引用分配存储单元。例1.15 引用的使用#include 结果i30 j30i80 j80Address of oxfff4Address of oxfff4例1.16 使用引用可以简化程序#include运行结果is (2) 引用的使用(1)引用名可以是任何合法的变量名。除了用作函数的参数或返回类型外在声明时必须立即对它进行初始化不能声明完后再赋值。int i;(2)引用不能重新赋值不能再把该引用名作为其他变量名的别名任何对该引用的赋值就是该引用对应的目标变量名的赋值。对引用求地址就是对目标变量求地址。int iint num(3)由于指针变量也是变量所以可以声明一个指针变量的引用。方法是 类型标识符 *引用名指针变量名;#include (4)引用是对某一变量或目标对象的引用它本身不是一种数据类型因此引用本身不占存储单元这样就不能声明引用的引用也不能定义引用的指针。int a;(5)不能建立数组的引用因为数组是一个由若干个元素所组成的集合所以就无法建立一个数组的别名。(6)不能建立空指针的引用int rp(7)也不能建立空类型void的引用因为尽管在C语言中有void数据类型但没有任何一个变量或常量属于void类型。void ra(8) 尽管引用运算符与地址操作符使用相同的的符号但时不一样的。引用仅在声明时带有引用运算符以后就像普通变量一样使用不能再带。其他场合使用的都是地址操作符。int j(3) 用引用作为函数的参数一个函数的参数也可定义成引用的形式void swap(int p1, int p2) //形参p1, p2都是引用{在主调函数的调用点处直接以变量作为实参进行调用即可不需要实参变量有任何的特殊要求。//直接以a和b作为实参调用swap函数例1.17 采用指针参数的例子#include运行结果a例1.18 采用“引用参数”传递函数参数#include 运行结果a(4) 用引用返回函数值函数可以返回一个引用将函数说明为返回一个引用的主要目的是为了将函数用在赋值运算符的左边。要以引用返回函数值则函数定义时要按以下格式类型标识符 函数名(形参列表及类型说明){函数体}说明以引用返回函数值定义函数时需要在函数名前加用引用返回一个函数值的最大好处是在内存中不产生被返回值的副本。例1.19 返回引用的函数#include 例1.20 用引用返回函数的值#include运行结果array(在定义返回引用的函数时注意不要返回该函数内的自动变量 (局部变量)的引用由于自动变量的生存期仅限于函数内部当函数返回时自动变量就消失了。fun()传递引用给函数与传递指针的效果是一样的但使用更简练。使用引用传递函数的参数在内存中并没有产生实参的副本它是直接对实参操作void swap(int *p1, int *p2){如何使一个被调函数同时返回多个值由于函数的返回值是通过函数体中的return语句完成的但一个return语句只能返回一个值为此我们可以采用以下方法(1)利用全局变量的方法在函数中把所需数据保存在全局变量中。当被调函数执行完毕后在主调函数中直接读取全局变量的值即可。(2)使用指针或数组的方法指针作为函数参数的情况下可将主调函数的某些变量的地址传递给被调函数。(3)利用引用的方法使用引用传递参数可以在被调函数中改变主调函数中目标变量的值这种方法实际上就是可以使被调函数返回多个值。例 使用引用使函数返回多个值以下定义了可以同时返回10个数中的最大值和最小值的函数max_min。#include 例 以下程序中定义了一个普通的函数fn1(它用返回值的方法返回函数值)另外一个函数fn2它以引用的方法返回函数值。#include 一个返回引用的函数值作为赋值表达式的左值一般情况下赋值表达式的左边只能是变量名即被赋值的对象必须是变量只有变量才能被赋值常量或表达式不能被赋值但如果一个函数的返回值是引用时赋值号的左边可以是该函数的调用。例2-26 测试用返回引用的函数值作为赋值表达式的左值。#include 用const限定引用声明方式 const 类型标识符 引用名目标变量名;用这种方式声明的引用不能通过引用对目标变量的值进行修改从而使引用的目标成为const达到了引用的安全性。例2-27#include “iostream.h”程序运行的结果100132200332引用总结(1)在引用的使用中单纯给某个变量取个别名是毫无意义的引用的目的主要用于在函数参数传递中解决大对象的传递效率和空间不如意的问题。(2)用引用传递函数的参数能保证参数传递中不产生副本提高传递的效率且通过const的使用保证了引用传递的安全性。(3)引用与指针的区别是指针通过某个指针变量指向一个对象后对它所指向的变量间接操作程序中使用指针程序的可读性差而引用本身就是目标变量的别名对引用的操作就是对目标变量的操作。课后练习题目#include●编号477输入编号直达本文●输入m获取文章目录C语言与C编程分享C/C技术文章