C 编程总结

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);//会多次分配内存

  vos_printf(strTmp);
  vos_printf(strTmp); //只会分配一次内存
<4> const int ciMax = 10;  //const 常量有数据类型,编译器会进行类型安全检查
    #define MAX_SIZE 10   // 宏定义 没有参数类型,不会进行类型安全检查
<5>const数据成员的初始化只能在类的构造函数的初始化表中进行.
<6>要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现。如
class A
{…
enum {size1=100, size2 = 200 };
int array1[size1];
int array2[size2];  
}
枚举常量不会占用对象的存储空间,他们在编译时被全部求值。但是枚举常量的隐含数据类型是整数,其最大值有限,且不能表示浮点数.
<6>const 位于* 的左侧,则修饰指针所指向的变量,变量为常量。
   const 位于* 的右侧,则修饰指针本身,指针本身为常量。
<7>如果给采用“指针传递”方式的函数返回值加const修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。如:
const char * GetString(void);
如下语句将出现编译错误:
char *str=GetString();
正确的用法是:
const char *str=GetString();
<8>
24.怎么在VS中用反汇编查看构造函数的调用过程
例子:
#include <stdio.h>
#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());
}
<1> 在  C c; 打断点,F5, 右键,转到反汇编,F10,
     lea         ecx,[ebp-18h]   //把this指针赋值给 ecx,
     call        C::C (411104h)
     ....................
     mov         ecx,dword ptr [ebp-14h]  //把this 指针 的前4字节赋值给 ecx
<2>在构造函数中调用虚函数,只会调用自身的函数,不会调用其他类(基类,派生类)的虚函数
   因为进入到该构造函数时,会拷贝自身类的虚函数表,给该对象的首4字节。
<3>

     ....................
    dword ptr [eax],offset C::`vftable' (41674Ch)   //把虚函数表拷贝到,对象的的前4个字节

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值