编程基础文章目录:
五大基础算法 | 基础数据结构(栈和队列) | 散列表 |
常见C++知识 | 基础数据结构(数组、串、广义表) | 四大比较排序算法 |
基础数据结构(线性表) | 基础数据结构(树和堆) |
微博:LinJM-机器视觉 Blogger:LinJM
这一篇其实是流水账,主要记录我查阅过的C++知识。
static const size_type npos = -1;
This is a special value equal to the maximum value representable by the type size_type. The exact meaning depends on context, but it is generally used either as end of string indicator by the functions that expect a string index or as the error indicator by the functions that return a string index.
查找字符串a是否包含子串b,
不是用strA.find(strB) > 0而是strA.find(strB) != string:npos
string::size_type pos = strA.find(strB);
if(pos != string::npos){}
memset
用来对一段内存空间全部设置为某个字符,一般用在对定义的字符串进行初始化为' '或'\0'。
void * memset ( void * ptr, int value, size_t num );
fputs函数和fflush函数
int fputs ( const char * str, FILE * stream );
int fflush ( FILE * stream );
关于*&连用的意思
template <class S, class T> static inline void clone(T*& dst, S* src, int n) { dst = new T[n]; memcpy((void *)dst,(void *)src,sizeof(T)*n); }上面clone函数里有T*& dst这个参数。下面看知乎上的一段回答:
memcpy函数
void * memcpy ( void * destination, const void * source, size_t num );
/* memcpy example */ #include <stdio.h> #include <string.h> struct { char name[40]; int age; } person, person_copy; int main () { char myname[] = "Pierre de Fermat"; /* using memcpy to copy string: */ memcpy ( person.name, myname, strlen(myname)+1 ); person.age = 46; /* using memcpy to copy structure: */ memcpy ( &person_copy, &person, sizeof(person) ); printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age ); return 0; }
在c++中,为了解决一些频繁调用的小函数大量消耗栈空间或者是叫栈内存的问题,特别的引入了inline修饰符,表示为内联函数。 如svm.cpp中的一段代码:
#ifndef min template <class T> static inline T min(T x,T y) { return (x<y)?x:y; }//static函数只能在本文件中使用 #endif #ifndef max template <class T> static inline T max(T x,T y) { return (x>y)?x:y; } #endif
定义在<stdio.h>中,是格式转换函数,即按用户指定的格式从键盘上把数据输入到指定的变量中。
成功输入则返回“1”。
C++中防止头文件被包含两次有两种方法解决:
【A:保护宏】
#ifndef _ABCDE_H #define _ABCDE_H //代码部分 #endif
在被包含过一次之后,宏_ABCDE_H已经有了,下次再碰到就会略过从#define _ABCDE_H开始到#endif之间的代码【B:还有一种特定编译器支持的指令:】
b.#pragma once
能保证该文件(物理上的)只被编译一次,也能起到防止重复包含的作用
但这2种方式是有区别的:
a.Macro guard可移植性好,绝大多数编译器都支持,而且万一不小心拷贝了几分相同的代码也不会出问题,但你得确保这个宏名不会与其他的宏冲突,否则等编译器报出一大堆错误的时候你可能会觉得莫名其妙;
b.#pragma once指令简单,它能保证该文件(物理上的)只被编译一次,不用去费劲的想不同的宏名,但如果有几份该文件的拷贝,显然起不到作用。
Debug 通常称为调试版本,它包含调试信息,并且不作任何优化,便于程序员调试程序。Release 称为发布版本,它往往是进行了各种优化,使得程序在代码大小和运行速度上都是最优的,以便用户很好地使用。
更多细节:VC++中Debug调试版本和Release发行版本的区别
static关键字可以用于声明变量、函数、类数据成员、类函数。
By default, an object or variable that is defined outside all blocks has static duration and external linkage. Static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends. External linkage means that the name of the variable is visible from outside the file in which the variable is declared. Conversely, internal linkage means that the name is not visible outside the file in which the variable is declared.
The static keyword can be used in the following situations.
一个变量如果位于函数的作用域内,但生命周期却跨越了这个函数的多次调用,则将这样的对象定义为static(静态的)。static局部对象确保不迟于在程序执行流程第一次经过该对象的定义语句时进行初始化。这种对象一旦被创建,在程序结束前都不会被撤销。当定义静态局部对象的函数结束时,静态局部对象不会撤销。在该函数的多次调用的过程中,静态局部对象会持续存在并保持它的值。《C++ Primer 4th》pp220
size_t count_calls() { static size_t ctr = 0; //value will persist across calls return ++ctr; } int main() { for (size_t i = 0; i != 10; ++i) cout << count_calls() << endl; return 0; }
C++中引入了ostringstream、istringstream、stringstream这三个类,要使用他们创建对象就必须包含sstream.h头文件。
stringstream通常用于做数据转换。
istringstream类是从istream和stringstreambase派生而来,ostringstream是从ostream和 stringstreambase派生而来, stringstream则是从iostream类和stringstreambase派生而来。它们的继承关系如下:
#include <string> #include <sstream> #include <iostream> int main() { std::stringstream stream; std::string result; int i = 10000; stream << i; //将int输入流 stream >> result; //从stream中抽取前面插入的int值 std::cout<<result <<std::endl;//print the string “10000” }更多细节:C++ stringstream介绍,使用方法与例子
explicit关键字只能用于类内部的构造函数声明上。
我们可以将构造函数声明为explicit,来防止在需要隐式转换的上下文使用构造函数(当构造函数被声明为explicit时,编译器将不使用它作为转换操作符)
更多细节:Explicit 关键字
1、定义const对象
const限定符提供了一个解决办法,它把一个对象转换成一个常量。
const int bufSize = 512;
现在任何修改bufSize的尝试都会导致编译错误。因为常量在定义后就不能修改,所以定义时必须初始化。
const std::string hi = "hello!"; //OK
const int i, j = 0; //error,i没有初始化
2、const对象默认为文件的局部变量
非const变量默认为extern。要使const变量能够在其他文件中访问,必须显示指定它为extern。
3、const引用
const引用是指向const对象的引用。
const int ival = 1024;
const int &refVal = ival; // OK
int &ref2 = ival; // error , 可以读取但不能修改
4、指向const对象的指针
若指针指向const对象,则不允许使用指针来改变其所指的const值。
为了保证这个特性,C++强制要求指向const对象的指针也必须具有const特性。
const double * cptr;
这里的cptr是一个指向double类型const对象的指针,const限定了cptr指针所指向的对象类型,而并非cptr本身,即cptr本身并不是const。在定义时不需要对它进行初始化,若需要允许给cptr重新赋值,使其指向另一个const对象,但不能通过cptr修改其所指对象的值。
在实际程序中,指向const的指针常用作函数的形参,将形参定义为指向const的指针以此确保传递给函数的实际对象在函数中不因为形参而被修改。
5、const指针
const指针本身的值不能被修改。
const指针的值不能修改,这意味着不能使curErr指向其他对象。任何企图给const指针赋值的行为都会导致编译错误。int errNumb = 0;
int *const curErr = &errNumb;
6、指针和typedef
在typedef中使用指针往往会带来意外的结果。下面是一个几乎所有人刚开始都会答错的问题。假定给出以下语句:
typedef string* pstring;
const pstring cstr; // const string * cstr;
请问cstr是什么类型?
很多人会认为是const string * cstr。也就是说,const pstring是一种指针,指向string类型的const对象,但是这是错误的。错误的原因在于将typedef看作文本扩展。
声明const pstring时,const修饰的是pstring的类型,这是一个指针。因此,该声明语句是把cstr定义为指向string类型对象的const指针,这个定义等价于:
string *const cstr:
C++程序通常由许多文件组成。为了让多个文件访问相同的变量,C++区分了声明和定义。
变量的定义(definition)用于为变量分配存储空间,还可以为变量指定初始值。在一个程序中,变量有且只有一个定义。
声明(declaration)用于向程序表明变量的类型和名字。定义也是声明:当定义变量时我们声明了它的类型和名字。可以通过extern关键字声明变量名而不是定义它。不定义变量的声明包括对象名、对象类型和对象类型前的关键字extern:
extern int i; // declares but does not define i
int i; // declares and defines i
extern声明不是定义,也不分配存储空间。事实上,它只是说明变量定义在程序的其他地方。程序中变量可以声明很多次,但是只能定义一次。
静态全局变量在声明它的整个文件都可见,而在文件之外是不可见的(这样其他文件可以定义相同名字的变量,不冲突)
在类内数据成员的声明前加上关键字static。
静态数据成员被当作类的成员,无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝。由该类型的所有对象共享访问。
静态数据成员 初始化:
<数据类型><类名>::<静态数据成员名> = <值>
在类外进行初始化。
使用传值方式,把实参的值传给函数局部工作区相应的副本中,函数使用这个副本执行必要的功能。这样,函数修改的是副本的值,实参的值不变
使用引用传递参数,需要将形参声明为引用,当一个实参与一个引用形参结合时,传递的是实参地址。节省传递参数时间和副本空间。
动态存储分配 new 和delete
Point *p = new Point[100];
delete [] p;
参考文献:
[1] C++ 头文件[.h]中保护宏的用法 [EB/OL]. [2013-12-23].http://blog.sina.com.cn/s/blog_656c58ac0101fhoz.html
[2] VC++中Debug调试版本和Release发行版本的区别[EB/OL].[2013-12-23]. http://blog.csdn.net/yeyang911/article/details/12951611
[3] MSDN STATIC(C++)http://msdn.microsoft.com/en-us/library/s1sb61xd.aspx
[4] Lippman S B, Lajoie J, Moo B E, et al. C++ PRIMER 中文版: 特别版[M]. 人民邮电出版社, 2010.