1. char* p = new char[10]; 代表开辟了有100个char型的空间(数组的指针),不是100个char*(指针的数组)
2. new和malloc
new会调用类的构造函数“返回”相应的类型;malloc只申请内存,返回void*.
delete只能和new配套使用,free只能与malloc使用。
char* p;
p = (char*)malloc(100);
3. 类名 变量名 和 类名* 变量名 的区别
执行到类名 变量名时,会紧跟着调用此类的构造函数,在这个变量生命周期结束后,执行此类的析构函数,释放空间。
执行到类名* 变量名=NULL时不调用此类的构造函数,当有new时才调用此类的构造函数,此变量存放在内存的栈中,不会自动释放,只有显示的执行delete 变量名时才会调用此类的析构函数,释放空间。
4. 内存空间是谁申请谁释放,但要注意释放的地方以及内存泄露及野指针。
在函数内申请的变量,当在函数内使用完后,就在函数内释放。
当此变量是传入的指针时(需要在函数外使用的),虽然也是在函数内申请的空间(new)但在函数外要使用,要在函数外释放。此种情况下,函数外的变量名(多赋的是NULL值)和函数内的变量名(在函数内new)是同一个变量(两个变量名在同一时间内不会同时存在),同一个空间,和两个指针指向同一空间是不同的。
5. #define SAFE_DELETE_ARRAY(p) { if(p) { delete [] (p); (p) = NULL; } }
6. 申请空间要从外向里申请;释放空间要从里向外释放(释放之前要判断一下是否为NULL,释放了NULL的指针将报错)。
7. memcpy
原型:extern void *memcpy(void *dest, void *src, unsigned int count);
用法:#include <string.h>
功能:由src所指内存区域复制count个字节到dest所指内存区域。
说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针。
8 #include <stdlib.h> system("cls");
9. string转换成char*
string path;
const char* a=path. c_str();
10 string转换成char
String s="asdas";
char c=s[0];
//c='a';
11. char buffer[100]=”aaaaaddddffff”;
char* buf=buffer;//不能反过来赋值,数组名代表的是常量,不能改变。
char* buf=”addafafa”;
12. /n只是回车,即回到本行第一列,ASCII码是0x0a,/r是换行,即换到本列下一行,ASCII码是0x0d
13 键盘输入一个字符正确,多个则出错。(不这样做,第一个字符被第一个cin接收,第二个字符被下一个cin接收到)
string strFirstSelect;
cin>>strFirstSelect;
if (strFirstSelect.length() != 1)
{
cout<<"you input a wrong number!"<<endl;
}
14. string型转换为int型
string str=”12345”;
int nlen = atoi(str.c_str());
15. c_str()介绍
#include <string>
const char* c_str();
c_str函数的返回值是const char*的,不能直接赋值給char*。
c_str()返回一个客户程序可读不可改的指向字符数组的指针,不需要手动释放或删除这个指针。
16. memset介绍
#i nclude string.h
void *memset(void *s,int c,size_t n);
2.功能:
memset将指针s所指的内存区域的前n个字节用字节c来填充;
3.返回值:
memset函数返回指向这个内存区域的指针s。
17. atoi介绍(atol, itoa)
函数名: atoi
功 能: 把字符串转换成整型数
函数说明: atoi()会扫描参数nptr字符串,检测到第一个数字或正负符号时开始做类型转换,之后检测到非数字或结束符 /0 时停止转换,返回整型数。
用 法: int atoi(const char *nptr);
需要用到的头文件: #include <stdlib.h>
18. exit(1);异常退出整个程序。不执行析构函数了,
解决办法:1.在这句之前调用析构函数。2.如果是在main函数中则执行return 0;和exit(1)效果一样。
函数解释:一般来说,每个程序退出后都会给系统一个返回值。其他程序可以根据这个返回值来判断这个程序是否是正常退出。exit(1)中的这个1就是返回值。这个数值是多少是你自己决定的。通常情况下,0代表正常退出,其他数字代表异常退出。
19.检查文件是否为空。
FILE * m_pFile = fopen(pFilePath,"r");
fseek(m_pFile, 0, SEEK_END);
int nCot = ftell(m_pFile);
if(nCot == 0)
{
fclose(m_pFile);
return 2;//file is empty
}
20. char* p = “ABCD”; //其实是常量的定义了,里面的任何一个字母都不能再变动了。
*p = ‘A’
p = &p[0]
p+1 = &p[1]
21. C++回调方法经典例子。
定义 (函数指针)
typedef unsigned (*_pWorkProc)(CWnd*); //定义下面这个函数的函数指针,为了在使用中调用
声明函数原型
unsigned MyWorkProc(CWnd* pParent);
使用
void Test(_pWorkProc pWorkProc) //回调函数的使用函数(调用回调函数),很重要!
{
pWorkPorc(this); //调用回调函数
}
定义一个回调函数
unsigned MyWorkProc(CWnd* pParent) //回调函数的内容
{
pParent->MessageBox("hello");
return 0;
}
void main() //main函数可有可无
{
Test(MyWorkProc);
}
22. 回调时的几个注意事项
class Number
{
public:
static int print1(int a);
int print2(int a);
};
int print3(int a);
void main()
{
typedef int (*MemberFun)(int);
typedef int (MessClass::*MemberFun)(int,int);
MemberFun p1;
p1=Number.print1;//正确
p1=Number.print2;//错误
p1=print3;//正确
MessClass::MemberFun p2;
p2=Number.print1;//错误
p2=Number.print2;//正确
p2=print3;//错误
}
23. sizeof数组的问题
char c[10];
cout<<sizeof(c);//答案是10,而不是4.这里的c不代表指针。
char* b;
b = c;
cout<<sizeof(b);//答案是4。指针。
24. fwrite(buffer,size,count,fp);
(1)buffer:是一个指针,对fwrite来说,是要输出数据的地址。
(2)size:要写入的字节数;
(3)count:要进行写入size字节的数据项的个数;
(4)fp:目标文件指针。
说明:写入到文件的哪里? 这个与文件的打开模式有关,如果是r+,则是从file pointer指向的地址开始写,替换掉之后的内容,文件的长度可以不变;如果是a+,则从文件的末尾开始添加,文件长度加大,而且是fseek函数对此函数没有作用。
25. int fflush(FILE *stream)
功 能: 清除文件缓冲区,文件以写方式打开时将缓冲区内容写入文件
多和fwrite同时使用。
26. 清除缓存区信息
cin.clear();
cin.sync();
27. 数组和char*的互相赋值。
1.
char* k = "hfada";
char c[10];// c是常量指针,不可以改变
strcpy(c, k);
strncpy(c, k, sizeof(c));
memcpy(c, k, sizeof(c));
2.
char c[10] = {'1','2','3','4','7'};
char* k = NULL;
k = c;
28.在不知道char*大小的情况下求它的字符个数。
char* k = “不知道是多少个字符”;
char a[] = “一段字符串
strlen(k);//不包括字符串最后的/0,和string中的.length()性质一样
strlen(a);
29.在DOS中格式化输出信息
cout<<setw(4)<<left<<信息;
setw(4):占四个字节
left:靠左对齐
30. string型中取某一个字符。
string strSecondSelect = “fdlfaldfal”;
char cSelect = strSecondSelect[0];
31 读文件的简单函数。
#include <fstream>
ifstream fileRow(“文件的完整路径”);
if(!fileRow.is_open()) //文件是否正常的打开。(不存在,不能打开,路径错误都会返回0)
{
}
string line;
while(getline(fileRow, line))//一行一行的读文件到line中,读到行结束符时结束
{
}
fileRow.close();//关闭文件。
32. 转换字符为小写或为大写
int tolower(int c);//转换成小写,原来是小写则不转换;
int toupper(int c);//转换成大写,原来是大写则不转换。
33. 一种读文件的方法。
struct VIDEO_INDEX_FORMAT
{
unsigned char camtype[6];
unsigned char frmsize[4];
unsigned char offset[8];
}
FILE *pIndexFile = fopen("d://video_index.dat", "rb");
VIDEO_INDEX_FORMAT *pVIformat = new VIDEO_INDEX_FORMAT;
fread(pVIformat, 32, 1, pIndexFile);
int offset = *((int *)pVIformat->offset); //取得都是数组的首元素[0]的值。
unsigned long frmSize = *((unsigned long*)pVIformat->frmsize); //取得都是数组的首元素[0]的值。
34. 枚举型的用法
typedef enum
{
FRAME_TYPE_I,
FRAME_TYPE_P,
FRAME_TYPE_B,
FRAME_TYPE_J,
} PGLIB_FRAME_TYPE;
PGLIB_FRAME_TYPE frmtype = FRAME_TYPE_B;
frmtype = FRAME_TYPE_I;
35. 初始化指针数组的方法
unsigned char *pBuf = new unsigned char[frmSize + 8];
memset(pBuf, 0, sizeof(char)*(frmSize + 8));
36. 要在函数中改变变量的值,需要往函数中传指针:type*。大多数情况是往函数中传 &变量 这样的形式的参数。
特殊情况:当函数调用本来就是 指针—>函数名() 的时候,可以将外面的指针名字作为参数传进去。