已经好久没有学东西了,今天将以前学的知识搬到了博客
C++语言
工具使用vscode 插件,安装c++的环境,配置环境变量。添加文件
配置连接 https://www.cnblogs.com/bpf-1024/p/11597000.html
官网下载的话有点慢。
launch.json
{ "version": "0.2.0", "configurations": [ { "name": "(gdb) Launch", // 配置名称,将会在启动配置的下拉菜单中显示 "type": "cppdbg", // 配置类型,这里只能为cppdbg "request": "launch", // 请求配置类型,可以为launch(启动)或attach(附加) "program": "${workspaceRoot}/${fileBasenameNoExtension}.exe",// 将要进行调试的程序的路径 "args": [], // 程序调试时传递给程序的命令行参数,一般设为空即可 "stopAtEntry": false, // 设为true时程序将暂停在程序入口处,一般设置为false "cwd": "${workspaceRoot}",// 调试程序时的工作目录,一般为${workspaceRoot}即代码所在目录 "environment": [], "externalConsole": true,// 调试时是否显示控制台窗口,一般设置为true显示控制台 "MIMode": "gdb", "miDebuggerPath": "D:\\C++\\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\\mingw64\\bin\\gdb.exe",// miDebugger的路径,注意这里要与MinGw的路径对应 "preLaunchTask": "g++", // 调试会话开始前执行的任务,一般为编译程序,c++为g++, c为gcc "setupCommands": [ { "description": "Enable pretty-printing for gdb", "text": "-enable-pretty-printing", "ignoreFailures": true } ] } ] }
tasks.json
{ "version": "2.0.0", "tasks": [ { "label": "g++", "command": "g++", "args": [ "-g", "${file}", "-o", "${fileDirname}/${fileBasenameNoExtension}.exe" ], "problemMatcher": { "owner": "cpp", "fileLocation": [ "relative", "${workspaceRoot}" ], "pattern": { "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", "file": 1, "line": 2, "column": 3, "severity": 4, "message": 5 } }, "group": { "kind": "build", "isDefault": true } }, { "type": "shell", "label": "C/C++: g++.exe build active file", "command": "D:\\C++\\x86_64-8.1.0-release-posix-seh-rt_v6-rev0\\mingw64\\bin\\g++.exe", "args": [ "-g", "${file}", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe" ], "options": { "cwd": "${workspaceFolder}" }, "problemMatcher": [ "$gcc" ], "group": { "kind": "build", "isDefault": true } } ] }
执行F5编译
基本模板
#include <iostream> ////将iostream的内容添加到程序中 iostream包含输入输出 using namespace std;//命名空间 // main() 是程序开始执行的地方 int main() { cout << "Hello World" << endl; // 输出 Hello World cout是iostream的一个打印对象。endl打印空格,确保语句立刻输出。清缓存,打印缓存 return 0; }
执行过程
g++ 命令
c++数据类型
C++ 为程序员提供了种类丰富的内置数据类型和用户自定义的数据类型。下表列出了七种基本的 C++ 数据类型:
类型 | 关键字 |
---|---|
布尔型 | bool |
字符型 | char |
整型 | int |
浮点型 | float |
双浮点型 | double |
无类型 | void |
宽字符型 | wchar_t |
其实 wchar_t 是这样来的:
typedef short int wchar_t;
所以 wchar_t 实际上的空间是和 short int 一样。
一些基本类型可以使用一个或多个类型修饰符进行修饰:
- signed
- unsigned
- short
- long
变量作用域
作用域是程序的一个区域,一般来说有三个地方可以定义变量:
- 在函数或一个代码块内部声明的变量,称为局部变量。
- 在函数参数的定义中声明的变量,称为形式参数。
- 在所有函数外部声明的变量,称为全局变量。
基础例子
#include <iostream> using namespace std; #include <iomanip> using std::setw; int main(){ double price_phone=35000.0; double price_book=11044.5; double price_wallet=1535.0; double discount=0; double real=0; int phone,book,wallet; //如果总价大于5w就打七折。否则打九折 cout<< fixed;//不使用科学计数法 cout<< setprecision(2);//数据精度保留两位小数点 cout << "钱包"<<setw(13)<< price_wallet <<"\n"<<"书本"<<setw(13)<< price_book <<"\n"<< "手机"<<setw(13)<<price_phone<< endl; cout << "请选择手机的数量\n"; cin >> phone; cout << "请选择书本的数量\n"; cin >> book; cout << "请选择钱包的数量\n"; cin >> wallet; double total=0; total=price_book*book+price_phone*phone+price_wallet*wallet; cout << "总计" << total<<endl; if(total>50000){ discount=0.7; }else{ discount=0.9; } real=total*discount; cout <<"打折后的价钱为"<< real << endl; system("pause"); }
对象模式
后续学习...
指针变量
#include <iostream> #include <cstdio> using namespace std; void swap(int *x,int *y); //声明存在这个函数,可以在main方法的下面调用 void swap1(int x,int y); void testip(); //指针命名 *ip 指针ip存储地址;$+变量 指针取值 *ip 指针地址ip 其实就是同一个变量(有待考虑) /* & 符号的意思是取地址,也就是返回一个对象在内存中的地址。 * 符号的意思是取得一个指针所指向的对象。 也就是如果一个指针保存着一个内存地址,那么它就返回在那个地址的对象。 */ int main(){ int x=5,y=6; swap(&x,&y);//将 x,y 的值互换; cout << x <<"**********************"<< y <<endl; swap1(x,y);//没有将 x,y 值互换; cout << x <<"**********************"<< y <<endl; testip(); system("pause"); } //这个例子是形参x y的值进行了互换,方法外面的值没有换 void swap1(int x,int y){ int t; t=x; //在t的地址赋值x的值,此时的x还有有值,把x的值复制一份给t; x=y; cout <<"我是swap1里面的x"<< x <<endl; y=t; }; //实例二 void swap(int *x,int *y){ int t; t=*x; //将x的值赋给t *x=*y; //将y的值赋给 cout <<"我是swap里面的*x"<< *x <<endl; *y=t; //将t的值赋给y,在y地址加上t的值 } //实例一 void testip(){ int var1=10; char var2[10]; int *ip; // 指针变量的声明 //取出var1的地址,然后放入指针ip中 ip = &var1; cout << "var1 变量的地址: "; cout << &var1 << endl; cout << "var2 变量的地址: "; cout << &var2 << endl; // 输出在指针变量中存储的地址 cout << "Address stored in ip variable: "; cout << ip << endl; // 访问指针中地址的值 cout << "Value of *ip variable: "; cout << *ip << endl; }
两种访问变量的方式
直接访问 | 间接访问 |
---|---|
直接通过变量名来访问 | 将变量i的地址存放在另一个变量中,然后通过该变量来找到i变量的地址,从而访问i的变量。 |
一个变量的地址称为该变量的“指针”、例如:地址2000是变量i的指针.如果有一个变量专门用来存放另一个变量的地址,称为指针变量。
指针变量就是地址变量,用来存放地址。指针变量的值是地址。
区别指针与指针变量的概念
例如:可以说变量i的指针是2000.而不能说i的指针变量是2000
指针是一个地址,指针变量是存放地址的变量。
指针变量
定义一个指针变量
int *pointer_x; //定义一个int行的指针变量 int x=200; pointer_x=&x //将变量x的地址赋值给pointer_x cout << *pointer_x <<endl;//打印x的值
指针的类型
定义 : 类型名 *指针变量名
类型
int * float * char * 等
如何引用
给指针变量赋值
pointer_a=&a;
两个符号的运用
& | * |
---|---|
取地址的运算符 | 指针运算符 *p 代表指针变量指向的对象 |
指针要赋初值(重要)
指针不赋初始值的话会变成野指针,不可控的,通过野指针修改变量可能会影响到系统的变量
int *ptr_num=nullptr; //第一种方式 int *ptr_num=0; //第二种方式
void * 指针(不能修改值)
可以存放任意对象的地址,一般用来和另一个指针比较
指针小结
引用
引用的底层是指针,是对指针的一个简单封装
引用参数
void swap2(int& x,int& y){ int t; t=x; //将x的值赋给t x=y; //将y的值赋给 cout <<"我是swap2里面的x"<< x <<endl; y=t; //将t的值赋给y,在y地址加上t的值 }
指针与数组
打印数组名就是首元素的地址
#include <iostream> using namespace std; int main(){ double score[]{12.5,45.6,78.5,12.6}; double *ptr_score=nullptr; ptr_score=score; //数组名称就是首地址的值 64位机子指针占8字节 cout << *ptr_score<<"\t"<< *(ptr_score+1)<<sizeof(ptr_score)<<endl; //使用指针循环 score就是double[5] 占了40个字节 sizeof(score)=5*8=40;sizeof(score[0])=8 for(int i;i<sizeof(score) / sizeof(score[0]);i++){ cout<< *(ptr_score+i)<<"\n"<<endl; } system("pause"); }
函数指针
函数名也是函数的地址
double (*ptrCalc)(double,double); //定义 double multiply(double num1,double num2); //函数 ptrCalc=multiply; //赋地址 ptrCalc(num1;num2);//使用
计算器例子
#include <iostream> using namespace std; //自定义函数方法完成加减乘除 //专门用来打印结果 void prt_result(double (*)(double,double),double,double); //调用函数打印结果 void prt_result(double (*ptrCalc)(double,double),double num1,double num2){ double result=ptrCalc(num1,num2); //执行的是函数 add divide cout << "运算结果为" << result << endl; } //依次为加减乘除 double add(double num1,double num2){ return num1+num2; } double subtract (double num1,double num2){ return num1-num2; } double multiply(double num1,double num2){ return num1*num2; } double divide(double num1,double num2){ if(num2==0){ cout << "除数不能为0"<< endl; }else{ return num1/num2; } } int main(){ //定义函数指针 是指针,指向函数 double (*ptrCalc)(double,double); double num1,num2; char opt; cout <<"请输入两个操作数"; cin >>num1>>num2; cout<<"请选择如何造作+ - * / "; cin>>opt; switch (opt) { case '+': ptrCalc=add; break; case '-': ptrCalc=subtract; break; case '*': ptrCalc=multiply; break; case '/': ptrCalc=divide; break; default: break; } prt_result(ptrCalc,num1,num2); system("pause"); }
模板函数
里面的T是泛型,无论传入什么值都能接受,所以叫模板函数
//定义一个模板函数。写一个通用模板 typename T 定义一个泛型T 参数 虚拟类型 template<typename T > void swap(T array[],int len); int main(){ } //实现 template<typename T > void swap(T array[],int len){ T temp;//因为不知道数组是什么类型,所以赋值一个泛型 temp=array[0]; }
内联函数
inline void method()
相当于吧方法内容复制到main函数
面向对象编程
封装性:数据和代码捆绑在一起,避免外界干扰和不确定性访问。封装可以使得代码模块化。
优点:
- 确保用户代码不会无意间破坏封装对象的状态
- 被封装的类的具体实现细节可以随时改变,而无须调整用户级别的代码
继承性:让某种类型对象获得另一个类型对象的属性和方法。继承可以扩展已存在的代码
多态性:同一事物表现出不同事物的能力,即向不同对象发送同一消息,不同的对象在接收时会产生不同的行为(重载实现编译时多态,虚函数实现运行时多态)。多态的目的则是为了接口重用
对象的定义
class 类名() | struct 类名() |
---|---|
calss默认的是private 私有属性 | 默认的是public 公有属性,一般使用数据 |
析构函数
- 析构函是类的一个成员函数,名字由波浪号接类名构成。它没有返回值,也不接受参数:
main.cpp
#include <iostream> using namespace std; #include "Student.h"//引用 .h的文件 int main(){ Student student; student.say("你好"); system("pause"); }
Student.h
#include <iostream> using namespace std; class Student { private: /* data */ string name; string stunumber; int age; public: //也可以在这里直接实现方法 Student(/* args */); ~Student(); void say(string mesage ); //新的方法的声明 void setName(string name); };
Student.cpp
#include "Student.h" #include <iostream> using namespace std; //类的方法的实现 Student::Student(/* args */) { } Student::~Student() { } //实现 void say(string message){ cout << message <<endl; } //给属性赋值,相当于java的set get void setName(string name){ name=name; }