您的位置:首页 > 编程语言 > C语言/C++

c++学习笔记 2005-9

2005-09-28 17:25 525 查看
9-24
《程序设计实践》
马尔可夫程序:根据一分文本,构造一个马尔可夫链,根据输入,可以随机生成比较合理的文本。
c程序代码最长,速度最快。

下面为前些天学习c++的记录:
9-16
文件缓存 与 内存的关系
setbuf(FILE *,char *) 设定文件缓存,是文件IO时系统使用。
而我们char buf[size];表示分配一段内存,从缓存区中读到内存。
写时也写道文件缓存区。使用缓存区,可以减少读写文件次数。
使用fflush()清空缓存、

缺省初始值在声明时指定。
9-15
一个类需要动态分配内存,需要拷贝构造函数,一个赋值操作符

char *p = "hello"; // 非const指针,
// 非const数据

const char *p = "hello"; // 非const指针,
// const数据

char * const p = "hello"; // const指针,
// 非const数据

const char * const p = "hello"; // const指针,
// const数据

9-12
函数的默认参数值,只能在定义函数时给出
如:int parse(int ch=24);
memset 头文件 "string.h"

静态使用数组
动态使用vector

#include <vector>
std::vector<type> name(size);

&name[0] 做数组参数用,做缓存区
如: inputStream.read((unsigned char* )&buf[0],BLOCKSIZE);

9-9
比如 16
字符存储: "16" 占两个字节
二进制存储: 0x10 占一个字节

NULL 与null 区别

长循环放内层

常量初始化:
const 数据成员的初始化只能在类构造函数的初始化表中进行,例如
class A
{…
A(int size); // 构造函数
const int SIZE ;
};
A::A(int size) : SIZE(size) // 构造函数的初始化表
{

}
A a(100); // 对象 a 的SIZE 值为100
A b(200); // 对象 b 的SIZE 值为200

【规则6-1-4】如果输入参数以值传递的方式传递对象,则宜改用“const &”方式来
传递,这样可以省去临时对象的构造和析构过程,从而提高效率。

【规则7-2-1】用malloc 或new 申请内存之后,应该立即检查指针值是否为NULL。
防止使用指针值为NULL 的内存。
.. 【规则7-2-2】不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右
值使用。
.. 【规则7-2-3】避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”
操作。
.. 【规则7-2-4】动态内存的申请与释放必须配对,防止内存泄漏。
.. 【规则7-2-5】用free 或delete 释放了内存之后,立即将指针设置为NULL,防止产
生“野指针”

char a[] = “hello”;//为数组初始化,在栈中分配内存
a[0] = ‘X’;
cout << a << endl;
char *p = “world”; // 注意p 指向常量字符串,在静态存储区
p[0] = ‘X’; // 编译器不能发现该错误

用运算符sizeof 可以计算出数组的容量(字节数
对指针则不能获得它所指得内存容量。

注意当数组作为函数的参数进行传递时,该数组自动退化为同类型的指针

函数不要返回指向栈内存得指针,栈内存,指局部变量。new 操作在堆内存。

指针变量delete 后要 置NULL,不然他还是指向一个内存单元,那个内存可能分配给别人了。

malloc/free是库函数,编译器不能利用他门直接调用构造析构函数。new delete 不是库函数,可以重载
如果用new 创建对象数组,那么只能使用对象的无参数构造函数。

如果C++程序要调用已经被编译后的C 函数,该怎么办?
假设某个C 函数的声明如下:
void foo(int x, int y);
该函数被C 编译器编译后在库中的名字为_foo,而C++编译器则会产生像_foo_int_int
之类的名字用来支持函数重载和类型安全连接。由于编译后的名字不同,C++程序不能
直接调用C 函数。C++提供了一个C 连接交换指定符号extern“C”来解决这个问题。
例如:
extern “C”
{
void foo(int x, int y);
… // 其它函数
}
或者写成
extern “C”
{
#include “myheader.h”
… // 其它C 头文件
}

8.2.1 重载与覆盖
成员函数被重载的特征:
(1)相同的范围(在同一个类中);
(2)函数名字相同;
(3)参数不同;
(4)virtual 关键字可有可无。
覆盖是指派生类函数覆盖基类函数,特征是:
(1)不同的范围(分别位于派生类与基类);
(2)函数名字相同;
(3)参数相同;
(4)基类函数必须有virtual 关键字。

9-8

char parray[]="abcdefghijklmnopqrstuvwxyz";
char* b=new char[27];
strncpy(b,parray,27);
printf(b);
delete [] b;
只有拷贝27个字符包括“/0”才可以正确显示b,否则机器自动向后读取,直到"/0"

在函数的参数传递中,编译器总是要为函数的每个参数制作临时副本,如果参数为p的话,那么编译器会产生p的副本_p,使_p=p;
如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因.

  【问题分析】
   根据上面的规则我们可以很容易分析例子中失败的原因.

   void MyFunc(char *pReturn, size_t size)
  {
   ………
   pReturn = (char *)malloc(sizeof(char) * num);
  ………
  }
  void main(void){
  char *pMyReturn=NULL;
  MyFunc(pMyReturn,10);
  }
  在MyFunc(char *pReturn, size_t size)中_pMyReturn真实地申请到了内存, _pMyReturn申请了新的内存,
只是把_pMyReturn 所指的内存地址改变了,但是pMyReturn丝毫未变。所以函数MyFunc并不能输出任何东西。
事实上,每执行一次MyFunc就会泄露一块内存,因为没有用free释放内存。
只有改变pReturn指向的值,才有效。

在类中声明了静态数据成员,必须像全局数据项一样,在类外定义和初始化它。

class MazeFactory {

public:

static MazeFactory* Instance();

//existing interface goes here

protected:

MazeFactory();

private:

static MazeFactory* _instance;

};

MazeFactory* MazeFactory::_instance = 0;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: