C++学习
C++学习
1.C++初步知识
1.1基础
头文件
#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;//用到c++标准库
标准C++规定main函数必须声明为int
类:数据成员和成员函数
对象:具有”类“类型特征的变量称为对象
注:仍允许用.h后缀的头文件 都用.h的话不用using namespace std;
C++一般将<xxx.h> 写成< cxxx >
声明结构体可以省略struct
1.2编译
编译为多个目标程序(.obj)再连接成一个可执行的二进制文件(.exe)
2.数据的存储、表示形式和基本运算
2.1转义字符
转义字符:虽然包含两个或多个字符,但它只代表一个字符。
\0是空字符
\ddd是八进制(可以1~3位)比如\012 \101
\xhh是十六进制(可以1~2位) 比如\x12
2.2常量和变量
#define pi 3.14//符号常量虽然有名字 但它不是变量
const int a=3;
//常变量(只读变量) 不能改变
bool a=true;
bool b=false;//增加布尔变量
//如果按整数来用的话 a的值为1 b的值为0
2.3强制类型转换
强制类型转换的一般形式为:(类型名)(表达式)
C++新增了:类型名(表达式)如int(x) 类似函数调用
2.4逗号运算符和逗号表达式
逗号运算符:表达式1,表达式2
求解过程:先求解表达式1,再求解表达式2,整个逗号表达式的值是表达式2的值(也可以拓展成多个)
2.5在标准输入流与输出流中使用控制符
cout<<hex<<b;//十六进制输出b
cout<<dec<<b;//十进制输出b
cout<<oct<<b;//八进制输出b
3.函数
3.1内置函数
在编译的时候直接将所调用函数的代码直接嵌入到主调函数中,而不是将流程转出去(速度会快一些,但增加目标程序的长度)。
inline int max(int a,int b,int c)
{
if(b>a)a=b;
if(c>a)a=c;
return a;
}
3.2函数的重载
C++允许用同一函数名定义多个函数,不同函数可能参数类型或者个数不一样,可以通过这个方式去找到合适的函数。参数类型和个数都一样是不对的。
例:
int max(int a,int b);
int max(int a,int b,int c);
double max(double a,double b,double c);
3.3函数模板
一个通用函数,其函数类型和形参类型不具体指定。
例:
#include <iostream>
using namespace std;
template <typename T>//通用函数定义
T max(T a,T b,T c)
{
if(b>a)a=b;
if(c>a)a=c;
return a;
}
3.4有默认参数的函数
float area(float r=6.5);
area();//调用 相当于area(6.5);
实参和形参的结合是从左至右顺序进行的。所以指定默认值的参数必须在形参表列中的最右端。例如:
void f1(int a=1,int b,int c=2);//错误
void f2(int a,int b,int c=2);//正确
注:
1.如果函数的定义在函数调用之前,则应在函数定义中给出默认值。如果函数的定义在函数调用之后,则在函数调用之前需要有函数声明,此时必须在函数声明中给出默认值,则在函数调用之前需要有函数声明。
2.一个函数不能既作为重载函数,又作为又默认参数的函数。不然缺的时候,系统无法分辨。
3.5用extern声明外部变量
1.有时候需要用extern来声明全局变量,以拓展全局变量的作用域。
提前引用声明:想用得提前声明,不然用不了
例子:
#include<iostream>
using namespace std;
int main()
{
extern int a,b;//对全局变量a,b作提前引用声明,不然不能用
return 0;
}
int a=15,b=7;//定义全局变量a,b
在多文件程序中声明外部变量:
例子:
//file1.cpp
extern int a,b;//系统读到这里,知道这个已在别处定义,它先在本文件里找,如果有,则将其作用域扩展到本行开始,如果本文件里面没有,就在其他文件里找
int main()
{
return 0;
}
//file2.cpp
int a=3,b=4;
2.用static声明的变量,只能本文件使用
3.6内部和外部函数
前面加static,又称为静态函数,只能在内部使用
外部函数外部变量类似
例子:
///file1.c
#include <stdio.h>
int main(void)
{
extern int max(int a, int b);//函数声明,可以去别的文件找
int c = 5, d = 10;
printf("max = %d\n", max(c, d));
return 0;
}
///file2.c
int max(int a, int b)
{
return(a>b?a:b);
}
3.7头文件
由于有了#include指令,就可以把不同的文件组合在一起,形成一个文件,因此说,头文件是源文件之间的接口。
4.数组
记得有个string
5.指针
5.1指向指针的指针
char *(*p);
char **p;//因为*运算符的结合性
//示例程序
#include<iostream>
using namespace std;
int main()
{
char **p;
char *name[]={"basic","python","c++","java"};//指针数组
p=name+2;//指向c++
cout<<*p<<endl;//取出c++
cout<<**p<<endl;//取出第一个字符
return 0;
}
/*运行结果:
c++
c
*/
5.2const指针
1.指向常量的指针变量
只是限制了通过指针变量改变它指向的对象的值,别的修改都正常修改。
int a=12,b=9;
const int *p=&a;
p=&b;//合法
a=8;//合法
*p=19;//不合法,不能这么修改
常指针:值可以变,但是指向是千万不能变的。
int a=4,b=6;
int *const p2=&a;
p2=&b;//不合法,指向不能改变
5.3引用
引用的作用是给一个变量起一个别名,声明引用的时候,必须同时初始化,声明一个引用后,不能再使之作为另一变量的引用。
int a;
int &b=a;//声明b是a的引用 &是引用声明符
//a和b的值一起变化
//示例函数:
void swap(int &a,int &b)//形参是引用,属于地址传递
{
int temp;
temp=a;
a=b;
b=temp;
}
swap(i,j);//相当于a是i的别名,b是j的别名
void swap(int *a,int *b);//这种其实还是值传递,传递的是一个地址的数
6.结构体
6.1基础
c++声明的时候允许不写struct
结构体指针p。(*p).num和p->num等价
用结构体变量的引用作函数参数
void print(student &stud)
{
cout<<stud.x<<" "<<stud.y<<endl;
}
6.2用new和delete运算符进行动态分配和撤销存储空间
数据结构书上:
typedef struct{//顺序表
elemtype *data;
int maxsize,length;
}seqlist;
//c语言方式
L.data(elemtype*)malloc(sizeof(elemtype)*initsize);
//c++方式
L.data=new elemtype[initsize];
new和delete是运算符
new运算符使用的一般格式为:new 类型 [初值]
delete运算符使用的一般格式为
delete 指针变量 (对变量)
delete [ ]指针变量 (对数组)
float *p=new float(3.14);//也可以不指定初值
开始面向对象!!
7.类和对象的特性
面向对象特点:抽象、封装、继承、多态性
对象:属性和行为
类是对象的抽象,而对象则是类的特例,即类的具体表现形式
private:被声明为私有的成员,只能被本类中的成员函数引用,类外不能调用(友元类除外)
public:就无所谓
protect:类似private,但是可以被派生类的成员函数
成员函数不占内存空间
8.怎样使用类和对象
8.1用构造函数实现数据成员的初始化
用参数初始化表对数据成员初始化
可以从传入的参数值对成员进行初始化
box();
box(int=10,int=10);//声明一个都指定了默认值的构造函数 声明可以不写变量名
8.2析构函数
对象释放前自动执行析构函数,静态调用结束之后并不释放,一般是Main函数结束之后或者exit结束之后会调用。
作用是清理工作,不能被重载。
先构造的后析构,后构造的先析构
8.3对象数组
student stud[3]={60,70,78};//3个实参分别作为3个元素的第一个实参
student stud[3]={60,70,78,45};//不合法,实参个数不能超过对象数组元素个数
student stu[2]={
student(1001,18,87),student(1002,19,76),student(1003,18,72)
};
8.4对象指针
1.指向对象的指针
2.指向对象成员的指针
void (Time:: *p2)();//指向time类中公共成员函数的指针变量
p2=&Time::get_time;
3.this:它是指向本类对象的指针,它的值是当前被调用的成员函数所在的对象的起始地址。
int box::volume(box *this)
{
return (this->height*this->width*this->length);
}
8.5常对象
Time const t1(12,34,46);//t1是常对象
const Time t1(12,34,46);//与上面等价
//要想访问(也不能修改)常对象
void get_time()const;//get_time是一个常成员函数 可以访问常对象
//如果实在想改变哪个数据,前面加上mutable,可以用常成员函数修改
mutable int count;
常对象成员:是不是常成员函数都可以引用
const int hour;
Time(int h):hour(h){}//常对象成员只能用参数列表化
常指针:
Time t1(10,12,15),t2;
Time * const ptr1;
ptr1=&t1;//指向t1,但是之后不能再背改变
ptr2=&t2;//ptr1不能改变指向
总结:
Time const t;//常对象
void Time::fun()const;//常成员函数
Time *const p;//常指针变量
const Time *p;//指向类常对象的指针变量 不能同p来改变
const Time &t1=t;//t1是类对象t的引用,二者指向同一存储空间,t的值不能改变
8.6对象的动态建立和释放
box *pt;
pt=new box(12,15,18);
cout<<pt->height;
cout<<pt->volume();
delete pt;//释放空间
对象的复制:
box box2(box1);
8.7静态成员
如果希望各对象中的数据成员的值是一样的,就可以退把它定义为静态数据成员。
静态数据成员既可以用对象名引用,也可以通过类名引用。
class box
{
public:
static int volume();
private:
static int height;
int width;
int length;
};
int box::height=10;//只能在类外面进行初始化
box::volume();//可以通过类 也可以通过对象
a.volume();
8.9友元
个人理解就是声明一下是朋友,可以访问私有成员。
1.把普通函数声明为友元函数
可以把不属于类的函数拉入类中。
friend void display(Time &);//在类里面写,把函数拉入类中,可以调用
2.友元成员函数
公有继承:
只能继承公有部分。有父类的属性和方法。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构