1.指针的引用 
他也是引用,引用是特定内存块的别名 
2.变量定义 
更准确的说是内存使用约定,并为该约定命名

命名3.指向常变量的指针和常指针 
有点拗口,都是指针,但对于所在内存块的使用约定不同。常变量指针只能用于指向常变量,和普通指针不同。常指针所在内存块有固定的数据不可更改。

4.引用类型做参数时,函数不会操作对应内存块的拷贝,而是直接去操作那块内存。

根据引用这个概念的解释,它是对内存块已有约定进行补充,从而形成了一个新版约定,因此在定义新版约定是必须有个老版约定做基础。引用并没有为问题的解决提供新的路径,只是一项新的便于操作数据和理解的特性。

5.extern "C":表示这一部分代码按照C语言的方式处理,比如c++中的mangling mechanism在c中就没有了,c++中的自动清栈式调用在c中也变成了手动清栈

static void fun(){}:static表示这个函数仅在本文件内有效

static int i;:表示该全局变量也是仅在本文件内有效

如果一个源文件想要引用其他源文件中的函数或者变量,需要在前面加修饰符 extern:

extern int i;extern int fun()

6.另外,c语言不支持函数重载,c++支持

 c++的编译器在处理函数重载时,实际上是给重载的函数分别取名,可以减轻编译器的负担,貌似挺聪明的一个做法
7.宏的嵌套必须有空格分开

#define PTM ;int b;
#define ASD int a PTM int c;

8.__cdecl是被调用者自行清栈,用汇编来看待这过程,类似于

push ebp

mov ebp,esp

sub esp,0C0h ;存放函数参数

push ebx

push esi

push edi

......

pop edi

pop esi

pop ebx

mov esp,ebp

pop ebp

ret

__stdcall 是调用者来负责清栈,它是在一堆pop之前就ret了

9.参数化宏#define macro(parameter1,parameter2) xxxxxxx 三个比较有用的符号:“\"表示换行   “#x”将参数x转成字符串  "xx##yy"将两个参数xx 和yy连接成一个字符串

10.位运算符的记忆

&: 是按位乘

|: 是叠加后不透明

^: 叠加后透明,或者是按位加,不记录进位

 11.c++11新特性lambda函数 http://blog.csdn.net/srzhz/article/details/7934652#comments
12.空数组的作用
struct ast_ignorepat {
const char *registrar;
struct ast_ignorepat *next;
char pattern[0];
};
这是个广泛使用的常见技巧,常用来构成缓冲区。比起指针,用空数组有这样的优势:
1.不需要初始化,数组名直接就是所在的偏移
2.不占任何空间,指针需要占用int长度空间,空数组不占任何空间。
“这个数组不占用任何内存”,意味着这样的结构节省空间;“该数组的内存地址就和他后面的元素的地址相同”,意味着无需初始化,数组名就是后面元素的地址,直接就能当做指针使用。
这样的写法最适合制作动态buffer。因为可以这样分配空间:
malloc(sizeof(struct XXX)+ buff_len);//重点是这句
看出来好处没有?直接就把buffer的结构体和缓冲区一块分配了。用起来也非常方便,因为现在空数组其实变成了buff_len长度的数组了。
13.cout的格式化输出首先要包含头文件<iomanip> 设置字符宽度setw(10)//10个字符不足补空格    setioslfags(ios::left)//字符串左对齐,默认右对齐。
14.find_if使用类成员函数的问题。
15.这cin有点折磨人,它是从输入缓冲区中读入数据,有时为了结束输入,会人为通过输入 ctrl+z来设置eof标志位,但这时缓冲区还没清空,则下一次cin还会按顺序从缓冲区读数据,造成结果偏离预期,解决这问题的两个重要的函数cin.clear()清楚标志位,cin.sync()清空缓冲区。
16.stl 算法find_if如果找不到预期值,则返回vector.end(),并不改变container的状态,vector.resize()会将vector.begin(), vector.end()的位置进行调整,但原有的数据会保留, remove_if 会改变container的size,但原有的数据会保留,因此使用以上方法要注意边界情况,根据查找失败情况,container的实际大小来进行数据的读取。
17.分层设计中好的设计应该是由上层提供缓冲区,下层获取的数据放在缓冲区中,缓冲区为空则上层不产生输出.
18. win32 窗口程序中可以调用win32 console中的函数,不过这时会弹出控制台窗口,同样console程序可以调用windows api需要包含windows.h头文件。

19. 用system执行多条命令行语句system("cmd.exe /c echo test & echo hello world & @echo off"); &符号连接两条语句,echo off关闭命令回显, 前面加@表示 echo off这条命令自身也不显示。

20.%m.nf   格式化输出,m表示位宽,n表示小数点后显示几位,没有m则有几位就显示几位。

21.c++输入时设置分隔符的办法cin.ignore(1,',')1表示读入的数量,逗号表示终止字符,或者用scanf("%d,%d,%d",a,b,c);

22.c++的valarray数组类的用法

valarray<int> va(14)//定义一个含14个元素的数组

valarryay<int> va2=va[slice(start,size,stride)]//对数组进行分隔裁剪

va.apply(fun)//对数组元素应用函数,类似于foreach()函数

va.size(size,val)改变数组的大小,并将各个元素值设置为val

std::size_t lengths[]= {2,3};
std::size_t strides[]= {7,2};

std::gslice mygslice (start,
std::valarray<std::size_t>(lengths,2),
std::valarray<size_t>(strides,2));

如上可以对数组进行多维度的划分。

23.(c++11新特性)

可变参数数量(函数,宏,类模板,异常捕获):
int printf (const char* format, ... ); 
#define VARIADIC_MACRO(...) 

  1. try{
  2. // Try block.
  3. }
  4. catch(...){
  5. // Catch block.
  6. }
  1. template<typename... Arguments>
  2. void SampleFunction(Arguments... parameters);
  1. typename... Arguments这一部分代表一个参数包,函数调用的时候参数包会被解包,e.g.SampleFunction<int, int>(16, 24)
    我们可以用sizeof...运算符来计算代入的参数个数,e.g. int count=sizeof...(Arguments);
    模板参数个数可变,和函数参数可变相结合时,可能出现两个省略号连在一起,加不加逗号均可
  1. template<typename... Arguments>
  2. void SampleFunction(Arguments..., ...){
  3. }
  1. 具体应用:
  1. template<typename... BaseClasses>
  2. class VariadicTemplate : public BaseClasses...
  1. template<typename... BaseClasses>
  2. class VariadicTemplate : public BaseClasses...{
  3. public:
  4. VariadicTemplate(BaseClasses&&... base_classes) : BaseClasses(base_classes)...{
  5. }
  6. };
    变参数模板也支持偏特化
  1. template<typename... Arguments>
  2. class VariadicTemplate{
  3. public:
  4. void SampleFunction(Arguments... params){
  5. }
  6. };
  7. template<>
  8. class VariadicTemplate<double, int, long>{
  9. public:
  10. void SampleFunction(double param1, int param2, long param3){
  11. }
  12. };
    几个相关的操作符sizeof... decltype()

int foo(int i) {
return i;
}
double foo(double d) {
return d;
}

template<typename T>
auto getNum(T t)->decltype(foo(t)) {
return foo(t);
}

上面是一个比较有意思的用法,auto配合decltype来产生可变返回值类型,这些机制都是编译时刻就能决定的,或者说这些所谓的新特性就是编译器这一部分人工推导完成的工作给实现,没错,这一些特性的实现都可以人工来根据当前编码环境所提供的信息来完成,比如decltype获取类型,我们自己来根据编码context一样能完成类型推导,所以这些特性都是编译时期的工作。


  1. 具体使用时要配合递归调用自身
  1. 24.右値引用
    首先是何为右值,我的理解是那些没有名称的临时变量,比如,cout<<16<<"abcd";这句中16"abcd"都是临时变量,右值引用的出现还是为了减少内在开销。
  2. 25.pair只是把不相关的元素组合起来,map相当于一个pair的集合。
    mapemplace方法和insert方法作用类似 只不过insert功能更高级一些 e.g. mymap.emplace('z',100)
    insert 可以单个插入也可以,一次插入多个.
single element (1)
  1. pair<iterator,bool> insert (const value_type& val);
with hint (2)
  1. iterator insert (iterator position, const value_type& val);
range (3)
  1. template <class InputIterator>
  2. void insert (InputIterator first, InputIterator last);

  1. 26.c++11也支持自动元素遍历的用法了,类似于for(auto& x:container)//x代表元素,container代表容器
  1. 27.

LPCSTR的中文解释

L表示long指针
P表示这是一个指针
C表示是常量const
STR表示这个变量是一个字符串
28.求结构体成员相对偏移量的宏offsetof
具体用法为offsetof(structname,member)
下面是vs2012中关于该宏的定义

#ifdef _WIN64
#define offsetof(s,m) (size_t)( (ptrdiff_t)&reinterpret_cast<const volatile char&>((((s *)0)->m)) )
#else
#define offsetof(s,m) (size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
#endif

ptrdiff_t是一个机器相关的类型,通常用来保存两个指针相减的结果,通常这个类型为long int

volatile是一个变量修饰符,表示该变量的使用不可以被优化,因为涉及到多线程同步的问题

reinterpret强制类型转换,并不改变变量的二进制结构

在这个宏中将0强制转化为S类型的指针,意即该S型变量的起始地址为0,其后的成员地址的获取都是根据这个起始地址来获取,再对某个成员取址就是相对于地址0的偏移量,也就表示了该成员在整个类型中的相对偏移量,这是非常巧妙的地方。

28.个人认为的接口和类继承的区别,其实二者都可以实现相同的功用,那就是代码的复用和扩展,但是我们从字面意思上来理解继承,就是说继承并不是功能的简单堆砌,而是有着本质上相同的东西,比如我们对于继承惯常的描述:以汽车为基类,可以派生出,轿车,卡车,客车等等,再往下派生比如,轿车又可以分为A级,B级,C级等等,我们总可以从一个角度来对事物进行划分,这种的划分没有哪种是最正确的,甚至没有哪种划分是最合理的,但是划分的时候我们总是尽可能的选择一种相对而言贴近业务需要的划分方式,接着说,这种惯常的描述,这种的派生之所以有其合理性,是因为在本质上这些类的对象都是相同的,有着一脉相承的东西,他们都是汽车,但是接口就不同了,我们总是说一个类实现了哪些接口,而不是继承了某些接口,这样的一种叙述方式也表明了,我们用实现接口这样的形式来进行功能的拼接并没有继承的意味在里面,接口和实现接口的类并没有一个共有的本质。C++里面没有接口的概念,但这其实不影响我们用接口的方式来进行功能的拼接以及用接口的方式来看待C++中的一些继承,比方说,我们有一个虚基类,实际上只要是包含了纯虚函数的类,他们都是抽象基类,并且不能被实例化,为了实现类似于接口的方式来构造我们的类,我们可以定义一些抽象基类,然后再在其他的类中继承和实现抽象基类中的纯虚函数,那么这里的继承其实就没有之前的一脉相承的意味了,而是更加类似于 其他一些语言中的implement。我想以上就可以说明了传统意义上的继承和接口的关系。还有需要说明的是,接口实际上可以看作是一种规范,它使我们的代码在保持了封装独立的前提下,还可以对外提供友好的接口,如果是一个完全封闭的类,那就失去了类的意义了。

29.c++使用参数化列表的时候,classA(int a):m_a(a),base(a){cout<<this->a;}这个构造函数里面的this->a是正常使用的,如果在基类的构造函数中是使用this->a是不能正常使用的,因为基类的构造函数执行在先,而且如果基类中没有成员变量a,却在构造函数中使用了this->a这样是不合乎语法的,即使你已经知道派生类中会有这个成员变量存在.

30.关于define中的#和##

首先c语句中的""和宏中的""都会被当成是字符串,这会让#和##失效,#是让变量字符串化,而##是连结变量和宏展开中的字符

31.for(auto it:arr){}这是c++11中新增的数组集合遍历方式,for_each这是stl提供的方法

32.unique_ptr<int> pt(new int[100]);这是c++中提供的具有内存自动回收机制的指针

33.strtok可以相当于js中的split  用法比较特别

str="1,2,3,5,6,9,2";

pch=strtok(str,", ");

cout<<pch;

white(pch!=null)

{

cout<<pch;

pch=strtok(NULL,", ");

}

34.关于函数指针作为返回值的函数的定义

void (*func())(){}

紧跟func的一对括号中间是设置函数参数列表的位置,最后一对小括号是属于返回函数的参数列表,这个形式可以拆开来看1.先定义返回値类型和函数名 void (*func)()1.给函数加上参数列表 这里和惯常的参数列表的位置不同,一般我们认为参数列表是放在最后的或者说是花括号之前的,其实他的规则不是这样,而是参数列表紧跟函数名,因此这里需要void(*func())()这样的形式来添加参数列表,没有参数也要保留一对小括号

同样的还有返回数组的引用的函数

int (&foo()) [10]{}, 也体现了参数列表紧跟函数名称的特点。

35.const_cast<char*>可以将非常量値变成常量值。

36.一直不明白strchr是何缩写,现在想来应该是string charater,即在string查找一个character,返回值和即character在string中的位置

37.同样的道理strstr就是在目标字符串中查找子字符串而不是一个字符,返回値同样是一个位置

38.fseek更改文件指针的位置 ftell得到文件指针相对于初始位置的偏移量,这两个配合来得到文件的大小

39.c++可变参数

  1. #include <stdio.h>
  2. #include <stdarg.h>
  3.  
  4. double average(int num,...) {
  5.  
  6. va_list valist;
  7. double sum = 0.0;
  8. int i;
  9.  
  10. /* initialize valist for num number of arguments */
  11. va_start(valist, num);
  12.  
  13. /* access all the arguments assigned to valist */
  14. for (i = ; i < num; i++) {
  15. sum += va_arg(valist, int);
  16. }
  17.  
  18. /* clean memory reserved for valist */
  19. va_end(valist);
  20.  
  21. return sum/num;
  22. }
  23.  
  24. int main() {
  25. printf("Average of 2, 3, 4, 5 = %f\n", average(, ,,,));
  26. printf("Average of 5, 10, 15 = %f\n", average(, ,,));
  27. }

va_start 初始化可变参数列表

va_list 表示参数列表

va_arg 从va_list中取一个参数

va_end 清理参数列表的内存

40. __cdecl, __stdcall, __fastcall是三种不同的调用约定, __stdcall是由被调用者清楚参数栈,函数最后一句执行retn X用X指示清除的pop的字节数,

__cdecl,这指示由调用者清理参数栈,这是为什么在函数调用结束后,会有 add esp,4 add esp, 8这样一类的语句, __cdecl是默认的函数调用约定

__fastcall,指示参数是由寄存器传递的,也不存在谁清理栈的问题了

41.c++14也是支持闭包的,如下

auto a = [](auto n){ return [&](auto i){ return n += i; }; }(1);
cout << a(2) << endl;
cout << a(3) << endl;

42.一直搞不清move semantics, 原来是在翻译上有一些偏差, 在这里move不是一个形容词,而是一个动词,动作的对象是semantics, 也就是说将语义移动了, 改变了, 那么语义还能移动吗

右值引用的引入只是为了将rvalue区分出来,这么一区分就是为了配合move constructor, 以前不做区分的,现在做了区分就是要通过move constructor减少内存copy提高性能

43. C++往往有一些琐碎的限制规则,比如常对象,你不能调用const object的非const成员函数,而必须使用const 成员函数, 这大概是一种保护机制

44. 解决了一些理解上的偏差, rvalue reference 只是将可能被销毁的temporary object利用起来,减少了内存的copy和alloc 这里注意 "asdfasdfa" 对于const char *类型的temporary variable仍然要使用const char*&&的方式来使用,也就是说rvalue reference 并不能超越const的限制

45. 一个关于是左值还是右值的疑惑

void printRef(const char*&& str) {}

printRef("asdfasdfad");

参数"asdfasdfad"到底是右值还是左值,按照之前的理解, 这个字符串是一个临时变量应该是右值,其实不然,这里的参数实际上是一个const char *类型,也就是说,这个并不是一个临时的变量,只是他的值并不允许被改变

右值可以认为是expression所产生的一个临时的值

c++语法集锦的更多相关文章

  1. markdown语法集锦

    参考:http://wowubuntu.com/markdown/#blockquote 1. 标题 # 一级标题 ## 二级标题 ### 三级标题 共六级标题 2. 列表 有序列表:1,2,3: 无 ...

  2. CSDN-Markdown语法集锦

    前言: 使用Markdown近一个来月.越来越认为不舒爽. 改字体.改字号.改颜色.改样式,全不会!想加个数学公式.得,仅仅会截图.把图片传上去了还不会控制大小.也不会控制文字与图片的排版,写出来的博 ...

  3. SQL语法集锦一:显示每个类别最新更新的数据

    本文转载http://www.cnblogs.com/lxblog/archive/2012/09/28/2707504.html (1)显示每个类别最新更新的数据 在项目中经常遇到求每个类别最新显示 ...

  4. SQL语法集锦三:合并列值与分拆列值

    本文转载http://www.cnblogs.com/lxblog/archive/2012/09/29/2708724.html 在SQL中分拆列值和合并列值老生常谈了,从网上搜刮了一下并记录下来, ...

  5. SQL语法集锦一:SQL语句实现表的横向聚合

    本文转载:http://www.cnblogs.com/lxblog/archive/2012/09/29/2708128.html 问题描述:假如有一表结构和数据如下: C1 C2 C3 C4 C5 ...

  6. 玩转Web之JavaScript(三)-----javaScript语法总结(三) 窗口/滚动条/文本的相关语法

    JS语法集锦(三) 窗口/滚动条/文本 alert("文本")    警告框:警告框经常用于确保用户可以得到某些信息,当警告框出现后,用户需要点击确定按钮才能继续进行操作. con ...

  7. MathJax使用指南

    MathJax使用指南 SublimePrettyJson Github CSDN-Markdown语法集锦 LaTex 简明教程 在Markdown中输入数学公式(MathJax) MathJax ...

  8. SQLServer、MySQL、Oracle语法差异小集锦

    一.差异集锦 在建表的时候,只有自增的语法不同. 下面给出3种数据库通用的建表与初始化测试语句: CREATE TABLE Country( Id int PRIMARY KEY, Name ) ); ...

  9. ES6语法糖集锦

    sublime3安装Es6插件 javascriptNext,然后安装即可 Java​Script​Next - ES6 Syntax()高亮插件 -------------------------- ...

随机推荐

  1. 团队SCRUM会议(第一次)

    每日Scrum:第一天 会议时间:4.30.晚八点半 会议地点:基础教学楼一楼大厅 小组成员:郭庆樑,林彦汝,张金 团队PM:张金 会议进程 • 首先我们讨论了实验第一个Sprint1要实现的功能,我 ...

  2. UIViewController添加子控制器(addChildViewController)

    // //  TaskHallViewController.m //  yybjproject // //  Created by bingjun on 15/10/27. //  Copyright ...

  3. Python学习路程day3

    set集合 ​set是一个无序且不重复的元素集合,访问速度快,天生解决重复问题 s1 = set() s1.add('luo')​ s2 = set (['luo','wu','wei','ling' ...

  4. hdu 2037

    PS:   - -原本想的是排序开始时间和消耗时间..后来想到可以排序结束时间..后来还wa了一次,因为排序的时候溢出了 思路: 1 3 //13 4 //20 7 3 8 2 9 5 10 //36 ...

  5. python saltstack

    1. 拷贝文件 # salt ‘*‘ cp.get_file salt://first.xml /tmp/first.xml 或 gzip=1-9,数字越大,压缩越高; makedirs=True 自 ...

  6. 技术解析:锁屏绕过,三星Galaxy系列手机也能“被”呼出电话

    近期,由两位安全研究人员,Roberto Paleari及Aristide Fattori,发布了关于三星Galaxy手机设备安全漏洞的技术细节.据称,Galaxy手机可在锁屏状态下被未授权的第三方人 ...

  7. [转]设计模式(22)-Strategy Pattern

    一. 策略(Strategy)模式 策略模式的用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 假 设现 ...

  8. C#山寨版本【天翼拨号客户端】---内含详细抓包,模拟数据---万事俱备,只欠东风。

    官方的客户端的最大缺点: 1.一台电脑不允许使用同时启动多个网卡(目的是禁止使用虚拟WIFI或通过网卡后共享网络到路由器?): 2.使用路由器无法拨号(提示:不允许NAT后登录) 3.之前用某哥们破解 ...

  9. mysql [ERROR] Can't create IP socket: Permission denied

    /*************************************************************************** * mysql [ERROR] Can't c ...

  10. Ubuntu安装文泉驿-微米黑字体

    sudo apt-get install ttf-wqy-microhei #文泉驿-微米黑