1.入参检查。指针为空判断。
2.对结构体对象初始化。memset (&structObj, 0, sizeof(structObj));
3.编写函数通常要把异常返回出去,编写错误码。注意写日志。
4.函数传入数组时,记得把数组的大小作为一个参数传进去,因为传入数组的数组名,不能算出数组的大小。
5.命名规范
<1>
unsinged long ulRet =0;
bool bIsTrue = true;
bool * pbIsTrue = true;
<2>
<3>
<4>
<5>
<6>
<7>
<8>
<9>
<10>
6.分配内存后,要判断内存是否分配成功。
7.释放内存后,要把指针赋空。要不然会出现野指针。
8.在循环时,注意数组越界。和循环翻转,导致死循环。
9.拷贝时,需要判断是否能容纳被拷对象。
10.有关数字的都要用宏替换,宏名的定义要有含义。
11.有比较成熟的库函数,或者已经成熟的标准函数,这种函数不要自己在编写。降低风险。
12.每遇到一个指针,都应该问问:这个指针的类型是什么?指针指的类型是什么?该指针指向了哪里?
13.一个指针ptrold加上一个整数n后,结果是一个新的指针ptrnew,ptrnew的类型和ptrold的类型相同,ptrnew所指向的类型和ptrold所指向的类型也相同。ptrnew的值将比ptrold的值增加了n乘sizeof(ptrold所指向的类型)个字节。就是说,ptrnew所指向的内存区将比ptrold所指向的内存区向高地址方向移动了n乘sizeof(ptrold所指向的类型)个字节。
14.当传入的指针不被修改时,需要添加const。
15.从函数中返回值时,要么返回错误码,如果函数内部
16.explicit 构造函数的隐式转换带来的错误或者误解。explicit 只对构造函数起作用,用来抑制隐式转换。
17.#pragma pack(push) // 以4字节对齐
#pragma pack(4)
struct tag_struct
{
char cTmp;
double dTmp;
int iTmp;
};
#pragma pack(pop)
18.
struct MyStruct
{
double dda1;
char dda;
int type
};
为上面的结构分配空间的时候,VC根据成员变量出现的顺序和对齐方式,先为第一个成员dda1分配空间,其起始地址跟结构的起始地址相同(刚好偏移量0刚好为sizeof(double)的倍数),该成员变量占用sizeof(double)=8个字节;接下来为第二个成员dda分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为8,是sizeof(char)的倍数,所以把dda存放在偏移量为8的地方满足对齐方式,该成员变量占用sizeof(char)=1个字节;接下来为第三个成员type分配空间,这时下一个可以分配的地址对于结构的起始地址的偏移量为9,不是sizeof(int)=4的倍数,为了满足对齐方式对偏移量的约束问题,VC自动填充3个字节(这三个字节没有放什么东西),这时下一个可以分配的地址对于结构的起始地址的偏移量为12,刚好是sizeof(int)=4的倍数,所以把type存放在偏移量为12的地方,该成员变量占用sizeof(int)=4个字节;这时整个结构的成员变量已经都分配了空间,总的占用的空间大小为:8+1+3+4=16,刚好为结构的字节边界数(即结构中占用最大空间的类型所占用的字节数sizeof(double)=8)的倍数,所以没有空缺的字节需要填充。所以整个结构的大小为:sizeof(MyStruct)=8+1+3+4=16,其中有3个字节是VC自动填充的,没有放任何有意义的东西。
19.#pragma pack(push,1) //以1字节对齐
struct RateInfoOld
{
time_t ctm; // rate time
int open; // open price: 11987=119.87
short high,low,close; // high,low,close shift from open
double vol; // volume
};
#pragma pack(pop)
20.在 a.c定义
char g_cTmp = "test";
在main.c 中
extern char g_cTmp;
printf("%s\n",g_cTmp);
21. static 讲述
<1>static char cTmp; //此变量只在文件中使用,其他文件没法访问。
<2>static 修饰的变量 放在静态数据区,保存变量持久内容。
<3>默认初始值为 0。
22. const 讲述
<1>const int iTmp=5; //限定变量为只读
<2>const int iTmp;
iTmp = 0; //error 定义时必须立刻初始化
<3>可以避免不必要的内存分配
#define STRING_TMP "TEST_FIRST"
const char strTmp[] = "TEST_FIRST";
vos_printf(STRING_TMP);
vos_printf(STRING_TMP);//会多次分配内存
class A
{…
enum {size1=100, size2 = 200 };
int array1[size1];
int array2[size2];
}
枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数.
const char * GetString(void);
如下语句将出现编译错误:
char *str=GetString();
正确的用法是:
const char *str=GetString();
#include<string.h>
class A
{
public:
A()
{
puts(GetClassName());
}
~A(){};
virtual char* GetClassName(){return "A";}
};
class B : public A
{
public:
B()
{
puts(GetClassName());
}
~B(){}
virtual char* GetClassName(){return "B";}
virtual char* GetClassName2(){return "B";}
};
class C : public A, public B
{
public:
C()
{
puts(GetClassName());
}
~C(){}
virtual char* GetClassName(){return "C";}
};
void main()
{
C c; //
c.GetClassName();
B* a = (B*)&c;
puts(a->GetClassName2());
B* b = (B*)(void*)&c;
puts(b->GetClassName2());
}
25. 快捷键 alt +G 转向定义
26.LPCSTR :VC中,字符串类型,long ptr const,
如:LPCSTR lpStr = "test";
27. LPCSTR 转换成 CString
LPCSTR lpStr = “test”;
CString str(lpStr);
CString 转换为 LPCSTR
CString str(_T("test"));
LPCSTR lpStr =(LPCSTR)str;
28.