今日学习札记--C++程序设计2(11.3)
2015-11-04 10:14
225 查看
1. 函数
- 函数的执行机制
1) 建立被调用函数的栈空间
2) 参数传递
2.1) 值传递(call by value)
2.2) 引用传递(call by reference)
3) 保存调用函数的运行状态
4) 将控制转交被调函数
- 函数重载原则
# 名同,参数不同(个数、类型、顺序)
# 返回值类型不作为区别重载函数的依据
- 默认参数
# 默认参数的声明
1) 函数原型中给出
2) 先定义的函数中给出
# 默认参数的顺序
1) 右 ->左
2) 不间断
- 内联函数inline
#目的:提高可读性,提高效率
#对象:使用频率高的小段代码
#实现方法:编译系统将为inline函数创建一段代码,在每次调用时,用相应的代码替换
#限制:非递归
#缺点:增大目标代码(object code)
病态的换页(thrasshing)
降低指令快取装置的命中率(instruction cache hit rate)
例子:inline int ascii(char a)
{ return a;
}
int main(int argc, char *argv[])
{
int i =0;
int r =0;
r = ascii('1');
printf("r=%d\n",r);
return 0;
}
2. 程序组织
- 程序结构
1) 逻辑结构
2) 物理结构(多个源文件相减,main唯一)
3) 工程文件(外部函数、外部变量)
- namespace:解决全局变量/函数的命名冲突?
namespace L
{
int k;
void f(int);
...
}
例1:using L::k;
using L::f;
k =0;
f(6);
例2:using namespace L;
k =0;
f(6);
- 宏:与作用域、类型、接口等概念格格不入
1) 潜伏于环境
2) 穿透作用域
3. 数组
- 特征
# 相同数据类型
# 有序
# 连续存储
0~n-1
- 一维数组
# 类型定义
# 函数参数
1)仅传递地址
2)元素个数需通过参数显示给出,不能通过sizeof取得
# 字符串
- 多维数组
# 定义: T A[c1][c2];
T A1[c2];
A1 A[c1];
# 存储组织
# 参数传递
1)只能缺省第一维
例1:
void f(int a[], int n);
void f(int a[][3], int n);
char s1[]="abc";
char s2[]={'a','b','c'};
4. 结构和联合
- struct
# 赋值—定义类型
# 参数传递
- union
# 共享存储空间
例子:例:定义一个能存储100个图形的数组,其中的图形可以是:直线、矩形、圆
enum FIGURE_TYPE {LINE, RECTANGLE, ELLIPSE};
struct Line
{ FIGURE_TYPE t ;
int x1, y1, x2, y2;
};
struct Rectangle
{ FIGURE_TYPE t;
int lef, top, rig, bot;
};
struct Ellipse
{ FIGURE_TYPE t;
int x, y, r;
};
union FIGURE
{ FIGURE_TYPE t;
Line line;
Rectangle rect;
Ellipse ellipse;
};
FIGURE figures[100];
void main()
{ input( figures, 100 );
for (int i=0;i<100;i++)
draw(figures[i]);
}
void draw_line(int,int,int,int);
void draw_rect(int,int,int,int);
void draw_ellipse(int,int,int);
5. 指针——管理地址信息,按地址管理数据(下一节)
6. 动态变量
- 动态变量
# 编译时刻无法确定
# 在程序运行时刻,动态产生、消亡
# 通过指向动态变量的指针变量来实现的
# 分配在堆区(heap)
# 局部变量也是动态产生、消亡,但在程序运行前编译程序已经知道它们的存在
# 动态变量与C++中的静态(static)变量属于不同的范畴,动态变量是程序设计的概念,
static是C++语言的概念
- 动态变量的产生——操作符
<
d12b
/span># new <类型名>
# new <类型名>[<整型表达式>]
例1:int *p = new int[10];
int (*p2)[5] = (int (*)[5])p;
for (int i=0;i<10;i++)
p[i] = i+1;
for (int j=0;j<2;j++)
{ for (int k=0;k<5;k++)
cout << p2[j][k] << " ";
cout << endl;
}
例2:typedef int i5Array [5];
void main()
{
i5Array *p = new i5Array [2];
for (int j=0;j<2;j++)
for (int k=0;k<5;k++)
p[j][k] = (j*5)+(k+1);
}
- 动态变量的产生——函数
# malloc定义:void *malloc (unsigned int size)
例子: p = (int *) malloc (sizeof(int)); //new int
q = (int *) malloc (sizeof(int)*20); //new int[20]
# new 对比 malloc
1) new 自动返回相应类型的指针,malloc要作强制类型转换
2) 如果创建的是动态对象,new会去调用相应类的构造函数,malloc则否
# 异常控制:必须在判断申请的空间有效的情况下,才能使用
- 动态变量的消亡
# 动态变量不会自动消亡,在程序运行期间,如果不再需要某个动态变量,应显示地使之消亡,否则将造成memory leak
# 操作符: new —— delete
# 函数: malloc —— free
# delete []
- 动态变量的应用
# 数据结构
1) 链表(单、双)——栈、队列
2) 树、图
# 结点的定义
struct NODE
{
int content;
NODE *next;
};
NODE *head = NULL;
# 结点的插入
1)产生一个结点
NODE *p = new NODE;
p->content = some_int_value;
p->next = NULL;
2)链表为空
head =p;
3)表头插入
p->next = head;
head = p;
4)表尾插入
NODE *q = head;
while (q->next)
q=q->next;
q->next = p;
5)插在链表中某结点(值为a)的后面
NODE *q = head;
while (q&&q->content != a)
q=q->next;
if(q) //存在a
{ p->next = q->next; q->next =p;}
else
cout<<"Not found!";
6)插在链表中某结点(值为a)的前面
NODE *q1=NULL, *q2=head;
while (q2 && q2->content != a)
{ q1 = q2; q2 = q2->next; }
if (q2)
//存在a
{ if (!q1)
// a是第一个结点
{ p->next = q2; head = p; }
else
// a不是第一个结点
{ p->next = q2; q1->next = p; }
}
else //不存在ai
cout << "Not found!";
7)结点删除
NODE *q1=NULL, *q2=head;
while (q2 && q2->content != a)
{ q1 = q2; q2 = q2->next; }
if (q2) //存在a
{ if (!q1) // a是第一个结点
{ head = q2->next; delete q2; }
else // a不是第一个结点
{ q1->next = q2->next; delete q2; }
}
else //不存在a
cout << "Not found!";
7. 引用
- 定义:为一块已有的内存空间取一个别名
# 引用变量和被引用变量应具有相同的类型
# 引用变量定义中的&不是取地址操作符
# 定义引用变量时必须要有初始化
- 应用:
# 函数参数传递
# 动态变量命名
- 引用变量和指针变量的区别
# 访问
1) 引用:直接访问
2) 指针:间接访问
# 存储
1) 引用:与被引用变量共享内存
2) 指针:有自己的内存空间
# 实参
1) 引用:变量
2) 指针:变量地址
- 函数返回值类型为指针或引用
# 函数返回值的类型可以是引用或指针类型
# 如函数返回值的类型是引用或指针类型,不应把局部量或局部量的地址作为返回值返回
# 操作符重载 >>、<<、++、--、[]等
- 用const限定引用
void swap (const int &a, const int &b)
- 引用一旦定义,不可改变
- 释放堆中变量的引用
int *p = new int(100);
int &x = *p;
......
delete &x;
- 函数的执行机制
1) 建立被调用函数的栈空间
2) 参数传递
2.1) 值传递(call by value)
2.2) 引用传递(call by reference)
3) 保存调用函数的运行状态
4) 将控制转交被调函数
- 函数重载原则
# 名同,参数不同(个数、类型、顺序)
# 返回值类型不作为区别重载函数的依据
- 默认参数
# 默认参数的声明
1) 函数原型中给出
2) 先定义的函数中给出
# 默认参数的顺序
1) 右 ->左
2) 不间断
- 内联函数inline
#目的:提高可读性,提高效率
#对象:使用频率高的小段代码
#实现方法:编译系统将为inline函数创建一段代码,在每次调用时,用相应的代码替换
#限制:非递归
#缺点:增大目标代码(object code)
病态的换页(thrasshing)
降低指令快取装置的命中率(instruction cache hit rate)
例子:inline int ascii(char a)
{ return a;
}
int main(int argc, char *argv[])
{
int i =0;
int r =0;
r = ascii('1');
printf("r=%d\n",r);
return 0;
}
2. 程序组织
- 程序结构
1) 逻辑结构
2) 物理结构(多个源文件相减,main唯一)
3) 工程文件(外部函数、外部变量)
- namespace:解决全局变量/函数的命名冲突?
namespace L
{
int k;
void f(int);
...
}
例1:using L::k;
using L::f;
k =0;
f(6);
例2:using namespace L;
k =0;
f(6);
- 宏:与作用域、类型、接口等概念格格不入
1) 潜伏于环境
2) 穿透作用域
3. 数组
- 特征
# 相同数据类型
# 有序
# 连续存储
0~n-1
- 一维数组
# 类型定义
# 函数参数
1)仅传递地址
2)元素个数需通过参数显示给出,不能通过sizeof取得
# 字符串
- 多维数组
# 定义: T A[c1][c2];
T A1[c2];
A1 A[c1];
# 存储组织
# 参数传递
1)只能缺省第一维
例1:
void f(int a[], int n);
void f(int a[][3], int n);
char s1[]="abc";
char s2[]={'a','b','c'};
4. 结构和联合
- struct
# 赋值—定义类型
# 参数传递
- union
# 共享存储空间
例子:例:定义一个能存储100个图形的数组,其中的图形可以是:直线、矩形、圆
enum FIGURE_TYPE {LINE, RECTANGLE, ELLIPSE};
struct Line
{ FIGURE_TYPE t ;
int x1, y1, x2, y2;
};
struct Rectangle
{ FIGURE_TYPE t;
int lef, top, rig, bot;
};
struct Ellipse
{ FIGURE_TYPE t;
int x, y, r;
};
union FIGURE
{ FIGURE_TYPE t;
Line line;
Rectangle rect;
Ellipse ellipse;
};
FIGURE figures[100];
void main()
{ input( figures, 100 );
for (int i=0;i<100;i++)
draw(figures[i]);
}
void draw_line(int,int,int,int);
void draw_rect(int,int,int,int);
void draw_ellipse(int,int,int);
5. 指针——管理地址信息,按地址管理数据(下一节)
6. 动态变量
- 动态变量
# 编译时刻无法确定
# 在程序运行时刻,动态产生、消亡
# 通过指向动态变量的指针变量来实现的
# 分配在堆区(heap)
# 局部变量也是动态产生、消亡,但在程序运行前编译程序已经知道它们的存在
# 动态变量与C++中的静态(static)变量属于不同的范畴,动态变量是程序设计的概念,
static是C++语言的概念
- 动态变量的产生——操作符
<
d12b
/span># new <类型名>
# new <类型名>[<整型表达式>]
例1:int *p = new int[10];
int (*p2)[5] = (int (*)[5])p;
for (int i=0;i<10;i++)
p[i] = i+1;
for (int j=0;j<2;j++)
{ for (int k=0;k<5;k++)
cout << p2[j][k] << " ";
cout << endl;
}
例2:typedef int i5Array [5];
void main()
{
i5Array *p = new i5Array [2];
for (int j=0;j<2;j++)
for (int k=0;k<5;k++)
p[j][k] = (j*5)+(k+1);
}
- 动态变量的产生——函数
# malloc定义:void *malloc (unsigned int size)
例子: p = (int *) malloc (sizeof(int)); //new int
q = (int *) malloc (sizeof(int)*20); //new int[20]
# new 对比 malloc
1) new 自动返回相应类型的指针,malloc要作强制类型转换
2) 如果创建的是动态对象,new会去调用相应类的构造函数,malloc则否
# 异常控制:必须在判断申请的空间有效的情况下,才能使用
- 动态变量的消亡
# 动态变量不会自动消亡,在程序运行期间,如果不再需要某个动态变量,应显示地使之消亡,否则将造成memory leak
# 操作符: new —— delete
# 函数: malloc —— free
# delete []
- 动态变量的应用
# 数据结构
1) 链表(单、双)——栈、队列
2) 树、图
# 结点的定义
struct NODE
{
int content;
NODE *next;
};
NODE *head = NULL;
# 结点的插入
1)产生一个结点
NODE *p = new NODE;
p->content = some_int_value;
p->next = NULL;
2)链表为空
head =p;
3)表头插入
p->next = head;
head = p;
4)表尾插入
NODE *q = head;
while (q->next)
q=q->next;
q->next = p;
5)插在链表中某结点(值为a)的后面
NODE *q = head;
while (q&&q->content != a)
q=q->next;
if(q) //存在a
{ p->next = q->next; q->next =p;}
else
cout<<"Not found!";
6)插在链表中某结点(值为a)的前面
NODE *q1=NULL, *q2=head;
while (q2 && q2->content != a)
{ q1 = q2; q2 = q2->next; }
if (q2)
//存在a
{ if (!q1)
// a是第一个结点
{ p->next = q2; head = p; }
else
// a不是第一个结点
{ p->next = q2; q1->next = p; }
}
else //不存在ai
cout << "Not found!";
7)结点删除
NODE *q1=NULL, *q2=head;
while (q2 && q2->content != a)
{ q1 = q2; q2 = q2->next; }
if (q2) //存在a
{ if (!q1) // a是第一个结点
{ head = q2->next; delete q2; }
else // a不是第一个结点
{ q1->next = q2->next; delete q2; }
}
else //不存在a
cout << "Not found!";
7. 引用
- 定义:为一块已有的内存空间取一个别名
# 引用变量和被引用变量应具有相同的类型
# 引用变量定义中的&不是取地址操作符
# 定义引用变量时必须要有初始化
- 应用:
# 函数参数传递
# 动态变量命名
- 引用变量和指针变量的区别
# 访问
1) 引用:直接访问
2) 指针:间接访问
# 存储
1) 引用:与被引用变量共享内存
2) 指针:有自己的内存空间
# 实参
1) 引用:变量
2) 指针:变量地址
- 函数返回值类型为指针或引用
# 函数返回值的类型可以是引用或指针类型
# 如函数返回值的类型是引用或指针类型,不应把局部量或局部量的地址作为返回值返回
# 操作符重载 >>、<<、++、--、[]等
- 用const限定引用
void swap (const int &a, const int &b)
- 引用一旦定义,不可改变
- 释放堆中变量的引用
int *p = new int(100);
int &x = *p;
......
delete &x;
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- ip地址基础知识
- VBS基础编程教程 (第1篇)
- VBS基础编程教程 (第3篇)
- 路由器基础精析
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- VBS基础编程教程 (第4篇)
- VBS基础编程教程 (第5篇)
- VBS基础编程教程 (第6篇)
- VBS编程教程 (第2篇)
- C++联合体转换成C#结构的实现方法
- AJAX初级教程之初识AJAX
- Jquery 基础学习笔记
- C++编写简单的打靶游戏
- C++ 自定义控件的移植问题