,C++Primer初级:
预处理(E查看)->编译(S查看)->连接 13_枚举:可以尽可能多用枚举,多个const变量,可以用枚举去做; string name("aaa"); //定义,初始化
string::size_type size = name.size(); //字符个数,保证可以获得对应的大小,int size = name.size(); 这个不安全
name.empty() 判断是否为空
字符串相加,是表示将两个连接起来,但是两个不能都是字符串字面值
例如 name+name2,但是不能“aa”+“bb”
ispunct(name[i])判断某个字符是否是标点符号(头文件cctype)
字符串的输入,不能用cin要用getline,然后用for循环,检查输入的字符串的每一个字符 vector 动态数组,其实是个类类型,一般可以替换到普通的数组。
常用里面的empty(),vector<int>::size_type, v.size(),和v.push_back();
vector begin(),返回一个迭代器,vector<int>::iterator iter = v.begin; 迭代器实质上是一个指针,所以可以给该值赋值*iter=;
一般用迭代器替代下标,例如用vector<int>::size_type idx=;
可以for(vector<int>::iterator i=v.begin();i!=v.end();i++){
cout <<"迭代器 "<<*i<<endl;//这样可以通过*i获得vector v中的元素;即迭代器是个指针,这比下标取元素简单多了,尽量多使用迭代器方式,少用下标形式取元素
}
常迭代器与非常迭代器,区别为,不可以与可以通过迭代你修改数据
例如 vector<int>::const_iterator i = v.begin(); 常迭代器常用来读取数值,不用常迭代器修改数据; bitset<> a() 将156按二进制存储,到32位大小空间中。
a.any(); 判断是否有1,a.none()判断没有一个1,a.count() a有几个1.a.size()获得a的大小;a.set(index) 设置某位为1。或者直接下标写法,a[index]; a.set() 设置所有的为1. reset是变为0; void*指针,是万能指针,可以指向任意的类型。但是这种指针不能通过其操作对象。
常指针才能指向常对象;普通指针不行,常指针必须初始化。常指针(常用来传递参数,防止修改参数)可以指向非常对象,这样之后,不能通过指针来修改其对象的值,也不能修改其指向再指向其他的对象。
举例:
#typedef string *pstring;
const pstring cpst; 与string *const cpst1;等同(常指针,指向字符串,必须初始化),与const string *cpst2;不同,指向常字符串指针,不用必须初始化
int a[]={, , , , , }
int *ip1=a; //指针可以可以看做数组的迭代器。
int *ip2 = a+;
ptrdiff_t a=ip2-ip1;得到地址差。即a=;相差四个数 引用声明时,必须初始化。指针可以不用 c风格的字符串,必须用\0结束。
char a1[] = {'a', 'b', '\0'};是
char a2[] = "ab";是
char a3[] = {'a', 'b'} 不是,只是c风格的字符数组
const char *a4 = "ab";是
strlen(a2);计算结果不包括\
c风格的字符比较,用strcmp;而c++风格的字符串string类型,可以直接比较。字符串string类型可以s1>s2,s1==s2。但是c风格的字符不能a1==a2等操作,这样操作的仅仅是地址。而不是内部的值;
c风格的字符不能用=做拷贝,必须用strcpy(a1,a2);。strcat(a1,a2);c风格的字符串连接,c++的string类型的连接直接用+号,
标准库中strcmp,strcpy,strcat等都比较危险。一般使用带n的方法,例如strncmp,strncpy,strncat等,strncpy(a1,a2,);n制定了拷贝的大小。不然很多黑客可以利用这些漏洞,可以修改里面的东西(缓冲区溢出攻击)。尽可能使用c++风格的字符串string类型。 动态数组创建,c语言,malloc(n*sizeof(int)),free(a)。c++ new int[n]和delete[] a;
int *a = new int[];没有初始化。int *a = new int[]();初始化了
string *astr = new string[];使用默认的构造函数进行初始化;
数组等的循环,一般用指针,专业点,可以认为指针是数组的迭代器。
int *ai = new int[];
for(int *p= ai; p!=ai+; ++p){
*p=;//通常通过指针作为迭代器,给数组ai循环初始化操作;
} c与c++转换
string 和char相互转换:string类型用c_str()转换后赋值的时候,对象必须是const,const char *= st.c_str();
数组和vector转换:int a[]={,,,,,}; vector<int> v(a, a+); 复制的时候,后面的是不包括的,所以是a+,而不是a+,或者用迭代器vector<int>::const_iterator
vector<int> ivec;
int ival; //tmp变量,很重要
while(cin>>ival){ivec.push_back(ival) }//input data to vector; 创建动态数组 int *a = new int[ivec.size()];动态创建一个数组
字符串数组的c实现为:
vector<string> svec;
string sval;
while(cin>>sval) svec.push_back(sval);
char **c = new char*[svec.size()]; //赋值时,注意最后一个是\0
赋值可用中间变量char *tmp = new char[svec.size()];
然后将c[i]=tmp; //因为c是二重指针,所以存放的是地址;释放的时候也得用for循环。 多重数组
int a[n1][n2]; int (*ip)[];//注ip是一个指针
常常用typedef简化指向数组的指针,例如:#typedef int int_array[];然后,写int_array *ip;与以上的ip一样;这样可以避免丢失括号而导致ip不是指针的问题,ip=a;表示指向a的第一行,即ip是一个指针,所以使用ip取a中值时,还得使用一个指针;
int *ip[]; //ip是一个数组,区分以上的有括号的情况 算术运算符
double /; 会等于3,除号是整除和小数除
cout<<-/-;会等于-,如果一正一负,结果可能是正也可能是负 -/ c++中是不确定的 箭头操作符与指针
Dog *p;
p=new Dog();
p->foo(); 和(*p).foo();等同,其中,foo为类Dog的方法
指针的指针,一般用一个临时指针,将中间值赋值给它;
vector<string*> spvec;
string str;
while(cin>>str)
{ string *pstr = new string;//相当于临时指针
*pstr=str;
spvec.push_back(pstr);
}
这里一定要释放
vector<*string>::iter = spvec.begin();
while(iter != spvec.end()){ delet e * iter;iter++;} //一般不直接操作spvec,而是通过迭代器,操作。 条件操作符,一般if 类型的可以用这个替换(a>b)?a:b; 不过慎用,避免嵌套,看起来繁杂不好理解 new delete
new的时候,如果是内置类型,一般要用括号;
例如int *a = new int();调用默认构造函数初始化
如果int *a = new int; 如果是内置类型,则没有初始化,很危险。
如果是在类类型,在main中创建的,这是等同的;所有的new 一定要使用delete撤销 强制类型转换符
C++新式的static_cast dynamic_cast reinterpret_cast const_cast 和传统C风格的;
举例:double dPi=3.1415926; int nNum=static_cast<int>(dPi);//这种啰嗦的写法提醒作者注意,这里用了强制转换,其实是和C风格一样
避免使用强制类型转换,C++一般不提倡c风格的在转换,因为没有检查,而dynamic_cast等,如果转换成果,返回值不为空,如果为空,表示转换不成果,例如:int n = dynamic_cast<int>(val);可以使用if(n) 判断是否成功 文件操作,抛出异常try catch,throw相结合的方式
FILE *input=fopen("a.txt", "rb");//常常对fopen进行判断,是否打开成功
FILE *output=fopen("b.txt", "rb");
一定要记得关闭fclose(input);fclose(output);
int size = fread(dst, sizeof(float), num, input);//size为读取的实质大小,dst为目标存储位置,sizeof(float)每次读多大的大小,num是总共读多少,input为输入文件流
int size_out = fwrite(dst, sizeof(float), num, output);//这里
用if(input==NULL) throw ;//抛出异常,可以输出,数字,字符串,类对象。
代替if(input==NULL) return ;
int func(){FILE *input =fopen("a.txt","rb");if (input==NULL) throw ;}然后用以下部分处理异常;
try{func();}catch(int e){printf("e:%d",e);} catch(const char *e){} 标准异常类:exception,runtime_error rang_error,invalid_argument在stdexcept中),bad_alloc在头文件<new>中,
例如:try{}catch(bad_alloc err){cout<<"allocate exception";}
int function(int a){if(a<)throw out_of_range("data not lower zero");}//定义自己的异常程序。调用的时候,用try catch即可。
设计自己的异常类,可以在自己定义的类中,添加类成员,这个类成员一般可以继承已有的异常类,然后实现里面的what方法:virtual const char *what() const throw(){ return "your message";} 使用预处理进行调试,
第一使用#ifndef NDEBUG 方式,二,assert(头文件cassert)
获取对应的信息,三,使用__FILE__ __LINE__ __DATE__ __TIME__ 直接和内部定义的宏一样返回对应的文件位置,行数,日期时间等,直接使用。assert(==(+)),如果不相等,则返回详细错误信息。其中NDEBUG为内部定义的宏,不使用调试的意思,如果用了,assert也将不起作用 引用形参;目的:一为了修改值,能传递回来,第二,防止赋值,降低操作时间,第三,使用const,避免修改
function(string a); 如果传递进去的a过长a="aaaaaaaaaaaaaaaaaaaaaa";会导致效率低下,特别是对a还不做修改时,强烈建议使用const 引用。function(const string &a);
指针引用 function(int *&val)val是个引用类型,同时也是指针。
例如:定义交换指针函数 swap(int *&a, int *&b); int a=; int b=; int *pa=&a; int *pb=&b;
swap(pa, pb);最后pa指向了b,pb指向了a。 vector list deque作为形参的时候,一般不是直接传递进入的,而是使用迭代器作为形参
例如:function(vector<int>::iterator begin, vector<int>::iterator end); 返回值为引用或者指针的时候,一定要注意,不要反悔一个函数结束时,此变量就不存在的对象:例如:int * function(){ int a = ; return a;}//这是很危险的,因为函数结束的时候,a就不存在了。切记。常引用或指针,不能赋值给非常引用或指针;
举例:改变字符串中的某个字符
char & change_s(string &str, int i){return str[i];}
调用时 string strv("aaa"); char &c=change_s(str,); c="i"; //结果str变为了aia;因为这里传递进去的是引用,返回的也是引用,多以对原来的变量进行了修改,也是对原来的引用变量修改。而不是赋值操作,一定要区别,并且返回为引用指针的时候,一定要小心; 大量的递归调用会占用内存和时间。默认实参,一般在函数声明处写。 内联函数一般放在头文件中,节省时间开销,递归和大函数,避免使用内联函数,内联函数在编译的时候,会展开。可以理解为避免了调用操作,而是直接展开替代。内联函数的编译对编译器来说,必须是可见的,所以一般得放在头文件中。 class
要变成对象了,才能使用,在类的定义中,没有对象,一般用this(类似于参数)表示,也可以不写,写上更好,表示这个变量时当前对象的。
例如
class Sale{
private:
bool val;
public:
bool function(const Sale sa){
this->val = sa.val; //this表示这里Sale的对象,不是这里的sa
}
}
只有静态成员才能直接使用初始化,一般的变量只能通过构造函数进行初始化,初始化的时候,一般用初始化列表形式进行初始化例如上面的用Sale():val(true),val1(){};多个变量可以使用","号隔开。初始化过程中,一般基本的数据类型都必须初始化,一些有默认进行初始化的类型,不用进行初始化,例如string类型,就可以不用初始化,会使用默认的初始值进行初始化 重载与作用域:
重载函数一定要写到一个作用域。防止函数被屏蔽或隐藏现象。
变量名和函数名同名,可能导致函数屏蔽:例如 int init = ; int a = init();其中init()为函数,这样会导致函数init();函数不可见,会出错,这种现象叫函数隐藏或者屏蔽。function(int *const a);和function(int *a);不能构成重载,但是function(int *a); 和function(const int *a);构成重载; 指向函数的指针(函数指针变量)(一般用typedef简化其声明)
bool (*pf)(int a, int b);声明了一个指向函数的指针,表示指向函数类型为参数表为(int, int)返回值为bool类型的函数指针,这里的(*pf)不能去掉。调用的时候,就是
pf=functionname;或者pf=&functionname 然后直接使用pf(,);或者(*pf)(,);.和调用functionname(,)一样。因为使用函数指针的时候,写起来太复杂。所以一般使用typedef 简化。
例如:typedef bool (*dPf)(int a, int b); 在使用的时候,就直接使用dPf pf;声明函数指针变量,就像直接使用bool (*pf)(int a, int b);一样,并且可以方便的定义多个函数指针变量,dPf pf1, pf2;非常方便。函数指针因为是个变量,所以可以作为函数形参,例如一个函数调用另外一个函数的时候,可以将另外一个函数的指针传递进入,实现一个函数调用另外一个函数。函数指针的形参必须和指向的函数的参数类型精确匹配。 流对象是不能复制的,所以要传递流对象的时候,一般用引用类型或者指针。
int function(ofstream ofs); ofstream of; 使用的时候function(of)会失败,因为流对象不能复制。把函数改为int function(ofstream &ofs)后,则可以这么使用了。 流的条件状态。if(cin.bad()) cin.fail() cin.eof() cin.good() cin.ignore(, "\n"),要么忽略前两百个,要么忽略到\n. cin.setstate(XXX), cin.rdstate()等等
如果输入int a; cin>>a,你输入的str,check这个流的状态的时候,可以知道cin.fail()为真,也就是这个输入是失败的。cin.clear()流状态清理到正常的 状态
流对象的字符串为C风格的字符串,例如ofstream f; f.open(str.c_str()) 逗号运算符,是逗号后面的为条件。例如while(cin>>a, !cin.eof()),其实while(cin>>a)当eof fail bad的时候会结束输入。而while(cin>>a, !cin.eof())只有到流的末尾时,才结束。另外注意,文件流的状态不会因为close了,而跟新,所以连续的用某个流open文件的时候,一定要记得用clear来恢复流的状态,然后再使用。
ifstream fs("file.txt"); 或者 ifstream fs;fs.open("file.txt");两种方式,将ifstream绑定文件。 文件模式:
in,out,app后面添加,ate定位到文件最后的文件定位指针,trunc截断,覆盖,binary 字符串输入输出流 stringstream istringstream ostringstream 是内存操作;cout cin 显示在屏幕,不是内存操作。

C++初级 入门笔记学习(一)的更多相关文章

  1. 每天成长一点---WEB前端学习入门笔记

    WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...

  2. Webpack新手入门教程(学习笔记)

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 30.0px Helvetica; color: #000000 } ...

  3. ORMLite学习入门笔记

    ORMLite学习入门笔记 使用原始的SQLiteHelper来操作维护数据库有点过于繁琐,重复工作量较大.所以会想到使用一个比较方便的ORM来维护我们本地的数据库,各位业界前辈都给我推荐了ORMLi ...

  4. 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2  任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...

  5. TypeScript 入门教程学习笔记

    TypeScript 入门教程学习笔记 1. 数据类型定义 类型 实例 说明 Number let num: number = 1; 基本类型 String let myName: string = ...

  6. React.js入门笔记

    # React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...

  7. unity入门笔记

    我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...

  8. MySQL入门笔记

    MySQL入门笔记 版本选择: 5.x.20 以上版本比较稳定 一.MySQL的三种安装方式: 安装MySQL的方式常见的有三种: ·          rpm包形式 ·          通用二进制 ...

  9. MySQL入门笔记(一)

    一.数据类型 1. 整型 2. 浮点型 3. 字符型 4. 日期时间型 二.数据库操作 1. 创建库 CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_nam ...

随机推荐

  1. 【算法导论C++代码】归并排序

    一个归并排序卡了一天最后还是归并算法有问题,最初是为了把算法导论的伪代码转到c++而加了一些东西,其中在对左右数组的赋值那里出了问题.因为进行测试时不完全,就是只用书上的数组进行测试时,归并算法部分还 ...

  2. 常见Hibernate报错处理:出现“org.hibernate.QueryException: could not resolve property”和 is not mapped和could not locate named parameter错误的解决

    正确写法: @Override @SuppressWarnings("unchecked") public List<Device> queryOSDevice(Str ...

  3. Git服务器分类

    目录(?)[-] 服务器上的 Git 协议 本地协议 优点 缺点 SSH 协议 优点 缺点 Git 协议 优点 缺点 HTTPS 协议 优点 缺点 在服务器部署 Git 将纯目录转移到服务器 小型安装 ...

  4. asyncio NetMQ 解决方案编译问题

    程序集代码 (原) <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <VersionPrefix& ...

  5. 持续集成之Jenkins+Gitlab简介 [一]

    转载:http://blog.csdn.net/abcdocker/article/details/53840449 持续集成概念 持续集成Continuous Integration 持续交付Con ...

  6. 一个简单的java回调函数的实现

    回调函数 回调函数涉及的3个函数 登记回调函数 回调函数 响应回调函数 简单的解释 你到一个商店买东西,刚好你要的东西没有货,于是你在店员那里留下了你的电话.过了几天店里有货了,店员就打了你的电话,然 ...

  7. Pinterest架构:两年内月PV从零到百亿

    Pinterest正经历了指数级曲线般的增长,每隔一个半月就翻番.在这两年里,Pinterest,从 每月PV量0增长到100亿,从两名c创始人和一个工程师成长为四十个工程师,从一台MySQL 服务器 ...

  8. MPTCP 源码分析(五) 接收端窗口值

    简述:      在TCP协议中影响数据发送的三个因素分别为:发送端窗口值.接收端窗口值和拥塞窗口值. 本文主要分析MPTCP中各个子路径对接收端窗口值rcv_wnd的处理.   接收端窗口值的初始化 ...

  9. 怎样用Google APIs和Google的应用系统进行集成(4)----获得Access Token以通过一些Google APIs的OAuth2认证

    在上篇文章中: "怎样用Google APIs和Google的应用系统进行集成(3)----调用发现Google APIs的RESTful的服务"一文中,我们直接用jdk的java ...

  10. openerp编辑与非编辑下隐藏按钮的方法

    在form表单中,有些控件希望在编辑的时候显示,非编辑时不显示,如hr模块的员工表单,在非编辑模式中,姓名的title不显示,而在编辑模式中显示出来.我们可以在xml文件中给控件赋属性值,class= ...