C++初级 入门笔记学习(一)
- ,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++初级 入门笔记学习(一)的更多相关文章
- 每天成长一点---WEB前端学习入门笔记
WEB前端学习入门笔记 从今天开始,本人就要学习WEB前端了. 经过老师的建议,说到他每天都会记录下来新的知识点,每天都是在围绕着这些问题来度过,很有必要每天抽出半个小时来写一个知识总结,及时对一天工 ...
- Webpack新手入门教程(学习笔记)
p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; text-align: center; font: 30.0px Helvetica; color: #000000 } ...
- ORMLite学习入门笔记
ORMLite学习入门笔记 使用原始的SQLiteHelper来操作维护数据库有点过于繁琐,重复工作量较大.所以会想到使用一个比较方便的ORM来维护我们本地的数据库,各位业界前辈都给我推荐了ORMLi ...
- 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总
当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2 任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...
- TypeScript 入门教程学习笔记
TypeScript 入门教程学习笔记 1. 数据类型定义 类型 实例 说明 Number let num: number = 1; 基本类型 String let myName: string = ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- unity入门笔记
我于2010年4月1日硕士毕业加入完美时空, 至今5年整.刚刚从一家公司的微端(就是端游技术+页游思想, 具体点就是c++开发, directX渲染, 资源采取所需才会下载)项目的前端主程职位离职, ...
- MySQL入门笔记
MySQL入门笔记 版本选择: 5.x.20 以上版本比较稳定 一.MySQL的三种安装方式: 安装MySQL的方式常见的有三种: · rpm包形式 · 通用二进制 ...
- MySQL入门笔记(一)
一.数据类型 1. 整型 2. 浮点型 3. 字符型 4. 日期时间型 二.数据库操作 1. 创建库 CREATE {DATABASE | SCHEMA} [IF NOT EXISTS] db_nam ...
随机推荐
- OpenGL ES 3.0之Fragment buffer objects(FBO)详解 (转)
http://www.cnblogs.com/salam/p/4957250.html 片段操作图 这篇文章将介绍从写入帧缓冲和读取帧缓冲的方式. Buffers(缓冲) OpenGL ES支持三种缓 ...
- [Unity-2] Unity播放音乐
Unity里面大部分的功能都能够通过拖拽来实现,可是为了方便介绍,在这里都通过代码来实现. Unity里面要播放音乐主要有下面3个要素: 1.AudioSource:控制音乐播放的主体 2.Audi ...
- 在 XenServer上调试windows程序
WinDbg WinDbg is one of a number of tools available from Microsoft that can be used for debugging Wi ...
- Linux下 安装VMware Tools工具
Linux下需要安装VMware Tools工具 Linux下需要安装VMware Tools工具来实现主机和虚拟机直接文件复制粘贴功能,安装方法如下: ①点击虚拟机VM菜单栏--虚拟机--安装VMw ...
- struts上传文件 血案
记录一个图片上传之后没有后缀 拓展名问题 平常我们查询数据都是 fileImage=fileImageService.getQuery(); 让entity等于它 那么fileImage.getF ...
- xcode7.1.1不能真机调试ios9.2系统设备的解决方法
转载自:http://www.cocoachina.com/bbs/read.php?tid-331335.html 前些天手机升级到iOS9.2版本号 xcode7.1还能真机測试. 昨晚更新xc ...
- redis 使用内存超过maxmemory
redis使用量超过了maxmemory,这时无法增加最大内存,redis 实例没有可用内存,导致命令都会执行失败 (error) OOM command not allowed when used ...
- SpringCloud系列十一:自定义Feign
1. 回顾 上文我们讲解了如何为服务消费者配置Feign. 在Spring Cloud中,Feign的默认配置类是FeignClientsConfiguration,该类定义了Feign默认使用的编码 ...
- Centos使用光盘作为本地yum源
[root@localhost CentOS]# mkdir /media/CentOS把光盘加载到本地[root@localhost CentOS]# mount /dev/cdrom /media ...
- 辛星跟您玩转vim第二节之用vim命令移动光标
首先值得一提的是,我的vim教程pdf版本号已经写完了,大家能够去下载.这里是csdn的下载地址:csdn下载.假设左边的下载地址挂掉了,也能够自行在浏览器以下输入例如以下地址进行下载:http:// ...