C++基础之技巧和小知识(代码中的积累)

来源:互联网 发布:中标数据查询网 编辑:程序博客网 时间:2024/06/02 06:23

1.do{}while(0)

why:宏里写多条语句,不用连接符\,且多条语句分多行,会出现没有替换所有语句,在所有语句前加{},VS可以通过,用do{}while(0)所有编译器都通过

看cocos2d中init函数源码发现的技巧

2.验证一些算法或者函数看变量的值不用每次printf,下断点鼠标放在上面

借鉴他人的经验,不用每次验证傻乎乎的printf或者cout

3.语句占用时钟周期(所以有时候编译器很聪明,几件事糅合为一条汇编语句)

编译器的算法好

4.高手技巧之一:循环、判断里将常量写在左边变量写在右面,有利于如果将==写成=立刻找出错误

看网上最简单的socket时候判断中的写法发现的技巧

5.内存对齐需要预编译指令#programe pack(n),n是系数,填的一般是0,1,2,4,8

我测验后发现,如果不想让内存对齐,n=1

之所以会出现内存对齐是两方面的冲突,1.是因为short、bool、char开辟的空间是2个字节、1个字节、1个字节2.开辟空间一般按4个字节4个字节的开辟,1和2冲突了,开4个空间存了char,剩余自己用cc补充

因为内存对齐和自己计算的所占内存大小不同后验证的结果

6.数组传参,形参变为指针

看汇编指令发现或者siziof测出的

7.高手技巧之一:头文件每个变量和函数都有注释

注释精确易懂

8.高手技巧之一:命名精确

注释精确易懂

9:高手技巧之一:衍生变量不存(例如a为1b为2后面算得加的结果是3,最后又用到3,3不用刻意存)

内存占用少,不过可以适当考虑自己编程效率

10:需求文档按照机器的思路来写

理清思路写代码,选择方向在出发

11.for(;;)比while(1)效率快

自己经常用的while(true),网上看到的自己也验证了一下

12.类名习惯大写

(写类过程中想不到命名的名字时遇到的问题)

13.malloc分配内存,分配失败,返回空指针,malloc(0)也是分配了空间的如图


new是封装的malloc的,分配失败,显示如图

(我在封装用链表管理数组过程中考虑到如果new失败遇到的问题)
14.交流电翻转一次是一个时钟周期,一个时钟周期cpu执行一条语句,现在电脑cpu主频3.2GHz,每秒执行3.2G的语句,有的时候可以牺牲运行效率

我在封装用链表管理数组过程中考虑delete两条链表操作相同,写成两个函数传入是哪条链表修改方便而没有写在一起没有写在析构里遇到的问题
15.delete一个空指针,不太好,我用的是VS2010,不会报错,但是不跨平台,老的平台里会报错
经常遇到,这次我在封装链表管理数组中要delete两条链表,不管有没有结点都delete掉发现不跨平台特性
16.return 1、return 2、return 0
之前练习习惯返回值是void或者只是bool,但是在这次封装链表管理数组过程中调用的函数里退出函数的情况情况多,返回的值来代表因为什么原因来退出函数的,函数的返回值做好注释//返回值:0代表……          1代表……

17.char *p = "hello";p指向hello(在常量区),char a[] = "hello";将字符串内容拷贝在数组开辟的空间中

原来在用一直没有注意,就知道这样写也可以,那样写也可以

18.memset(void *s,int c,size_t n)把变量s里面从第一个开始算到n的字节赋值为c,常用于指针赋空,也可以char赋值,切记不用其他类型变量,因为以字节为单位

指针赋空我经常用NULL,看到他人的用法练习的

19.如果开辟一块空间,但具体空间大小在运行前不知道,直接建立数组是不行的,动态数组又很麻烦,用new[size]的方式

在封装链表管理数组过程中不知道用户需要存储数据的大小,用int a[size]编译时候需要确定大小,报错不能int*转化为int[],new返回内存首地址

20.成员变量是指针,成员函数中给指针赋值成员函数退出后指针的值存在

成员变量不像练习的时候int、char,机会都是指针,不是像函数中的局部变量一样退出后就没有了

21.int默认是带符号,对于是否带符号左移相同,即左移的位数后得到的结果和左移的位数对32取余后的结果是一样的(8<<42和8<<(42%32))

右移:带符号的符号位右移,符号位始终是最开始的符号(1101<<2是1110),无符号的该怎么右移怎么右移

一位朋友面试时候HR考的


22.strlen是计算字符串长度的,遇到‘\0’停止,直接计算指向不可访问内存的指针,会直接报错,strcpy也是一样


在封装String类的时候构造没有写判断传入的指针为不为空发现


23.strcpy拷贝一串字符串,将‘\0’也拷贝了,strlen是计算一串字符串的长度,没有计算'\0‘的长度

封装String类的时候验证的

24. char *s = "1234";一般我们要把字符串传入,传的是指针,理解是把字符串的首地址放到指针里传入,但是我们忽略的是直接传入字符串,也可以,传的是字符串的首地址

封装好String类后实验发现的

25.怎么识别一个例如sizeof是函数,还是关键字,还是操作符~~~看汇编,函数有call,关键字像static、class这些都没有对应的汇编代码

封装String类的时候对sizeof()的解析发现的技巧

26. sizeof返回对象所占内存的字节数

 int a = 2;                    a = sizeof(a);          //4
 char *p = NULL;       a = sizeof(p);         //4                  a = sizeof(*p);                //1-----计算NULL占的内存
 p = "123456";            a= sizeof(p);          //4                  a = sizeof(*p);               //7---加上‘\0’的
A t;                               a = sizeof(t);          //8----A里面两个int成员变量
int b[5];                        a = sizeof(b);        //20

封装String类的时候深究练习sizeof对比


27.int a = sizeof(A);a是多少//A是一个没有任何成员变量和成员函数的类的对象-------a是1,空类自动插入一个char来标示是哪个对象

<pre name="code" class="cpp">封装String类的时候深究sizeof()

28.typedef的使用

typedef int INT//不用加分号,和宏有些类似,如果typede写成#define的话,出现int的地方就替换成INT了,是typedef的情况,是定义了一个类型,INT的作用就是int类型

封装多线程类的时候看到DWORD是无符号long

28.类也可以像函数一样声明

我们如果在main函数里调一个普通函数,要是将这个普通函数的实现写在main函数的下面,需要在main函数上面写一个这个函数的声明,类也可以

封装多线程类的cpp里有一个结构体,结构体里有一个成员是这个类的对象,类在结构体上面写的,报错的时候随手像函数一样的写了个声明
29.将结构体写在cpp里和写在这个cpp类的public下是一样的

封装多线程的头文件中,这个类的构造函数需要传入一个结构体的指针,我在这个头文件中写了这个结构体,写在这个cpp中但是写在类的外面,为了好看,我将结构体写在类的public下,没有啥影响
30.new开辟的空间大小需要先在栈上push


new一次是在堆上开辟一快连续的空间,new是封装C的malloc,malloc后面写的是开辟的空间的具体大小
31.成员变量成员函数是this调用


这个知识之前粗浅的知道,封装多线程的过程中发现,我要在成员static函数中用成员变量,需要先将这个类的this指针传入,才能在static成员函数中调用成员变量
32.需要数据肿么办

(1)传参(2)需要的数据写成全局的

封装多线程的卖票过程中票数写成static多个线程共享,或者每个线程中传入指向票数地址的指针可以达到同样的目的
33.报错0xC00000005:读取位置0x00000030时发生访问冲突

是访问路径不对


我封装多线程类的时候虚函数中传入的参数是结构体的指针指出来的结构体成员变量,继承后重写的函数中传入的是结构体的指针,参数前后不一造成的
34.报错下面这个(偷懒没写错误种类,截图……貌似写的这几个字也超过报错的字数)


问题出在调用函数的方式出错,我封装多线程的过程中线程回调函数是普通调用,我写在类中,调用方式冲突,解决,我加了static

35.高手技巧之一:建的对象写在花括号里会发生的事情:建对象调构造函数,出了花括号自动掉析构函数


封装多线程卖票程序,写自动锁的原理

36.断点可以断到创建的副线程中

额(⊙o⊙)…
37.报错(如图)

我封装多线程的过程中,一开始的想法是将线程回调函数写虚,发现函数的关键字只能加一个~

38.我称作是“自动记忆”

我VS新建了很多的.h和.cpp,我先在a.h里删了一行,第二步我在b.h里删了一行,在c.cpp里删了一行,Ctrl+z是回退到上一步,接下来我在a.h里回退,按理说我最后一步是在c.h里做的操作,但是回退的是a.h里删的一行恢复了,在哪个文件回退,恢复的是这个文件的上一步

O(∩_∩)O~
39.高手技巧之一:下载个有道,起名的时候达到见名知意的感觉,命名规范又精准,他人看到你的代码感觉高精尖
嘿嘿~ 
40.函数是个工厂
多个对象调用这个函数,空间是不一样,但用的函数代码是同一段,不管调用多少次

曾经有个姓谭的朋友去工作的时候告诉我,函数就是个工作,需要什么原料得到什么结果,用到熟练的时候自然而然也就明白了

41.栈溢出or堆(堆没有溢出这个词)

题:我在构造里面new本类的对象会出什么错?

如果我建这个类的对象,建对象之前会push开辟空间大小的值,就是说先压栈,如果我建一个这个类的对象,调构造,构造里又建这个类的对象,又去调构造,死循环,栈1M溢出

如果我建这个类的对象,new的空间太大,我new个1024G,没有这么大的空间,但VS不会报错,不会像上面栈溢出会弹出stackoverflow的框框,我测验在我电脑上new1024G不会报错,new3G编译不通过

没有那么大的空间可new,反汇编push的是0


封装多线程扩展功能时候遇到的问题

42.每个人的代码中都有内存泄漏

函数中用到建立的局部变量,在没有退出函数前没有用到局部变量的语句的时钟周期,这个局部变量所占的空间泄漏

和朋友讨论的时候得到的,一般没人会想到这些,这也的确算是废话
43.大牛和菜鸟的区别有时候不在于玩不成任务,在于结构不同

面向对象中有些内容面向过程完全可以解决,但是扩展增删很不方便,时间足够菜鸟也能做出来,但是结构混乱

大牛的代码添加什么功能,随便改,不会拍桌子

拍桌子的程序员是废物

高手就是程序相关资源的合理应用---CPU时间和内存耗用

面向对象中规划时候感受

以下来自:《C程序设计:现代方法》总结

44.float会取小数点后面六位数,第六位小数后面的数四舍五入--0.1234567打印结果是0.123457,0.1234564打印结果是0.123456

取小数位固定方法%+.+num(取的位数)+f

45.两整数相除,向下取整,5/2 = 2,非3

46.可以用表达式表示的地方减少使用变量,打印s1,s1 = s2 *s3;用s2*s3代替

47.scanf的f和printf的f是格式化的意思

48.宏替换的是表达式,表达式用括号括起来,大写宏,库函数都是小写

49.main函数中的return和exit(0)完全等价

50.早期编译器删除注释,现在空格代替注释,注释中嵌套注释,非法,//注释个别编译器不合法会移植困难

51.标识符长度限制,没有限制,但编译器记住前31字符,两个名字前31字符相同编译器无法区分

52.printf格式串多余打印的值,打印0,格式串少,不打印多的值

53.123按%4d打印是右对齐,空格123,%-4d左对齐,123空格

54.scanf陷阱,%d%f%d,&x,&y,&z,x、z int,,y float,,输入打印10.3 5 6结果10,0.30001,5

55.求数反向123打印321,除数字分割外可利用%1d

56.求数的位数,除10的次数

57.求GCD最大公约数

int gc(int n,int m){ if(!n)return m; gc(m,n%m);}

58.字符可以当数组下标(C当字符为整数)





(PanPen120原创 如有建议 请留言)


0 0
原创粉丝点击