目录
c++编程基础
第一节包括:
- 一些基础类型:bool int char float
- 算术运算符,关系运算符,逻辑运算符
- 条件分支和循环控制语句
- 一些复合类型
- 一套标准,通用的抽象化库
1.1 如何编写一个程序呢:
c++程序都是从main() 函数开始执行,形式如下:
int main()
{
//.....
}
int 是c++程序语言的关键字--具有特殊意义的名字。
函数是一块独立的程序代码序列能够执行一些运算,由四部分组成:1 返回类型2 函数名3 参数列表4 函数体
main 函数返回非零的值表示程序执行有无,正确是return 0;
函数的参数列表()括住置于函数名之后,可以为空;
函数的主题是由{} ;
//单行注释 多行注释
基础数据类型:bool char int float
class 的定义有两部分,分别写在不同的文件,其中所谓的头文件用来声明class提供的各种行为,另一文件包含行为的实现。
#include
我们可以写个例子:
#includeusing namespace std;//标准库所提供的任何事物都被封装在命名空间std内。 #include //引入头文件 int main() { string name; cin>>name ;//输入 cout< 1.2对象的定义与初始化
对象的名字可以是有任何字母,数字,下滑线的组合。对象名字不能以数字开头。
单一声明语句中定义多个对象其间用逗号分隔。
int a=0,b=0;初始化语法:
int a(0); stirng name="Tom";c++ 支持三种浮点数类型
float 单精度 double 双精度 long double 长双精度转义字符:
'n' 换行符 't' 制表符 ' ' null ''' 单引号 '\' 反斜线Bool 对象 其值可以是true/false;
const int a=3;被它定义的变量获得初始值之后,无法再改变。
1.3 表达式
算术运算符 + - * / %
条件运算符C ?A:B 如果C为true执行A,否则执行B;
复合运算符 += -= *= /=
关系运算符> < >= <= == !=
if () {}; if () {}else {}; if () {}if else() {}else {};逻辑运算符:! && ||(会出现短路)
//运算符优先级从高到低 ! * / % + - < > <= >= == != && || =条件语句
switch () { case 1: break: case 2: break; default: break; }循环语句
while () {}; break; continue:1.5 Array和vector
#includeusing namespace std; #include #include int main() { int arr[] = { 1,2,3,4,5 };//自动推断arr的长度 vector v = { 1,2,3,4,5 }; array a = { 1,2,3,4,5 };// 第一个是表示存储类型,第二个是存储元素的个数 for (int i = 0; i < v.size(); i++) { cout << v[i]; } cout << endl; for (auto i : a) { cout << i; } cout << endl; return 0; } 1.6指针带弹性
int* p = nullptr; int a = 1024; p = &a; //*p是求a的值 //p存储的是a的地址 //虽然指针可以不指向空,防止内存泄漏将指针指向nullptr;1.7 文件的读写
要对文件进行读写首先包含头文件#include
#includeusing namespace std; #include int main() { ofstream ofs("123.txt"); ofs << "neltelan";//向123.txt写入neltelan ofs.close();//关闭文件 //声明ofs的同时,如果文件并不存在便会有一个文件产生出来并共输出使用。若存在就打开并用于输出。 ifstream ifs("123.txt");//类似ofstream 供输入 char a[1024] = { 0 }; while (ifs.getline(a, sizeof(a)))//读取文件内容 { cout << a << endl; } ifs.close(); return 0; }
面向过程中的编程风格
2.1 如何编写函数
函数四部分组成:
- 1返回类型。没有返回值的类型为void
- 2函数名。简明字义
- 3参数列表。函数参数扮演者占位符的角色。
- 4函数体。操作本身的工作逻辑的实现内容。
- 函数必须先被声明,然后才能被使用。函数的声明不必提供函数体。但必须指明返回类型,函数名,以及参数列表。
double fun(double x);//函数声明#includeusing namespace std; #include double fun(double x); int main() { cout << "fun(4) = " << fun(4) << endl; return 0; } double fun(double x)//函数定义 { return x * x * x; } 2.2 调用函数
我们以一个vector 内的整数的排序;
#includeusing namespace std; #include void display(vector &vec); void swap(int &val1, int &val2); void bubble_sort(vector &vec); int main() { vector v = { 1,5,3,7,3,8,9,2,3,5 }; bubble_sort(v); display(v); return 0; } void display(vector &vec) { for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; cout << endl; } } void swap(int &val1, int &val2) { int temp = val1; val1 = val2; val2 = temp; } void bubble_sort(vector &vec) { for (int i = 0; i < vec.size(); i++) { for (int j = i+1; j < vec.size(); j++) { if (vec[i] > vec[j ]) { swap(vec[i], vec[j]); } } } } 指针和引用
int a =1024; int *pi=&a;//pi指向一个int对象 int &val=a;//val是a 的别名,引用从一而终引用的方式将对象作为函数参数传入时,对象本身并不会复制出另一份-复制的是对象的地址。
将参数声明为引用的理由之一:希望得以直接对所传对象进行修改。
理由之二:降低复制大型对象的额外负担。
void display(vector&vec)//避免复制占用大量内存 { for (int i = 0; i < vec.size(); i++) { cout << vec[i] << " "; cout << endl; } } 作用域及范围
函数内定义的对象,只存在于函数执行期间。如果返回局部变量的地址会导致运行错误。局部变量放在堆栈上,当函数执行完毕,这块区域将会被弃置。
对象在程序内的存活区域称为该对象的作用域;全局变量会自动初始化为0;局部变量不予初始化。
动态内存管理
new和delete运算符:
int *p; p=new int;//在堆区开辟int大小的内存 p=new int(111)//指定初始值; int *pi=new int[10];//分配10个int大小未初始化的空间 delete pi//释放。如未释放后果不堪设想 数组的释放 delete []pi;2.3提供默认参数值
默认参数指的是当函数调用中省略了实参时自动使用的一个值;
对于带参数列表的函数必须从右往左添加默认值。
#includeusing namespace std; int fun(int a, int b = 100); int main() { fun(20); fun(1000, 1000); return 0; } int fun(int a, int b ) { cout << "a = " << a << endl; cout << "b = " << b << endl; return 0; }
2.4 使用局部静态对象
因为局部对象会在每次调用函数时建立。并在函数调用结束时被弃置。因此我们使用局部静态对象。局部静态对象可以返回引用。
const vector* fun(int a) { static vector elems; return &elems; } 局部静态对象所存储的空间,即使不同的函数调用过程中,依然持续存在。
2.5 声明inline函数
将函数声明为inline函数表示要求编译器在每个函数调用调用点上将函数展开。
一般最合适声明inline的函数,体积小常被调用,所从事的计算不复杂。
inline定义常放在头文件中。
2.6 重载函数
重载:参数列表不相同的两个或多个函数,可以拥有相同的函数名称
void fun(char ch); void fun(const string&); void fun(const string&, int); void fun(const string&, int, int);编译器如何区别-->它会将调用者提供的实际参数拿来和每个重载函数的参数比对,找出最合适的。注意编辑器无法根据返回类型来区分两个具有相同的函数。
2.7 函数模板
函数模板代表一个函数的家族:
templatevoid swap(T& a, T& b) { int temp = a; a = b; b = temp; } //T 可以是int float long double 等.... 2.9 设定头文件
再调用一个函数之前,必须先声明,让程序知道它的存在。为了减少重复操作,将所有声明集中到一个.h 结尾的文件。可供多个程序使用,使用时只需#include<它>就可以了;声明可以多次但定义只需一次。
为啥会有#include<> 和 #include" "呢-->如果此文件被认定为标准的或项目专属的头文件用<>;
用户的头文件用" ";
泛型编程风格
指针的算术运算
如果给定一个vector用来存储整数,找到value并必须返回指针指向的值:
int* find(const vector*vec, int val) { for (int i = 0; i < vec.size(); i++) if (vec[i] == val) return &vec[i]; } 如何实现一个泛型find()的呢
templateelemtype* find(const vector &vec, const elemtype & val) { for (int i = 0; i < vec.size(); i++) { if (vec[i] == val) return &vec[i]; } return 0; } 如果我们用的是数组不是向量上述模板不适合
当数组被传给函数,或函数返回仅有第一个元素的地址会被传递。
int fun(int arr[10]){}; int fun1(int *arr){};//两个传递数组作用相同数组查找泛型:
templateelemtype* find(const elemtype * arr, int size, const elemtype & val) { if (!arr || size < 1)//判断是否数组合理 { return 0; } for (int i = 0; i < size; i++) { if (arr[i] == val) { return &arr[i]; } } return 0; } 3.2 iterator
写一个display():
templatevoid display(const vector &vec, ostream & os) { vector ::const_iteator it1 = vec.begin(); vector ::const_iteator it2 = vec.end(); for (; it1 != it2; ++it) { os << *it << " "; os << endl; } } //const_iteator只读不可修改,iteator可读可写
基于对象的编程风格
类是一种将抽象转换为用户定义类型的c++工具,它将数据表示和操作数据的方法组合一个整洁的包。
类声明:以数据成员的方式描述数据部分,以成员函数的方式描述公有接口
类的方法定义:描述如何实现类的成员函数
c++将接口放在头文件中,并将实现放在源代码文件中
不必在类声明中使用关键字private因为这是类对象默认访问控制
class world { float mass; char name[10]; public: void fun(); };
类和结构的区别:结构的默认访问类型是public,类的是private
实现类的成员函数
定义成员函数是有作用域解析符(::)来标识所属类
类方法可以访问类的private组件
#pragma once #include#include using namespace std; class student { string name; int age; public: void studentset(string, int); void display(); }; 我们可以先实现函数的定义在.cpp文件中
#include"test.h" void student::studentset(string name, int age) { this->name = name;//this 是区分name,右边name是传参进来的,左边的name是调用本函数的对象里的name this->age = age; } void student::display() { cout <<"姓名:" << this->name <<"年龄:" << this->age << endl; }#include"test.h" int main() { student one; student two; //创建每一个新对象都有自己的新空间,由于存储其内部变量和类成员,但同一个类的所有对象共享同一组类方法,及每一个方法只有一个副本。 one.studentset("小米", 23); two.studentset("小花", 34); one.display(); two.display(); return 0; }类的定义
类的定义必须用分号结尾;
1.类的成员
成员可以是:成员函数(方法,构造和析构函数),成员变量(数据成员),成员枚举,类型别名和嵌套类。
最好将不改变对象的成员函数声明为const.成员函数和数据成员不能同名。
2.访问控制
三种:public protected private
3.声明顺序
可以使用任何顺序声明成员和访问控制说明符,还可以重复使用访问说明符;
class sheet { public: void fun(); private : double value; public: double getvalue(); };4.类内成员初始化
可直接在类定义中初始化成员变量。
class student { string name="Tom"; int age=10; public: void studentset(string, int); void display(); };5.定义方法
通常类定义在头文件中,方法定义在包含头文件的源文件中。
#include"test.h" void student::studentset(string name, int age) { this->name = name;//this 是区分name,右边name是传参进来的,左边的name是调用本函数的对象里的name this->age = age; } void student::display() { cout <<"姓名:" << this->name <<"年龄:" << this->age << endl; } 注意每个方法名之前都出现了类名和作用域解析符。
如何实现一个类
我们以栈stack为例:
class Stack { public://公有接口 bool push(const string&); bool pop(const string& elem); bool peek(string& elem); bool empty(); bool full(); int size() { return stack.size(); }; private://私有接口 vectorstack; }; class 定义有两部分组成:class声明以及在声明之后的主题部分有一个大括号以分号结尾。
bool Stack::empty() { return stack.empty(); }在.cpp 文件内定义Stack里的成员函数,::指明函数属于哪个类。
4.2 构造和析构函数
构造函数名必须与类名相同,不指定返回值类型,可以发生重载。
class Triangular { public: Triangular();//无参构造 Triangular(int len);//有参构造 Triangular(Triangular&)//拷贝构造 };当class object定义出来后,编辑器自动根据获得的参数,调用对应的构造函数。
没有构造函数编辑器会自动提供构造函数。
与构造函数类似的析构函数。
严格规定~类名(){}为析构函数。它不可以重载。
4.3 mutable 和 const
int sum(const Triangular &tain) { //....这里面不可以对tain进行修改 }class Triangular { public: Triangular();//无参构造 Triangular(int len);//有参构造 Triangular(Triangular&);//拷贝构造 int len()const { return length; };//在成员函数后面加const表示这个函数不会更改类对象的内容。 int po()const { return pos; }; int ne()const { return next; }; private: int length; int pos; int next; };Mutable 数据成员
class Trianguar { public: bool next(int& val)const; void next_reset()const { _next = _beg_pos - 1; }; private: mutable int _next;//虽然成员函数后有const但依然可以修改_next变量。 int _beg_pos; int _length; };4.4This 指针
我们看一个拷贝构造函数:
Triangular& Triangular::copy(const Triangular& rhs) { if(this!=&rhs)//检查两个对象是否相同 _length = rhs._length; return *this;//this 指向调用者 }this指针系在成员函数内用来指向其调用者(一个对象)。
持续更新!!!!!!



