版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
返回本书目录
C语言绪论返回本章目录1.1.2C程序的开发过程1.1.3VisualC++6.0集成环境1.1.1C程序实例1.1VisualC++6.0环境运行的C程序实例返回本节目录2.C程序实例(2)3.C程序实例(3)1.C程序实例(1)1.1.1C程序实例1.1.1C程序实例(1)返回本节目录1.C程序实例1【例1.1】输出一行信息:ThiseisaCprogram.程序名为l1_1.cpp。#include"stdio.h" /*文件包含*/main() /*主函数*/{printf("ThisisaCprogram.\n"); /*输出信息*/}程序输出结果:ThisisaCprogram.程序演示[例1.1]程序演示单击运行输入源程序弹出运行结果窗口运行结果返回例题返回本节目录1.1.1C程序实例(2)2.C程序实例2【例1.2】输入两个整数,输出它们的和。程序名为l1_2.cpp。#include"stdio.h" /*文件包含*/main() /*主函数*/{inta,b,c; /*声明定义变量a,b和c*/
scanf("%d%d",&a,&b); /*输入变量a和b的值*/c=a+b; /*计算c等于a与b的和值*/
printf("c=%d\n",c); /*输出变量c的值*/}运行程序输入:90<CR>7<CR>程序结果:C=97返回本节目录程序演示[例1.2]程序演示单击运行输入源程序弹出运行结果窗口运行结果输入90和7,并以回车作分隔符和输入结束符。返回例题返回本节目录1.1.1C程序实例(3)3.C程序实例3【例1.3】输入两个整数,通过调用函数计算它们的和,然后输出和值。程序名为l1_3.cpp。#include"stdio.h" /*文件包含*/intsum(intx,inty) /*定义sum函数*/{intz; /*声明定义变量z*/z=x+y; /*计算z等于x与y的和值*/return(z); /*将z的值返回,通过sum带回调用处*/}main() /*主函数*/{inta,b,c; /*声明定义变量a,b和c*/
scanf("%d%d",&a,&b); /*输入变量a和b的值*/c=sum(a,b); /*调用sum函数,将得到的值赋给c*/
printf("c=%d\n",c); /*输出变量c的值*/}运行程序输入:907<CR>程序结果:C=97返回本节目录程序演示[例1.3]程序演示单击运行输入源程序弹出运行结果窗口返回例题运行结果输入90和7,并以空格作间隔符,以回车作输入结束符。返回本节目录1.1.2C程序的开发过程返回本节目录1.编辑2.编译
(1)编辑指编辑创建源程序是将编写好的C语言源程序代码录入到计算机中,形成源程序文件。(2)本书用VisualC++6.0环境提供的全屏幕编辑器。在附录3中介绍TurboC2.0的环境情况。(3)在VC6.0环境中的源程序文件,其扩展名为.cpp,而在TurboC2.0环境中的源程序文件的扩展名为.c。(1)编译源程序就是由C系统提供的编译器将源程序文件的源代码转换成目标代码的过程。(2)编译过程主要进行词法分析和语法分析,在分析过程中如果发现错误,将错误信息显示在屏幕上通知用户。经过编译后的目标文件的扩展名为.obj。
1.1.2C程序的开发过程返回本节目录3.连接4.运行
(1)连接过程是将编译过程中生成的目标代码进行连接处理,生成可执行程序文件的过程。(2)在连接过程中,时常还要加入一些系统提供的库文件代码。经过连接后生成的可执行文件的扩展名为.exe。
运行可执行文件的方法很多,可在C系统下执行“运行”命令。也可以在操作系统下直接执行可执行文件。可执行的程序文件运行后,将在屏幕上显示程序执行的结果。1.1.3VisualC++6.0集成环境返回本节目录1.启动VisualC++6.0环境2.
编辑源程序文件3.编译和连接4.执行
利用VisualC++6.0集成环境开发C程序的过程如下:1.1.3VisualC++6.0集成环境返回本节目录1.启动VisualC++6.0环境
方法:单击“开始”-“程序”-“MicrosoftVisualstudio6.0”-“MicrosoftVisualC++6.0”命令,启动VisualC++,VC6主窗口如下:菜单栏项目工作区标题栏输出区工具栏状态栏文件编辑区返回1.1.3VisualC++6.0集成环境返回本节目录2.
编辑源程序文件(1)建立新工程项目①单击“文件”-“新建”,弹出“新建”对话框。②单击“工程”选项卡;单击“Win32ConsoleApplication”选项;“工程”文件框中输入项目名,如“gc1”和“位置”框输入或选择新项目所在位置,单击“确定”按钮。弹出“Win32ConsoleApplicationStep1of1”对话框。③单击“Anemptyproject”按钮和“完成”按钮。系统显示“新建工程信息”对话框。单击“确定”按钮。
单击“工程”单击“Win32ConsoleApplication”输入项目名选择新项目位置单击“确定”单击该选项单击“完成”单击“确定”返回1.1.3VisualC++6.0集成环境返回本节目录2.
编辑源程序文件(2)建立新项目中的文件①单击“文件”-“新建”,弹出“新建”对话框。②
选择“文件”选项卡。单击“C++SourceFile”选项,在“文件”文件框中输入文件名,单击“确定”按钮。系统自动返回VC6主窗口。③显示文件编辑区窗口,在文件编辑区窗口输入源程序文件。单击“文件”输入文件名单击“C++Sourcefile”单击“确定”选择“添加工程”输入源程序返回1.1.3VisualC++6.0集成环境返回本节目录3.
编译和连接
方法一:选择主窗口菜单栏中“编译”菜单项;系统弹出下拉菜单,选择“构件”菜单命令。
方法二:单击主窗口编译工具栏上的“Build”按钮进行编译和连接。单击“编译”
(1)系统对程序文件进行编译和连接,生成以项目名称命名的可执行目标代码文件.exe。(2)编译连接过程中,系统如发现程序有语法错误,则在输出区窗口中显示错误信息,给出错误的性质、出现位置和错误的原因等。如果双击某条错误,编辑区窗口右侧出现一个箭头,指示再现错误的程序行。用户据此对源程序进行相应的修改,并重新编译和连接,直到通过为止。
单击“Build”返回1.1.3VisualC++6.0集成环境返回本节目录4.
执行方法一:单击“编译”菜单中“执行”命令。方法二:单击主窗口编译工具栏上的“BuildExecute”按钮来执行编译连接后的程序。运行成功,屏幕上输出执行结果,并提示信息:“Pressanykeytocontinue”。此时按任意键系统都将返回VC6主窗口。
在执行程序过程中出现运行错误。用户要修改源程序文件并且重新编译、连接和执行。单击“编译”单击“BuildExecute”返回返回本章目录1.2.2C程序的书写格式1.2.1C程序的结构特点1.2C程序的基本结构1.2.1C程序的结构特点返回本节目录
任何函数(包括主函数main())都是由函数说明和函数体两部分组成。其一般结构如下:[函数类型]函数名(函数参数表)
/*函数说明部分*/
{说明语句部分;
/*函数体部分*/
执行语句部分;
}1.2.1C程序的结构特点1.C程序是由函数构成的。2.
函数由函数说明和函数体组成。3.C程序总是从main函数开始执行。4.C程序语句和数据定义必须以分号“;”结束。5.C语言严格区分大小写。6.C语言数据输入和输出是由库函数实现的。7.C语言用/*注释内容*/形式进行程序注释。
一个C源程序可由一个main函数和若干个其他函数组成,其中必须有一个且只能有一个main函数。
函数说明部分包括函数名、函数返回值类型、函数的形式参数(形参)名、形式参数类型。函数体即函数说明部分下面的用一对大括号括起来的部分{……}。返回本节目录
main函数始终是C程序执行时入口处。
C语言中,分号是程序语句的结束标志,也是C语句的必要组成部分。
如变量a和变量A系统认定为两个不同的变量。
C语言本身没有输入输出语句。输入和输入操作是由库函数scanf和printf等函数来实现的。
在“/*”和“*/”之间的所有字符都为注释符,C系统不对注释符进行编译。1.2.2C程序的书写格式返回本节目录1.C程序书写格式自由。2.C程序书写采用缩进格式。3.程序中适当使用注释信息。
根据语句的从属关系,程序书写时采用缩进格式,使程序语句的层次结构清晰,提高程序的可读性。同一层次语句要左对齐,不同层次的语句要缩进若干个字符,这样程序层次清楚,便于阅读和理解。
在书写程序时,适当地加入注释同样可增加程序的可读性。
对于短语句可以多条语句书写在同一行,也可以将长语句分写在多行。但需要注意,分行时不能将一个单词分开,也不能将双引号引起来的字符串分开。我们提倡一行一条语句的风格。
返回本章目录1.3.2C语言的词法
1.3.1C语言的字符集
1.3C语言的词法1.3.1C语言的字符集
C语言的字符集是由ASCII字符集组成(1)26个小写字母:a—z。返回本节目录(2)26个大写字母:A—Z。(3)10个数字:0—9。(4)其他符号:+、-、*、/、=、,、.、_、)、(、&、^、%、$、#、@、!、~、<、>、?、’、;、:、”、)、[、]、{、}、-、\、空格。
1.3.2C语言的词法
返回本节目录C语言使用一组字符来构造具有特殊意义的符号,我们称之为词法符号。主要有关键字、标识符、运算符、分隔符、常量及注释符等。1.关键字
关键字是系统预定义的词法符号,具有特定的含义。ANSIC规定有32个关键字,C++又补充了29个关键字。C和C++均不允许对关键字重新定义,即程序员不能用这样关键字再定义其他含义。
关键字举例:
intcharfloatlongifelseforwhile
sizeofstaticstruct
注释符前面已经介绍。运算符是对数据进行某种操作的单词,是系统预定义的函数,具体内容将在第2章详细介绍。常量是程序中由书写形式决定类型和值的数据。C语言常量有数字常量、字符常量和字符串常量。将在第2章中做详细介绍。
1.3.2C语言的词法
返回本节目录
2.标识符
3.分隔符
4.其他
标识符是指用来标识程序中用到的变量名、函数名、类型名、数组名、文件名以及符号常量名的有效字符序列。
C语言标识符命名必须符合语法规定:标识符是以字母或下划线开始,由字母、数字和下划线组成的符号串。
分隔符是程序中的标点符号,用来分隔单词或程序正文。(1)空格:作为单词之间的分隔符。(2)逗号:作为变量之间或函数的多个参数之间的分隔符。(3)冒号:作为语句标号与语句间的分隔符以及switch语句中case与语句序列之间的分隔符。(4)大括号:作为函数体、复合语句等定界。
返回本章目录1.4.2C语言字符数据输入/输出1.4.3C++的输入输出流1.4.1C语言格式输入/输出1.4C语言数据输入和输出1.4.1C语言格式输入/输出
标准函数库中定义了一些输入输出函数,程序在调用这些库函数时,必须在源文件的开始处加上头文件的“包含命令”,格式如下:
#include<库函数头文件名>或#include"库函数头文件名"
1.格式输出函数printf()
printf()函数的作用:向计算机系统默认的输出设备(一般指终端或显示器)输出一个或多个任意类型的数据。
printf()函数的一般格式如下:
printf(“格式字符串”[,输出项表]);(1)“输出项列表”是需要输出的一些数据。数据可以有0项、1项或多个输出项,多个输出项之间用“,”分隔,并且输出项应与格式控制相匹配。(2)“格式控制”是用双引号括起来的一串字符,也称格式控制字符串,包括格式说明、普通字符和转义字符3种。格式控制字符串的功能是指定输出数据的格式和类型。下面均以【例1.2】和【例1.3】中的printf("c=%d\n",c);进行说明。其中,“c=”是普通字符,“%d”是格式说明,’\n’是转义字符,而c是输出项。返回本节目录1.4.1C语言格式输入/输出
(1)普通字符:普通字符内容按照原样向输出设备输出。如“c=”在屏幕上输出结果就是:c=返回本节目录下面分别对“格式控制”的3种形式进行说明(2)格式说明:格式说明是以字符“%”开头,加上格式字符组成,表示对数据输出格式的控制,它与后面的数据输出项对应。格式说明与数据输出项的数据个数、数据类型及数据排放次序相匹配对应。如,格式说明“%d”与输出项“c”对应,即控制数据输出项c按格式说明"%d"规定的格式(十进制整数形式)输出。因此,据c值为97,输出结果是:97
如果,格式说明“%d”改为“%c”,则输出项c的值将按“%c”规定的格式(字符型数据)输出。因此,据c值为97,输出结果是:a
‘a’为97对应的ASCII字符。常用的格式字符情况如教材表1-1所示。(3)转义字符:转义字符是以’\’开头和其他特殊字符组合而成的具有一定含义的字符。如’\n’
表示“回车换行”符。
转义字符是ASCII字符中的一种,主要用来控制外部设备。常用的一些转义字符及其含义见教材表1-4所示。1.4.1C语言格式输入/输出
2.格式输入函数scanf()
格式控制输入函数scanf作用是:按指定的格式从标准输出设备(键盘)输入数据。
函数scanf()的使用格式为:
scanf(“格式控制”,地址列表);
(1)“地址列表”是由接收数据变量的地址组成。求地址运算符为&,如&a,&b分别表示变量a和变量b的地址。若接收多个数据,则变量地址之间用“,”分隔,并且地址列表与格式控制中的格式说明相匹配。(2)“格式控制”基本同于printf函数的格式控制。格式控制的功能是规定输入数据的格式。格式控制包括格式说明和普通字符,一般不包括转义字符。
返回本节目录
(1)格式说明之间有普通字符或转义字符时,则数据输入时,必须按它们的原样输入这些字符作为数据分隔符。如,scanf("%d,%d",&a,&b);
输入数据时,数据之间必须用“,”作为分隔符。可输入:90,7<CR>。(2)连续输入多个数值型数据时,数据之间要用空格、Tab键或回车键作分隔符。如【例1.2】和【例1.3】中语句scanf(“%d%d”,&a,&b);输入数据时,数据之间可用空格、Tab键或回车键分隔符。可输入:907<CR>。
(3)连续输入多个字符数据时,各字符间不输入分隔符。如,scanf("%c%c",&a,&b);输入数据时,连续输入相应的字符。可输入:AB<CR>。则将‘A’字符输给了变量a,将‘B’字符输给了变量b。(4)数据型数据和字符型数据交叉输入时,若字符在前,则字符和数值型数据间可以加入分隔符(空格、Tab键和回车键);若数值在前,则数值和字符间不可以加分隔符(空格、Tab键和回车键)。(5)输入数据时,可以指定数据所占列数,系统自动按它截取所需数据。如,scanf("%3d%3d",&a,&b);若输入:12345678<CR>系统自动将123赋给a,456赋给b。
(6)输入数据时不能规定精度。如,scanf("%5.2f",&a);是不合法的。
1.4.1C语言格式输入/输出
注意:格式字符和附加格式字符使用应与输出项相匹配。返回本节目录字符输入函数getchar的一般格式为:
getchar()
getchar作用:在标准输入设备(键盘)读入一个字符。例如,charc;c=getchar();执行时,要求输入一个字符,如输入:3<CR>,则输入的字符’3’就赋给了变量c。1.4.2C语言字符数据输入/输出
1.字符输出函数putchar()2.字符输入函数getchar()
字符输出函数putchar的一般格式为:
putchar(c)putchar作用:在标准输出设备(显示器)上输出c对应的一个字符。输出的字符是括号中c所对应的一个字符。c可以是单字符数据、整型数据及其表达式。如,charc=’Y’;putchar(c);输出结果为Y。如,inta=98;putchar(a+1);输出结果为c。返回本节目录1.4.3C++的输入输出流C++程序中,还增加了特有的输入/输出流,由输入/输出流库提供。cin和cout是流库预定义标准输入流对象和标准输出流对象,分别连接键盘和显示器。
头文件iostream.h包含了操作所有输入/输出流所需的基本信息。因此,大多数C++程序都将iostream.h头文件包括到用户的源文件中,即:#include<iostream.h>1.输出cout输出流对象cout必须配合插入操作符<<使用。输出格式为:
cout<<输出项1<<输出项2<<……<<输出项n;功能:首先计算出各输出项的值,然后将其转换成字符流形式输出。返回本节目录【例1.4】将【例1.1】使用输出流cout完成数据输出。程序名为l1_4.cpp。#include<iostream.h> /*文件包含*/main() /*主函数*/{cout<<"ThisisaCprogram.\n"; /*输出信息*/}
输入项还可以是各种控制字符或函数,如回车换行符’\n’等。常用的输入/输出流格式控制符见教材表1-5所示。使用格式控制符要包含头文件iomanip.h,即源文件开始应增加文件包含命令#include<iomanip.h>。
【例1.5】将【例1.2】使用输入流cin和输出流cout完成。程序名为l1_5.cpp。#include<iostream.h> /*文件包含*/#include<iomanip.h>main() /*主函数*/{inta,b,c; /*声明定义变量a,b和c*/cin>>a>>b; /*输入变量a和b的值*/c=a+b; /*计算c等于a与b的和值*/cout<<"c="<<c<<endl; /*输出变量c的值*/}1.4.3C++的输入输出流返回本节目录2.输入cin输入流对象cin必须配合提取操作符>>来完成数据的输入。输入格式为:
cin>>变量1>>变量2>>……>>变量n;功能:读取用户输入的字符串,按相应变量的类型转换成二进制代码写入内存。执行到输入语句时,用户按语句中变量的顺序和类型键入各变量的值。输入多个数据时,以空格、Tab键和回车键作分隔符。
返回本章目录1.5.2高级语言与C语言
1.5.1程序与程序设计语言1.5程序设计语言发展1.5.1程序与程序设计语言返回本节目录1.
程序2.程序设计语言
程序是控制计算机完成特定功能的一组有序指令的集合。前面我们见到的各个例题【例1.1】、【例1.2】、【例1.3】和【例1.4】和【例1.5】都是一些小的程序,都能完成一定的功能。
编写程序所使用的语言称为程序设计语言,它是人与计算机之间进行信息交流的工具。前面我们介绍的程序【例1.1】、【例1.2】和【例1.3】是用TurboC程序设计语言编写的,而【例1.4】和【例1.5】是用VisualC++程序设计语言编写的。可见,C语言和VisualC++语言是两种程序设计语言,是程序员编程的工具。返回本章目录2.1C语言各种运算符和表达式的应用2.C程序实例(2)1.C程序实例(1)【例2.1】关于常量、变量及数据类型说明的程序实例。程序名为l2_1.cpp。#include"stdio.h"main(){inta=3; /*定义整型变量a并赋予常量值3*/shortr=6; /*定义短整型变量r并赋予常量值6*/
charc='a'; /*定义字符变量c并赋予字符常量值'a'*/
floatpi=3.14; /*定义单精度实型变量pi并赋予实型常量值3.14*/doubles; /*定义双精度实型变量s*/s=pi*r*r; /*将pi*r*r值赋给s*/
printf("int:%d,short:%d,char:%d,float:%d,double:%d\n",sizeof(a),
sizeof(r),sizeof(c),sizeof(pi),sizeof(s)); /*输出各变量占内存的字节数*/
printf("a=%d,r=%d,c=%c,pi=%f,s=%lf\n",a,r,c,pi,s); /*输出各变量的值*/}2.1.1C程序实例(1)返回本节目录1.C程序实例1程序结果[例2.1]程序结果及分析返回例题返回本节目录结果分析:变量可以被定义成不同的数据类型并赋值,不同类型的数据在内存中所占的字节数不同,通过sizeof()求得数据宽度。短整型、整型、字符型、单精度实型、双精度实型在内存中分别占2字节、4字节、1字节、4字节和8字节。同时,这些数据在输出时所使用的输出格式控制符也不相同,分别为%d、%d、%c、%f和%lf形式。由此可见,数据表现为常量或变量,数据又具有不同的数据类型,不同数据类型的数据存储格式不同,数据的输出格式控制也不相同。注意:在TruboC环境下,整型数据存储时在内存中占2字节。2.1.1C程序实例(2)2.C程序实例2【例2.2】关于运算符和表达式的程序实例。/*程序名为l2_2.cpp。*/#include"stdio.h"main(){inti=3,a=5,b=7,c,d; /*定义变量并赋初值*/
printf("i=%d\n",i++); /*输出i++的值*/
printf("i=%d\n",i); /*输出i的值*/c=a>b?a:b; /*计算表达式c=a>b?a:b*/
printf("c=%d\n",c); /*输出c的值*/d=a<=b&&i; /*计算表达式d=a<=b&&i*/
printf("d=%d\n",d); /*输出d的值*/d=(c,d=c); /*计算表达式d=(c,d=c)*/
printf("d=%d\n",d); /*输出d的值*/}
返回本节目录程序结果[例2.2]程序结果及分析返回例题返回本节目录结果分析:由结果i=3i=4可知printf("i=%d\n",i++);中i++的值仍然为3,而i的值由3增1后变为4,理解自增运算符++的运算方式。c=a>b?a:b;语句中包括了关系运算符“>”、条件运算符“?:”、赋值运算符“=”,经过各种运算处理后c的值为7。d=a<=b&&i;语句中包括了关系运算符“<=”、逻辑运算符“&&”、赋值运算符“=”,经过各种运算处理后d的值为1。d=(c,d=c);语句中包括了赋值运算符“=”、逗号运算符“,”,经过各种运算处理后d的值为7。2.2C语言的数据类型返回本节目录单精度实型(float)双精度实型(double)整型(int)字符型(char)枚举类型数组类型结构体类型共用体类型实型基本类型构造类型空类型(void)指针类型数据类型2.2C语言的数据类型2.2.1基本数据类型2.2.2常量2.2.3变量及其类型定义返回本节目录2.2.1基本数据类型返回本节目录1.整型数据2.实型数据3.字符型数据2.2.1基本数据类型(一)
1.
整型数据整型数据分为一般整型(int)、短整型(short)和长整型(long),并且每一种类型又分为带符号(signed)和无符号(unsigned)两种类型。整型数据的特性见下表:
返回本节目录数据类型名说明VisualC++6.0环境TurboC2.0环境字节取值范围字节取值范围short[int]短整型2-32768~327672-32768~32767signedshort[int]带符号短整型2-32768~327672-32768~32767unsignedshort[int]无符号短整型20~6553520~65535int整型4-2147483648~21474836472-32768~32767signed[int]带符号整型4-2147483648~21474836472-32768~32767unsigned[int]无符号整型40~429496729520~65535long[int]长整型4-2147483648~21474836474-2147483648~2147483647signedlong[int]带符号长整型4-2147483648~21474836474-2147483648~2147483647unsignedlong[int]无符号长整型40~429496729540~4294967295返回2.2.1基本数据类型(二)
2.
实型数据实型数据分为单精度实型(float)、双精度实型(double)和长双精度实型(longdouble)。具体情况见下表所示
:
数据类型名说明VisualC++6.0环境TurboC2.0环境字节取值范围有效数字字节取值范围有效数字float单精度实型4-3.4×1038~3.4×10386~74-3.4×1038~3.4×10386~7double双精度实型8-1.7×10308~1.7×1030815~168-1.7×10308~1.7×1030815~16longdouble长双精度实型16-1.2×104932~1.2×10493218~1910-1.2×104932~1.2×10493218~19返回返回本节目录2.2.1基本数据类型(三)
3.
字符型数据字符型数据分为一般字符型(char)、带符号字符型(signedchar)和无符号字符型(unsignedchar)三种类型。具体情况见下表所示
:
数据类型名说明字节取值范围char字符型1-128~127signedchar带符号字符型1-128~127unsignedchar无符号字符型10~255返回返回本节目录2.2.2常量1.整型常量2.实型常量3.字符型常量4.字符串常量
返回本节目录2.2.2常量(一)1.整型常量(1)十进制整型常量:以数字1~9开头,其他位以数字0~9构成十进制整型常量。如12,-38等。(2)八进制整型常量:以数字0开头,其他位以数字0~7构成八进制整型常如012,-037等。
在C语言中,整型常量有十进制、八进制、十六进制三种进制表示方法,并且各种数制均可有正(+)负(-)之分,正数的“+”可省略。
(3)十六进制整型常量:以0X或0x开头(数字0和大写或小写字母x),其他位以数字0~9或字母a~f或A~F构成十六进制整型常量。如0x12,-0Xa9等。
如果在整型常量加上后缀L或l表示该常量为长整型常量,加上后缀U或u表示无符号整型常量。返回返回本节目录2.2.2常量(二)2.实型常量(1)小数表示法:它是由数的符号、数字和小数点组成的实型常量(注意:必须有小数点)。如-2.5、3.0、4.、.34等都是合法的实型小数形式。
(2)科学计数法:科学计数法也称指数法。它是由数的符号、尾数(整数或小数)、阶码标示(E或e)、阶符和整数阶码组成的实型常量。尾数不可缺省,阶码必须为整数。如-2.5E-3、3e5、34E-3等都是合法的指数形式。如-2.5E-3表示-2.5×10-3。
实型常量又称浮型常量。实型常量由整数部分和小数部分组成,有两种表示形式:小数表示法和科学计数法。它只能用十进制表示。
实型常量分为单精度、双精度和长双精度三种类型。实型常量如果没有任何说明,则表示为双精度常量,实型常量后加上F或f则表示单精度常量,实型常量后加上L或l则表示长双精度常量。
返回返回本节目录2.2.2常量(三)3.字符型常量(1)一般字符常量:一般字符常量是用单引号括起来的一个普通字符,其值为该字符的ASCII代码值。ASCII编码表见附录1。如’a’、’A’、’0’、’?’等都是一般字符常量,但是’a’和’A’是不同的字符常量,’a’的值为97,而’A’的值为65。
字符型常量是由一对单引号括起来的一个字符。它分为一般字符常量和转义字符。一个字符常量在计算机的存储中占据一个字节。(2)转义字符:C语言允许用一种特殊形式的字符常量,它是以反斜杠(\)开头的特定字符序列,表示ASCII字符集中控制字符、某些用于功能定义的字符和其他字符。如’\n’表示回车换行符,’\\’表示字符“\”。常用的转义字符见1.4.1中所叙。
如果在整型常量加上后缀L或l表示该常量为长整型常量,加上后缀U或u表示无符号整型常量。返回返回本节目录(4)存放的变量不同。字符常量可存放在字符变量或整型变量中,而字符串常量需要存放在字符数组中。字符变量和字符数组后续介绍。
2.2.2常量(四)4.字符串常量
字符串常量也称字符串,由一对双引号括起来(“”)的字符序列。字符序列中的字符个数称字符串长度,没有字符的字符串称为空串。如“a”、“12+3”等都是合法的字符串常量。字符串常量中的字符是连续存储的,并在最后自动加上字符’\0’(空字符,该字符在ASCII码值为0,也称NULL字符)作为字符串结束标志。如字符串“a”在计算机内存中占两个连续单元,存储内容为字符’a’和’\0’对于字符串常量和字符常量的区别是十分显著的,主要表现在以下4个方面:
(1)表示形式不同。字符常量以单引号表示,而字符串常量以双引号表示。
(2)存储所占的内存空间不同。字符常量在内存中只用1个字节存放该字符的ASCII码值。字符串常量在内存中,除了存储串中的有效字符的ASCII码值外,系统还自动在串后加上1个字节,存放字符串结束标志’\0’。
返回(3)允许的操作不同。字符常量允许在一定范围内与整数进行加法或减法运算,如’a’-32合法。字符串常量不允许上述运算,如“a”-32非法的。
返回本节目录(1)数据类型:C语言的合法数据类型。如例中的int、short、char、float、double等。
(2)变量名表:变量名是C语言合法的标识符。变量名表可以包含多个变量名,彼此之间使用逗号分开,表示同时定义若干个具有相同数据类型的变量,如:
floata,b;(3)变量定义语句可以出现在变量使用之前的任何位置。程序设计时不违背“先定义,后使用”的原则即可。
2.2.3变量及类型定义返回本节目录1.变量定义变量定义一般格式:数据类型变量名表;如:inta;对变量定义说明如下:
变量是指在程序执行过程中其值可以被改变的量。变量有三个基本要素:变量名、变量数据类型和变量的值。在C语言中,任何一个变量在使用之前都必须首先定义它的名字,并说明它的数据类型。也就是说,变量使用前必须先定义,即指定变量名,说明变量数据类型。变量定义的实质是按照变量说明的数据类型为变量分配相应空间的存储单元,在该存储单元中存放变量的值。
C语言中,变量使用时遵循“先定义,后使用”的原则。2.2.3变量及类型定义返回本节目录2.变量初始化及赋值
在【例2.1】中“s=pi*r*r;”语句是通过赋值运算符“=”将“pi*r*r”的值赋给变量s,即该语句实现了给变量s的赋值。所以,变量值可以通过初始化取得,也可以在定义后,通过给变量赋值的方法取得。
在【例2.1】中“inta=3;shortr=6;charc='a';floatpi=3.14;”的“=”是赋值运算符,用来给变量赋值。所以,以上四条语句都是在定义变量的同时给变量赋了值,称为变量的初始化。变量初始化是指定义变量同时,给变量一个初始值。2.3.2算术运算符及算术表达式
2.3.1运算符和表达式
2.3运算符及表达式
返回本章目录2.3.3关系运算符及关系表达式
2.3.4逻辑运算符及逻辑表达式
2.3.5条件运算符及条件表达式
2.3.6赋值运算符及赋值表达式
2.3.7逗号运算符及逗号表达式
2.3.8求字节运算符2.3.9类型转换
分类名称运算符算术运算符+、-、*、/、%、++、--关系运算符<、<=、>、>=、==、!=逻辑运算符&&、||、!位运算符<<、>>、~、|、^、&赋值运算符=及其扩展赋值运算符条件运算符?:逗号运算符,指针运算符*、&求字节数运算符sizeof强制类型转换运算符(类型)分量运算符.、->下标运算符[]其他函数运算符()2.3.1运算符和表达式这里介绍运算符和表达式的概念以及运算符的优先级和结合性问题。1.运算符返回本节目录C语言提供了13类,共计34种运算符。据运算符的运算对象的个数,C语言的运算符分为单目运算符、双目运算符和三目运算符,如单目++,双目<,三目?:等。运算符具体分类情况见下表所示。2.3.1运算符和表达式2.表达式3.运算符的优先级4.运算符的结合性返回本节目录
用运算符将操作对象连接起来、符合C语法规则的式子称为表达式。表达式因运算符种类也可分为各种表达式,如算术表达式、关系表达式、赋值表达式等,每一个表达式也都具有一定的值。如:a=b+c
运算符的优先级是指不同的运算符在表达式中进行运算的先后次序。如,算术运算符*、/的优先级高于+、-的优先级。在【例2.2】中“c=a>b?a:b;”语句中运算符按优先级由高到低排列顺序为“>”、“?:”、“=”。
当一个运算对象的两侧的运算符的优先级相同时,运算的结合方向称为结合性。运算符的结合性分为左结合和右结合两种。在C语言中,运算对象先与左面的运算符结合称左结合,如+、-、*、/的结合方向为自左向右;运算对象先与右面的运算符结合称右结合,如单目运算符++、--的结合方向是自右向左。2.3.2算术运算符及算术表达式
算术运算符分基本算术运算符和自增、自减运算符。1.基本算术运算符
基本算术运算符包括加法(+)、减法(-)、乘法(*)、除法(/)和求余(%)。后三种运算符优先级高于前两种,它们都是左结合性。对于运算符/和%有如下说明:(1)若除法运算符的运算对象均为整型数据,则结果为其商的整数部分,舍去小数部分。如13/7的结果为1。若运算对象中有一个为负值,则舍入的方向是不固定的。如,-13/7在有的机器上得到结果是-1,有的机器上得到结果是-2,但多数机器采取“向零取整”方法,即13/7=1,-13/7=-1,取整后向零靠拢。返回本节目录(2)求余运算符的运算对象必须是整型数据,运算结果的符号与被除数的符号相同,如,-13%7运算结果为-6,13%-7运算结果为6,-13%-7运算结果为-6。2.3.2算术运算符及算术表达式2.自增、自减运算符
自增(++)和自减(--)运算符是单目运算符,其功能是使运算对象(变量)的值增1或减1。它们既可以作前缀运算符(位于运算对象的前面),如++i,--i;也可以作后缀运算符(位于运算对象的后面),如i++,i--。前缀和后缀运算的数据处理方法有明显的差异。对于前缀形式表示在用该表达式之前先使变量值增(减)1;对于后缀形式表示在用该表达式的值之后使n的值增(减)1。++j,--j在使用j之前,先使j的值加(减)1。j++,j—
在使用j之后,使j的值加(减)1。
在【例2.2】中“inti=3;printf("i=%d\n",i++);”,i++是后缀形式,则先计算表达式的值,其值为当前i值,因此,输出i=3,然后使i自增1,i值为4。所以,语句“printf("i=%d\n",i);”输出的结果是i=4。返回本节目录
自增或自减运算符在使用时,需要注意以下几点:(1)运算符的操作对象,只能是变量,而不能作用于常量或表达式。运算符的优先级高于基本算术运算符,结合性是“自右向左”右结合。(2)i++,遵照右结合原则,它相当于-(i++),而不相当于(-i)++形式。2.3.3关系运算符及关系表达式
关系运算符是对两个操作对象进行大小比较的运算符,是逻辑运算的一种简单形式。用关系运算符将两个表达式连接起来的符合C语法规则的式子称为关系表达式。关系表达式的运算结果是一个逻辑值,即“真”或“假”。在C语言中关系运算结果为真,以整数“1”表示,结果为假,以整数“0”表示。
C语言中的关系运算符共有六种,它们是:
> < >= <= != ==
大于小于 大于等于小于等于 不等于 等于
关系运算符的优先级低于算术运算符的优先级,且等于(==)和不等于(!=)的优先级低于另外四种运算符的优先级。关系运算符的结合性是左结合性。在【例2.2】实例“inta=5,b=7;”和“c=a>b?a:b;d=a<=b&&i;”中a>b值为0,a<=b值为1。返回本节目录2.3.4逻辑运算符及逻辑表达式返回本节目录
参与逻辑运算的逻辑量“真”或“假”的判断原则是:以0代表“假”,以非0代表“真”。即将一个非零的数值认作“真”,将零值认作“假”。逻辑运算的结果逻辑值只有两个,“真”和“假”,它们分别用“1”和“0”表示。
C语言中提供的三种逻辑运算符及运算法则见下表所示:
逻辑运算符中“&&”和“||”低于关系运算符,“!”高于算术运算符。在【例2.2】程序实例中“d=a<=b&&i;”先计算“a<=b”为真值为1,再计算“1&&i”,两个操作对象均非零为“真”,故结果为“真”,值为1。再将该值1赋给变量d。在处理逻辑表达式时应注意以下几点:
运算符运算名称运算法则结合性&&逻辑与当两个操作对象都为“真”时,运算结果为“真”,其他情况运算结果都为“假”。左结合||逻辑或只有当两个操作对象都为“假”,运算结果才为“假”,其他情况运算结果都为“真”。左结合
!逻辑非当操作对象为“真”时,运算结果为“假”;当操作对象为“假”时,运算结果为“真”。右结合2.3.4逻辑运算符及逻辑表达式返回本节目录
在处理逻辑表达式时应注意以下两点:
(1)C语言编译系统在给出逻辑运算结果时,以0代表“假”,以1代表“真”。但在判断一个逻辑量“真假”时,以非0表示“真”,以0表示“假”。例如:当a=5.4,b=5,c=’a’时,!a,!b,!c的值均为“假”,即为0。a&&c的值为1,因为x和y均为非0。(2)在进行逻辑运算时,逻辑表达式运算到其值完全确定时为止。例如:运算表达式(a=3)&&(a==5)&&(a=6)时,由于a=3之后运算a==5的值为假,所以就不再进行a=6的运算了,因此a的值仍为3,而整个逻辑表达式的值为0。
使用条件表达式时,应注意以下两点:(1)条件运算符优先级高于赋值运算符。如a=b>0?b:-b;相当于y=(b>0?b:-b),功能是将b的绝对值赋给a。(2)条件运算符结合性是右结合。如b>0?1:b<0?-1:0;相当于b>0?1:(b<0?-1:0)。2.3.5条件运算符及条件表达式
条件运算符是“?:”,是C语言中唯一的三目运算符,用条件运算符将两个表达式连接起来的符合C语法规则的式子称为条件表达式。条件表达式的一般形式:
表达式1?表达式2:表达式3;
操作过程:先计算表达式1的值,若为“真”,则计算表达式2的值,整个条件表达式的值就是表达式2的值;若表达式1的值为“假”,则计算表达式3,整个条件表达式的值就是表达式3的值。
条件运算符优先级低于逻辑运算符,其结合性是右结合。在【例2.2】程序实例中“a=5,b=7;c=a>b?a:b”,先计算a>b值为假,则条件表达式值取b的值为7。因此,c值为7。返回本节目录C语言允许在赋值运算符“=”之前加上其他运算符,构成复合运算符。在“=”之前加上算术运算符,则构成算术复合赋值运算符;在“=”之前加上位运算符,则构成位复合赋值运算符。象+=、-=、*=等。使用如,a+=b-c等价于a=a+(b-c),a%=b-c等价于a=a%(b-c)。
2.3.6赋值运算符及赋值表达式
赋值运算符包括简单赋值运算符和复合赋值运算符,复合赋值运算符又包括算术复合赋值运算和位复合赋值运算符(位运算在第8章介绍)。由赋值运算符将操作对象连接起来符合C语法规则的式子称为赋值表达式。
1.简单赋值运算符及其表达式
2.简单赋值运算符及其表达式
赋值运算符是“=”,其作用是将赋值运算符右侧的表达式的值赋给其左侧的变量。在【例2.2】程序实例中“i=3,a=5,b=7;c=a>b?a:b;d=a<=b&&I;d=(c,d=c); ”都是将“=”右侧的数值或表达式的值赋给“=”左侧的变量。赋值运算符的优先级低于条件运算符,其结合性是右结合。如:a=b=c=a>b?a:b;相当于a=(b=(c=(a>b?a:b)));
值得注意的是:赋值运算符运算对象中的左侧对象一定是变量。如:a=b-c=5;相当于a=((b-c)=5);,由于表达式中出现将数值5赋给b-c表达式,因此,该表达式是非法的。返回本节目录2.3.7逗号运算符及逗号表达式
逗号运算符是“,”,它的优先级低于赋值运算符,是左结合性。用逗号运算符将若干个表达式连接成一个逗号表达式。一般形式如下:
表达式1,表达式2,……表达式n
逗号表达式的操作过程是:先计算表达式1,再计算表达式2,……,最后再计算机表达式n,而逗号表达式的值为最右边表达式n的值。如:
a=4.5,b=6.4,34.5-20.1,a-b
该逗号运算表达式,它由四个表达式结合而成,从左向右依次计算,逗号表达式的值为a-b的值,即-1.9。在【例2.2】程序实例中“d=(c,d=c);”是将逗号表达式c,d=c的值赋给变量d。值得注意的是,逗号运算符是C语言所有运算符中优先级最低。如:a=10,20;不同于a=(10,20);,前者a的值为10,表达式的值为20,后者a的值为20,表达式的值也为20。
返回本节目录2.3.8求字节运算符
C求字节运算符是sizeof,它用于计算变量或某种类型的量在内存中所占的字节数。用法有两种:
1.sizeof表达式2.sizeof(类型名)
功能是计算出表达式计算结果所占用内存的字节数。如:在【例2.1】程序实例中“printf(”int:%d,short:%d,char:%d,float:%d,double:%d\n“,sizeof(a),sizeof(r),sizeof(c),sizeof(pi),sizeof(s));”就是输出变量a,r,c,pi,s所占的内存字节数。
功能是计算出某种类型的量存储时所占用内存的字节数。如:
sizeof(float)计算单精度实型数据在内存中所占的字节数,结果为4。
返回本节目录返回本章目录3.1.2顺序结构语句3.1.3程序实训3.1.1顺序结构的C程序实例3.1顺序结构程序设计3.1.1C程序实例返回本节目录C程序实例【例3.1】编程实现:输入一个长方形的二边长,求长方形的面积并输出。/*程序名为l3_1.cpp。*/#include"stdio.h"main(){floata,b,s;scanf("%f%f",&a,&b);s=a*b;printf("Theareaofrectangleis%5.2f.\n",s);}
返回本节目录程序运行情况如下:输入:3.04.0<CR>输出:Theareaofrectangleis12.00.这个程序属于顺序结构,程序是按照书写的顺序自上而下一步步执行,程序中的每一条语句都被执行一次,且仅能被执行一次。【例3.1】编程3.1.2顺序结构语句1C语言的顺序结构语句可以分为四大类:1.表达式语句表达式的后面加一个分号就构成了一个语句,例如:sum=a+b;。事实上,C语言中有使用价值的表达式语句主要有3种:(1)赋值语句。例如:sum=a+b;(2)自动增1、减1运算符构成的表达式语句。例如:i++;(3)逗号表达式语句。例:x=1,y=2;2.空语句语句仅有一个分号“;”,它表示什么也不做。一般和后面章节所讲循环语句结合使用起到延时作用。3.复合语句由"{"和"}"把一些变量定义和执行语句组合在一起,称之为复合语句,又称语句块。复合语句的语句形式如下:{语句1;语句2;…;语句n;}返回本节目录返回本节目录例如:{inta=0,b=1,sum;sum=a+b;printf("%d",sum);}【注意】与C语言中的其他语句不同,复合语句不以分号作为结束符,若复合语句的"}"后面出现分号,那不是该复合语句的组成成分,而是单独的一个空语句。在复合语句起始部分可以有变量定义,如:"inta=0,b=1,sum;",也可以没有。复合语句的"{}"内可能会有多个语句,但在语法上把它整体上视为一条语句看待。4.函数调用语句由一个函数调用加上一个分号组成一个语句,如:
scanf("%d%d",&a,&b);printf("a=%d,b=%d\n",a,b);3.1.2顺序结构语句2C程序实例【例3.2】由键盘输入两个整数给变量a和b,然后输出a和b,在交换a和b中的值后,再输出a和b,验证两个变量中的数值是否正确地进行了交换。
/*程序名为l3_2.cpp。*/#include"stdio.h"main(){inta,b,t;printf("Enteraandb:\n");scanf("%d%d",&a,&b);printf("a=%d,b=%d\n",a,b);t=a;a=b;b=t;printf("a=%d,b=%d\n",a,b);}程序运行情况如下:Enteraandb:123456<CR>a=123,b=456a=456,b=123返回本节目录3.1.3程序实训【例3.2】返回本节目录注意:在程序中交换两个变量a和b的值,不可以简单地用:a=b;b=a;两条语句来实现。假设a和b的值分别为23和78,赋值语句a=b;将使a的值变为78,接下来的b=a;使b的值变为78,这样,a和b的值最终都变为78。所以在本例中引入了中间变量t,用来临时存放a的值,这样才能完成变量a和b的正确交换。【例3.3】输入一个double类型的数,使该数保留小数点后两位,对第三位小数进行四舍五入处理,然后输出此数,以便验证处理是否正确。/*程序名为l3_3.cpp。*/#include"stdio.h"main(){doublex;printf("Inputx:\n");scanf("%lf",&x);3.1.3程序实训【例3.3】3.1.3程序实训【例3.3】返回本节目录printf("(1)x=%f\n",x);/*将x输出*/
x=x*100;x=x+0.5;x=(int)x;x=x/100;/*将x扩大100倍,加上0.5之后取整,再缩小100倍*/
printf("(2)x=%f\n",x);/*将四舍五入后的x输出*/}程序运行情况如下:Inputx:3.14159<CR>则输出的结果为:(1)x=3.141590(2)x=3.1400003.1.3程序实训【例3.4】返回本节目录【例3.4】从键盘上输入一大写英文字母,要求改用相应的小写字母输出。/*程序名为l3_4.cpp。*/#include"stdio.h"main(){charc1,c2;scanf("%c",&c1);printf("Theuppercaseis%c.\n",c1);c2=c1+'a'-'A';printf("Thelowercaseis%c.\n",c2);}程序运行时:输入:B<CR>输出:TheuppercaseisB.Thelowercaseisb.3.2选择结构程序设计3.2.1选择结构的C程序实例3.2.2if语句3.2.3switch语句3.2.4程序实训
返回本章目录3.2.1选择结构的C程序实例
返回本节目录
【例3.5】请输入两个整数a,b,比较a+b和a×b哪个大,输出判断结果。
/*程序名为l3_5.cpp。*/#include"stdio.h"main(){inta,b,s1,s2;printf("请输入两个整数a,b:");scanf("%d,%d",&a,&b);s1=a+b;s2=a*b; /*求两个数的和、积*/
if(s1>s2)printf("(a+b)>(a*b)/n");/*语句A*/
elseprintf("(a+b)<=(a*b)\n"); /*语句B*/}运行结果为:请输入两个整数a,b:2,3<CR>(a+b)<=(a*b)在这个程序中使用了if分支语句,它不像前面的程序那样,按照语句的书写顺序一步步执行下去,而是根据所给条件的真假,选择两者其中之一执行。该程序执行的过程是:比较两数的和与积,如果s1>s2,则执行语句A(跳过语句B不执行),否则,就跳过语句A执行语句B。可见if语句在程序中起到了改变语句执行顺序的作用。if语句就是我们在下一节中要介绍的条件分支语句。3.2.1选择结构的C程序实例结果
返回本节目录3.2.2
if语句1.if语句的一般形式返回本节目录2.if-else中的复合语句3.非关系、非逻辑表达式构成的条件表达式4.if语句的嵌套1.if语句的一般形式1
1.if语句的一般形式:if语句有两种形式:(1)不含else子句的if语句语句形式如下:if(<表达式>)<语句1>例如if(a<b){t=a;a=b;b=t;}其中,if是C语言的关键字,表达式两侧的圆括号不可少,最后是一条语句,称为if子句。如果在if子句中需要多个语句,则应该使用花括号把一组语句括起来组成复合语句,这样在语法上仍满足"一条语句"的要求。执行过程:首先计算紧跟在if后面一对圆括号中的表达式的值,如果该表达式的值为非零(“真”),则执行其后的if子句,然后去执行if语句后的下一个语句。如果该表达式的值为零(“假”),则跳过if子句,直接执行if语句后的下一个语句。返回3.2.2目录1.if语句的一般形式2
(2)含else子句的if语句语句形式如下:if(<表达式>)<语句体1>[else<语句体2>]执行过程:首先计算<表达式>的值,如果该表达式的值为非零("真"),则执行<语句体1>,如果该表达式的值为零("假"),则跳过<语句体1>,直接执行<语句体2>,两者执行其一后再去执行if语句后的下一个语句。返回3.2.2目录1.if语句的一般形式实例【例3.6】求分段函数的值,如果x≥0,y=2x+1,否则,
y=0。#include"stdio.h"main()/*程序名为l3_6.cpp。*/{intx,y;/*变量y存放f(x)的值*/
printf("请输入x的值:");
scanf("%d",&x);if(x>=0)y=2*x+1;elsey=0;printf("当x=%d时,f(x)=%d",x,y);}返回3.2.2目录1.if语句的一般形式实例运行结果:请输入x的值:3<CR>
当x=3时,f(x)=7因为输入x=3,那么
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度购物中心水电维修服务合同(1000字)6篇
- 二零二五年度冷链物流食品供应合同3篇
- 二零二五年度环保材料买卖合同样本详述3篇
- 二零二五年度绿色建筑文明施工与环境保护一体化协议书3篇
- 二零二五年度行政上诉状编制要点与官方格式3篇
- 二零二五年度企业委托高校培养博士研究生技术合作协议3篇
- 二零二五年度互联网医疗健康品牌授权协议3篇
- 二零二五年度企业股权激励协议(限制性股权)6篇
- 二零二五年度农产品销售承包协议
- 2025版科技研发园区物业管理权转让与技术创新服务合同3篇
- 上海市2024年中考化学真题(含答案)
- 安徽省淮南四中2025届高二上数学期末统考模拟试题含解析
- 保险专题课件教学课件
- 牛津上海版小学英语一年级上册同步练习试题(全册)
- 室上性心动过速-医学课件
- 建设工程法规及相关知识试题附答案
- 中小学心理健康教育课程标准
- 2024年山东省第三届中小学生海洋知识竞赛试题及答案(初中组)
- 四年级上册脱式计算400题及答案
- 2024年湖南高速铁路职业技术学院高职单招(英语/数学/语文)笔试历年参考题库含答案解析
- 《活着》读书分享课件
评论
0/150
提交评论