c语言

lint  /splint

---------------------------------------------------------------------------------

左值表示存存储在计算机内存中的对象

NUL  结束一个ACSII字符串

NULL表示什么也不指向

---------------------------------------------------------------------------------

静态链接只装入需要的函数

cc main.c -lm  记住库放最后,最基础的放最后边,左边依赖右边

nm  -sx a.out 查找符号表 

size /dump

ldd

---------------------------------------------------------------------------------

检查源码工具
cb
indent
cdecl
cflow 打印程序中调用被调用者关系
cscope
ctags
lint
sccs 源码版本控制系统
vgrind 格式器

检查可执行文件的工具
dis 目标代码反汇编工具
dump -Lv 打印动态链接信息
ldd
nm
strings
sum

帮助调试工具
truss
ps
ctrace
debugger
file

性能优化工具
gprof
prof
tcov
time

---------------------------------------------------------------------------------

BSS "Block Started by Symbol" "Better Save Space" 不占目标文件空间 只保存没有值的变量

alloca() 分配的内存在stack
/usr/include/sys/frame.h 过程活动记录
<setjmp.h>
setjmp() longjmp() == c++ catch throm

---------------------------------------------------------------------------------

作为函数定义的形式参数 或 表达式中    数组=指针

没有办法把数组本身传给一个函数,因为它总是被自动转换为指向数组的指针。所以要给个长度

a[i] 编译器解释为 *(a+1)

---------------------------------------------------------------------------------

__FILE__ 文件名

__LINE__ 当前行号

__TIME__ 文件被编译的时间

__DATE__ 文件被编译的日期

<stdexcept>

<exception>

<type_info>

---------------------------------------------------------------------------------

具有 const 形 参或非 const 形参的函数并无区别

如果使用引用形参的唯一目的是避免复制实参,则应将形参定 义为 const 引用

编译器忽略为任何数组形参指定的长度

大部分情况下,数 组以普通的非引用类型传递,此时数组会悄悄地转换为指针。一般来说,非引用 类型的形参会初始化为其相应实参的副本。而在传递数组时,实参是指向数组第 一个元素的指针,形参复制的是这个指针的值,而不是数组元素本身。函数操纵 的是指针的副本,因此不会修改实参指针的值。然而,函数可通过该指针改变它 所指向的数组元素的值。通过指针形参做的任何改变都在修改数组元素本身

如果形参是数组的引用, 编译器不会将数组实参转化为指针,而是传递数组的引用本身。在这种情况下, 数组大小成为形参和实参类型的一部分

C++ 程序,只能将简单数据类型传递给含有省略符形参的 函数。实际上,当需要传递给省略符形参时,大多数类类型对 象都不能正确地复制 省略符暂停了类型检查机制

内联函数应该在头文件中定义,这一点不同于其他函数

注意不能基于指针本身是否为 const 来实现函数的重载:

     f(int *);

     f(int *const); // redeclaration

 

int (*ff(int))(int*, int); 阅读函数指针声明的最佳方法是从声明的名字开始由里而 外理解。

要理解该声明的含义,首先观察: ff(int)

将 ff 声明为一个函数,它带有一个 int 型的形参。该函数返回 int (*)(int*, int);

---------------------------------------------------------------------------------

IO 对象不可复制或赋值 

只有支持复制的元 素类型可以存储在 vector 或其他容器类型里。由于流对象不能复制,因此不能 存储在 vector(或其他)容器中

形参或返回类型也不能为流类型 

对 IO 对象的读写会改变它的状态,因此引用必须是非 const 的

 

如果需要刷新所有输出,最好使用 unitbuf 操纵符 

nounitbuf 操纵符将流恢复为使用正常的、由系统管理的缓冲区刷新方式

为了确保用户看到程序实际上处理的所有输出,最好的方法 是保证所有的输出操作都显式地调用了 flush 或 endl。

---------------------------------------------------------------------------------

在容器中添加元素时,系统是将元素值复制到容器里

s.find( args)在 s 中查找 args 的第一次出现

s.rfind( args)在 s 中查找 args 的最后一次出现

 s.find_first_of( args)在 s 中查找 args 的任意字符的第一次出现

s.find_last_of( args)在 s 中查找 args 的任意字符的最后一次出现

s.find_first_not_of( args)在 s 中查找第一个不属于 args 的字符

s.find_last_not_of( args)在 s 中查找最后一个不属于 args 的字符

适配器(adaptor)是标准库中通用的概念,包括容 器适配器、迭代器适配器和函数适配器。本质上,适配器是使一事物的行为类似 于另一事物的行为的一种机制。容器适配器让一种已存在的容器类型采用另一种 不同的抽象类型的工作方式实现。例如,stack(栈)适配器可使任何一种顺序 容器以栈的方式工作

默认的 stack 和 queue 都基于 deque 容器实现,而 priority_queue 则 在 vector 容器上实现

 

stack 适配器 所关联的基础容器可以是任意一种顺序容器类型.

因此,stack 栈可以建立在 vector、list 或者 deque 容器之上。而 queue 适配器要求其关联的基础容器 必须提供 push_front 运算,因此只能建立在 list 容器上,而不能建立在 vector 容器上。priority_queue 适配器要求提供随机访问功能,因此可建立在 vector 或 deque 容器上,但不能建立在 list 容器上

 

map<K,V>::key_type 在 map 容器中,用做索引的键的类型

 

map<K,V>::mapped_type在 map 容器中,键所关联的值的类型

 

map<K,V>::value_type一个 pair 类型,它的 first 元素具有 const map<K, V>::key_type 类型,而 second 元素则为 map<K, V>::mapped_type 类型

对于 map 容器,如果下标所表示的键在容器中不存在,则添加新元素

 

m.count(k)  返回 m 中 k 的出现次数

m.find(k) 如果 m 容器中存在按 k 索引的元素,则返回指向该元素的迭代

set 存储的元素仅仅 是键,而没有所关联的值 

set 容器只是单纯的键的集合

正如不能修改 map 中元素的键部分一样,set 中的键也为 const

 

m.lower_bound(k)返回一个迭代器,指向键不小于 k 的第一个元素

m.upper_bound(k)返回一个迭代器,指向键大于 k 的第一个元素

m.equal_range(k)返回一个迭代器的 pair 对象它的 first 成员等价于 m.

 ---------------------------------------------------------------------------------

算法永不执行容器提供的操作

使用“普通”的迭代器时,算法从不修

改基础容器的大小。正如我们所看到的,算法也许会改变存储在容器中

的元素的值,也许会在容器内移动元素,但是,算法从不直接添加或删

除元素

find_first_of,带有两对迭代器参数。每对迭代器中, 两个实参的类型必须精确匹配,但不要求两对之间的类型匹配。特别是, 元素可存储在不同类型序列中,只要这两序列的元素可以比较即可

vector<int> vec; // empty vector

// ok: back_inserter creates an insert iterator that adds elements to vec

fill_n (back_inserter(vec), 10, 0); // appends 10 elements to vec

back_inserter 函数是迭代器适配器 

back_inserter 生 成一个绑定在该容器上的插入迭代器。在试图通过这个迭代器给元素赋值时,赋 值运算将调用 push_back 在容器中添加一个具有指定值的元素

back_inserter,创建使用 push_back 实现插入的迭代器。

front_inserter,使用 push_front 实现插入。

inserter,使用 insert 实现插入操作。除了所关联的容器外,inserter

   还带有第二实参:指向插入起始位置的迭代器

 

istream_iterator 用于读取输入流,而 ostream_iterator 则用 于写输出流

尽管 map 和 set 类型提供双向迭代器,但关联容器只能使用算法的一 个子集。问题在于:关联容器的键是 const 对象。因此,关联容器不能 使用任何写序列元素的算法。只能使用与关联容器绑在一起的迭代器来 提供用于读操作的实参。

     在处理算法时,最好将关联容器上的迭代器视为支

     持自减运算的输入迭代器,而不是完整的双向迭代

     器。

 ---------------------------------------------------------------------------------

普通的非 const 成员函数中,this 的类型是一个指向类类型的 const 指针,可以改变 this 所指向的值,但不能改变 this 所保存 的地址

在 const 成员函数中,this 的类型是一个指向 const 类类型对象的 const 指针。既不能改变 this 所指向的对象,也不能改变 this 所保存的地址

不能从 const 成员函数返回指向类对象的普通引用。const 成 员函数只能返回 *this 作为一个 const 引用

要将数据成员声明为可变的,必须将关键字 mutable 放在成员声明之前

 

形参表和函数体处于类作用域中

函数返回类型不一定在类作用域中

只要创建该类型的一个对象,编译器就运行一个构造函数

构造函数的工作是初始化对象。不管对象是 否为 const,都用一个构造函数来初始化化该对象

抑制由构造函数定义的隐式转换

可以通过将构造函数声明为 explicit,来防止在需要隐式转换的上下文中 使用构造函数

explicit 定义上不再重复它 关键字只能用于类内部的构造函数声明上

 ---------------------------------------------------------------------------------

复制构造函数、赋值操作符和析构函数总称为复制控制。编译器自动实现这 些操作,但类也可以定义自己的版本 

有一种特别常见的情况需要类定义自己的 复制控制成员的:类具有指针成员

直接初始化 直接调用与实参匹配的构造函数,复制初始化总是调用复制构造函数。复制初始 化首先使用指定构造函数创建一个临时对象,然后用复制构造 函数将那个临时对象复制到正在创建的对象

 

声明而不定义成员函数是合法的,但是,使用未定义成员的任何尝试将导致 链接失败。通过声明(但不定义)private 复制构造函数,可以禁止任何复制类 类型对象的尝试:用户代码中复制尝试将在编译时标记为错误,而成员函数和友 元中的复制尝试将在链接时导致错误

如果定义了复制构造函数,也必须定义默认构造函 数

如果类需要析构函数,则它也需要赋值操作符和复制构造函 数,这是一个有用的经验法则。这个规则常称为三法则,指 的是如果需要析构函数,则需要所有这三个复制控制成员

 

 ---------------------------------------------------------------------------------

以下4个操作符不能重载

:: .*.?:

重载操作符必须具有一个类类型操作数 

优先级和结合性是固定的

不再具备短路求值特性

类通常将 IO 操作符设为友元

赋值必须返回对 *this 的引用

plus<Type>

minus<Type>

multiplies<Type>

divides<Type>

modulus<Type>

negate<Type>

 

equal_to<Type>

not_equal_to<Type>

greater<Type>

greater_equal<Type>

less<Type>

less_equal<Type>

 

logical_and<Type>

logical_or<Type>

logical_not<Type>

bind1st 将给定值绑定到二元函数对

象的第一个实参,bind2nd 将给定值绑定到二元函数对象的第二个实参

count_if(vec.begin(), vec.end(),

              bind2nd(less_equal<int>(), 10));

count_if(vec.begin(), vec.end(),

             not1(bind2nd(less_equal<int>(), 10)));

 

auto_ptr 对象只能保存一个指向对象的指针,并且不能用于指向动态分配 的数组

====================

char* sql=“xxx” “ff”;   

原文地址:https://www.cnblogs.com/anjsxz/p/3740449.html