




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+程序设计(part 1),南京大学软件学院郑滔 Tel: 506 Room: 623,Ole-Johan Dahl Kristen Nygaard,Norwegian computer scientist Turing Award in 2001 http:/heim.ifi.uio.no/olejohan/ http:/heim.ifi.uio.no/kristen/,Father of Simula67 Father of OO programming,E.W.Dijkstra Niklaus Wirth,Swiss computer scientist Turing Award in
2、1994 http:/www.inf.ethz.ch/personal/wirth/,Design PASCAL、Modula2、Oberon,Netherland computer scientist Chair of Computer Sciences at the University of Texas at Austin from 1984 until 2000. Turing Award in1972 /users/EWD/,“A Case against the GO TO Statement” Algol 68,Dennis Ritc
3、hie Ken Thompson,American computer scientist Turing Award in 1983 (工程师获奖) http:/cm.bell- http:/plan9.bell-,Father of C Co-inventing Unix,Bjarne Stroustrup,Ph.D, University of Aarhus, Denmark College of Engineering Chair in Computer Science Professor at Texas A typedef int INT ; C+是强类型语言 要求程序设计者在使用之前
4、对数据的类型进行声明,表达式,操作数、操作符和标点符号组成的序列,表示一个计算过程 优先级a+b*c 结合性a+b-c 求值次序(a+b)*(a-b)与编译系统有关 类型转换约定 int x=10; float y=2.0; x*y 表达式种类 算术表达式 关系和逻辑表达式 赋值表达式 逗号表达式 字位运算符表达式 操作符可重载,表达式,计算与类型 相同类型的两个操作数运算后,其结果仍然为该类型的值 类型对计算的限制 类型具有取值范围,超出取值范围的值没有意义 混合类型计算和类型转换 转换总是朝表达能力更强的方向,并且转换总是逐个运算符进行 自动转换(隐式类型转换 coersion) 显式转换
5、(强制类型转换 casting),表达式,赋值表达式 左值右值表达式 左值:可以出现在赋值表达式左部的表达式, 具有存放数据的空间 类型不同时,先计算右值表达式的值,再转换为左值类型,然后赋值 算术表达式 增量和减量操作符 前增量(前减量) +a ( -a ) 前增量的结果是左值 后增量(后减量) a+ ( a- ) 提高编译结果的执行效率,表达式,条件运算符表达式 ? : 唯一的三目运算符 只计算一个运算分量 如果 和的值类型相同,且均为左值,则该条件运算符表达式为左值表达式 可嵌套 sign(x) x 0? 1: x = 0? 0 : -1 就近原则,表达式,逗号表达式 , 的值作为该逗号
6、表达式的值 int a, b, c; d = (a = 1, b = a+2, c = b+3); cout 为左值,则该逗号表达式为左值,表达式,字位运算符表达式 对整型数二进制位(bit)的操作,将整型数看作二进制序列 取反 、与 c = a*b + +b; 求值次序使交换率失去作用 int a=3; c = a+ * +a; 副作用的危害 破坏了可移植性 降低了程序的可读性 消除副作用,语句,表达式语句 IO语句 cin、cout iostream.h 、可重载 控制流语句 顺序、选择、重复,iostream,stdio.h,语句,switch switch 后必须是整型表达式,case
7、 后必须是整型常量表达式 值各不相同 各个case(包括default)出现的次序可以任意 case 仅起标号作用,不改变执行顺序 break 多个case可以公用一组语句 通常可以和if语句配合使用,enum,函数,原则 函数定义不允许嵌套 先定义后使用 函数的执行机制 建立被调用函数的栈空间 保存调用函数的运行状态和返回地址 参数传递 值传递 (call by value) 引用传递 (call by reference) 将控制转交被调函数,Call by name Call by value-result,Runtime Environment,函数,函数原型 遵循先定义后使用原则 自
8、由安排函数定义的位置 标准库函数的函数原型都在头文件(.h)中提供,用#include 指令包含这些原型文件 用户自定义的函数必须在源代码中说明函数原型 函数原型是一条语句 函数原型不必含有参数的名字,只需含有参数的类型 函数原型必须和函数定义在返回值类型、函数名和参数表完全一致,编译器在遇到函数调用时,需检查函数原型,函数,函数重载 原则 一组重载函数,相互间至少在参数个数、类型或顺序上有所不同 返回值类型不作为区别重载函数的依据 匹配重载函数的顺序 严格 内部转换 用户定义的转换 void f(long);void f(double); f(10); ambiguous,Name mang
9、ling extern “C”,函数,带默认参数的函数 默认参数的声明 函数原型中给出 先定义的函数中给出 默认参数的顺序规定 从右到左,中间不能间断 默认参数与函数重载 void f(int); void f(int, int=2); ambiguous,函数,内联函数inline 目的 提高程序的可读性 提高程序的运行效率 对象 使用频率高的小段代码 实现方法 编译系统将为 inline 函数创建一段代码,在每次调用时,用相应的代码替换 限制 非递归 由编译系统控制,函数,明智地运用inlining(Use inlining judiciously) 缺点 增大目标代码(object co
10、de) 病态的换页(thrashing) 降低指令快取装置的命中率(instruction cache hit rate) 只是对编译系统的提示 Big/complex/ Function pointer Compiler (outlined) static function recompile/link vs rebuild,作用域与生命期,程序的局部性原则 程序的内存结构 Code、Global data、Stack、Heap Scope 全局变量 static 局部变量 静态局部变量 static(生命期),程序结构,程序结构 逻辑结构 物理结构 多个源文件组成 只能其中一个 文件含有主
11、函数 工程文件 外部函数 外部变量 extern,main,f1,f2,fn,cpp1,cpp2,cpp3,obj1,obj2,objn,Compiler,exe,Lib,Linker,程序结构,Static global variable static 防止名冲突 值可靠 Static function 限制使用 对函数定义的补充static Constant 缺省为 static 开放 extern,程序结构,标识符在程序中有效的范围 程序级 外部量、外部函数 文件级 静态函数、静态全局量 函数级 标号、形式参数、局部量 块级 可见性 分析在某一位置标识符的有效性 : 引用全局变量 nam
12、espace using namespce,int global;/程序级 void f() /程序级 static float f; /文件级 static void g() /文件级 void main() int x; /函数级 if (x0) float x=0; /块级 ,多文件结构,Header File 声明的部分 宏定义 包含指令 类型声明 函数声明 内联函数 常量定义 变量声明,编译预处理,包含 #include “” 宏定义 define 字符串字符串 undef宏名字 带参数的宏 条件编译 #if#else#elif #endif#ifdef#ifndef 设定编译器状态
13、 #pragmawarning(disable:4101) once,数组,特征 相同数据类型 有序 连续存储0n-1 一维数组 类型定义 函数参数 仅传递地址 元素个数需通过参数显示给出,不能通过sizeof取得 字符串,数组,多维数组 定义T Ac1c2 存储组织 参数传递 只能缺省第一维 降维处理,typedef T A1c2; A1 Ac1;,数组,#include int maximum(int grade, int num) int max = 0; for (int k=0;k max) max = gradek; return max; void main() int A24
14、= 68,69,70,71 , 85,86,87,89; cout “the max grade is” maximum( ); ,sizeof(A)/sizeof(A00),maximum(,A0,2*4,结构和联合,struct 赋值同类型 align 参数传递 union 共享存储空间,_declspec(align(8),结构和联合,例:定义一个能存储100个图形的数组变量,其中的图形可以是:直线、矩形、圆。 FIGURE figures100; struct Line double x1, x2, y1, y2; struct Rectangle double left, top,
15、right, bottom; struct Circle double x, y, r; ,enum FIGURE_TYPE LINE, RECTANGLE, CIRCLE; struct Line struct Rectangle FIGURE_TYPE t ; FIGURE_TYPE t; double x1, x2, y1, y2; double left, top, right, bottom; ; ; struct Circle FIGURE_TYPE t; double x, y, r; ; union FIGURE FIGURE_TYPE t; Line line; Rectan
16、gle rect; Circle circle; FIGURE figures100;,结构和联合,void draw(FIGURE figure)多态性 switch ( figure.t ) case LINE: draw_line(figuresi.line); break; case RECTANGLE: draw_rectangle(figuresi.rect); break; case CIRCLE:draw_circle(figuresi.circle); break; void main() InputF( figures, 100 ); for (int i=0;i100;i
17、+) draw(figuresi); ,void input (Figure fig, int size) int t; for (int k=0; k t; switch (t) case LINE: figk.type = LINE; cin figk.line.x1 figi.line.y1 figk.line.x2 figi.line.y2; break; case RECTANGLE: case CIRCLE: . ,指针,处理地址信息、动态数据 指针定义与基本操作 指针与函数 指针与数组 指针与结构 多级指针 动态变量,指针定义与基本操作,定义 格式 * int *p; /p为一个
18、指针变量 语义 指针变量的值是另外一个变量的内存地址。 如:上述指针变量 p 的值为某一整型变量的内存地址。 说明 当在一个定义(或声明)中定义(或声明)多个指针变量时,每个指针变量前都要有* int *p,*q; /p和q均为指针变量 int *p, q; /p为指针变量,q为整型变量,指针定义与基本操作,也可以先用 typedef 定义一个指针类型,然后再用该指针类型定义指针变量,如: typedef int* Pointer; Pointer p,q; / p和q均为指针变量 取地址操作符(,9,x,0X5A12,p,0X7B77,0X5A12,1000,指针定义与基本操作,当一个指针变
19、量的值为另一个变量的地址时,通常也说成:该指针指向另一个变量,如:指针变量p指向整型变量x,可用下面的图示法表示: Pointer literal (0 / NULL) 不指向任何对象 指针变量的初始化 区别 * 的三种用途 乘法运算符 指针定义(或声明)符 取指针所指向的值(间接访问),p,1000,x,指针定义与基本操作,指针的运算 赋值 对于一个指针变量,可以把一个同类型的指针值赋给它。 int x; double d; int *p, *q; p = ,指针定义与基本操作,加上或减去一个整型值 一个指针值可以与一个整型值进行加或减运算,结果为同类型的指针值。 int x; int *p
20、; p = p + 1; p = /q的值加8 ( sizeof(double) ),指针定义与基本操作,同类型的指针值相减 同类型的指针值可以相减,结果为整型值。 int *p, *q; int offset; offset = p - q; int a10; int *p, *q,offset; p = /结果值为 3,指针定义与基本操作,两个同类型的指针值比较 两个同类型的指针值可以进行等于(=)和不等于(!=)比较,一般不进行大于(,=)和小于(,=)比较。 指针值的输出 int x=1; int *p= /输出p指向的字符,即:A cout (void *)p /输出p的值,指针定义
21、与基本操作,void * 只存放地址信息 void *p; 任何其它类型的指针均可以赋值给void指针 void *any_pointer; int x; double y; any_pointer = 不能进行指针运算和间接引用(*),若要进行指针运算或间接引用,必须作强制类型转换。 *any_pointer /error *(int *)any_pointer) /OK *(double *)any_pointer) /OK,指针定义与基本操作,例:将某指针所指向的一块内存清零。 void memset ( void *pointer, unsigned size) char *p = (
22、char *)pointer; for (int k=0;ksize;k+) *p+ = 0; void memset(void *, int, unsigned); void memcpy(void *, void *, unsigned size);,指针定义与基本操作,常量指针与指针常量 常量指针const * const int x=0; int y; const int *p; /p为指向常量的指针(常量指针) int *q; p = /OK! Why?,constant,P,variable,x(常量),const_cast,指针定义与基本操作,指针常量 * const 必须在定义
23、时初始化 int x, y; int * const p = /Ok,variable,P(常量),constant,x,const int * const p; ?,指针与函数,指针作为行参 提高传输效率 函数副作用 常量指针 Function Pointer 指向函数的指针,double f(int x) int g() void main() double (*fp) (int); / typedef double (*FP)(int); / FP fp; fp = f; fp = /Error ,函数指针,函数参数 编写函数,使其能计算任意一元函数在某区间上的定积分 #include
24、double integrate(double (*f)(double),double a, double b) (*f)(x), a , b, double my_func(double x) void main() integrate(sin,0,1); integrate(cos,1,2); integrate(my_func,1,10); ,示例,sort,int scompare(const void *elem1, const void *elem2) TStudent *p1 = (TStudent *)elem1; TStudent *p2 = (TStudent *)elem
25、2; return strcmp(p1-name,p2-name); ,void MySort(void *base, unsigned num, unsigned width, int (*compare)(const void *elem1, const void *elem2) char *A = (char *)base; char *tmp = (char *)malloc(width); for (unsigned i=1;i0) /Aj Aj+1) memcpy(tmp,A+j*width,width); /int tmp = Aj; memcpy(A+j*width, A+(j
26、+1)*width,width);/Aj = Aj+1; memcpy(A+(j+1)*width,tmp,width); /Aj+1 = tmp; free(tmp); ,TStudent student = ; int num = sizeof(student)/sizeof(student0); int width = sizeof(student0); MySort(student,num,width,icompare);,指针与数组,数组元素操作 下标表达式 访问效率 数组元素的指针表示法 一维数组 多维数组,int b2010; / typedef int A10; A b20;
27、int *q; q = bij *(*(b+i)+j) *(*(p+i)+j) pij,int a10; int *p; int i; p = /数组名表示其首元素的地址,是常量! (int *const) ai *(a+i) *(p+i) pi char s28 = “C+”, “PASCAL”, “FORTRAN”;,s1,C + + 0,P A S C A L 0,F O R T R A N 0,s2,指针数组,函数main的参数 带参数和返回值的函数main的原型为 int main(int argc, char *argv, char *env) argc: 参数个数 argv: 命
28、令行参数 env: 环境参数。 示例 c: copy file1 file2 操作系统将启动copy程序,调用其main函数, argc : 3 argv: copy、 file1、 file2 env:,#include #include #include void MyFormat(char *lpszFormat, .) va_list marker; va_start(marker,lpszFormat); for (int i=0;i4;i+) cout va_arg(marker,double) endl; va_end(marker); void main() MyFormat(
29、“test %f %f %f %f test_end,1.1,2.2,3.3,4.4); ,/platform : x86 typedef char * va_list; #define _INTSIZEOF(n) ( (sizeof(n) + sizeof(int) - 1) /pp为指针变量,指向另一个指针 /变量(int *) int x = 2, y = 8; int *p p = 指针变量必须初始化或赋值,否则将会导致运行时刻的严重错误,多级指针,编写一个函数,交换两个字符串 void swap(char *p1, char *p2) char *tmp = *p1; *p1 = *
30、p2; *p2 = tmp; void main() char p18 ; strcpy(p2, abcd“); char p28 ; strcpy(p2, 1234“); cout p1 p2 endl; swap( ,动态变量,动态变量 编译时刻无法确定 在程序运行时刻,动态产生、消亡 通过指向动态变量的指针变量来实现的 分配在程序的堆区(heap) 局部变量也是动态产生、消亡,但在程序运行前,编译程序已经知道它们的存在 动态变量与C+中的静态(static)变量属于不同的范畴,动态变量是程序设计中的概念(与语言无关),static是C+语言中的概念。,动态变量,动态变量的产生 new n
31、ew ,int *p = new int10; int (*p2)5 = (int (*)5)p; for (int i=0;i10;i+) pi = i+1; for (int j=0;j2;j+) for (int k=0;k5;k+) cout p2jk ; cout endl; ,typedef int i5Array 5; void main() i5Array *p = new i5Array 2; for (int j=0;j2;j+) for (int k=0;k5;k+) pjk = (j*5)+(k+1); ,动态变量,动态变量的产生 库函数 malloc void *ma
32、lloc(unsigned int size) int *p,*q; p = (int *)malloc(sizeof(int); /new int q = (int *)malloc(sizeof(int)*20); /new int20 new与malloc的区别 new自动返回相应类型的指针,malloc 要作强制类型转换。 如果创建的是动态对象,new 会去调用相应类的构造函数,malloc 则否 new或malloc为动态变量申请空间时,必须在判断申请的空间有效的情况下,才能使用,动态变量,动态变量的消亡 动态变量不会自动消亡,在程序运行期间,如果不再需要某个动态变量,应显式地使之消
33、亡,否则将造成 memory leak 用new 产生的动态变量,用 delete 使之消亡; 用 malloc 产生的动态变量,用 free 使之消亡 delete ,cookie,动态变量的应用,数据结构 链表(单、双)栈、队列 树、图 结点的定义 struct NODE int content; NODE *next; ; NODE *head=NULL;,单链表,结点的插入 产生一个新结点: NODE *p = new NODE; p-content = some_int_value; p-next = NULL; 如果链表为空 head = p; 插在表头 p-next = head; head = p;,单链表,如果插在表尾 NODE *q = head; while (q-next ) q = q-next; q-next = p; 插在链表中某一个结点(a)的后面 NODE *q = head; while (q ,单链表,如果插在链表中某一个结点(a)的前面,则: NODE *q1=NULL, *q2=head; while (q2 ,guard node,单链表,结点的删除 (假设要删除的结点的值为a
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 紧固件销售与市场拓展考核试卷
- 幕墙施工中的精细化管理考核试卷
- 原油加工过程质量控制考核试卷
- 纺织品企业绿色供应链与环保措施考核试卷
- 生命体征测量技术
- 5-11序列信号发生器1-分析与设计
- 1-6码制-二-十进制码
- 小学一年级下册数学期末考试试卷及答案
- 2025年北京大兴区中考一模物理试卷试题(含答案详解)
- 统编版语文五年级下册第14课《刷子李》精美课件
- 山东省济宁市邹城市2024-2025学年高一下学期4月期中考试政治试题(含答案)
- 金华兰溪市卫健系统普通高校招聘医学类笔试真题2024
- 2025年浙江省杭州市萧山区中考一模数学模拟试卷(含详解)
- 化工企业安全演练计划
- 2025年03月国家粮食和物资储备局直属联系单位(60名)笔试历年典型考题(历年真题考点)解题思路附带答案详解
- 2025年北师大版中考生物必背考点复习提纲
- 小学创建“五好”学校关工委实施方案
- 2022可调节负荷并网运行与控制技术规范+第4部分-数据模型与存储
- 《食品生产经营企业落实食品安全主体责任监督管理规定》解读与培训
- DB15T 3516-2024野生动物救护站建设规范
- 2025-2030中国内联pH传感器行业市场发展趋势与前景展望战略研究报告
评论
0/150
提交评论