C++基础

命名空间:防止命名冲突

命名空间将函数,变量,类等标识符封装在各自逻辑范围内
命名空间可以在全局作用域或其他作用域(另一个命名空间)内部定义,但是不能在函数或类的内部定义

命名空间的定义可以不连续,即具有累加性,可以将同一个命名空间的定义分解为若干部分,并且这些部分可以位于不同代码文件中

C++自带的标准命名空间为std

命名空间的使用

//方法一:在需要使用命名空间中内容时用,在函数内部使用
命名空间名::局部内容名

//法二和法三在主函数外部
//方法二:在使用该内容前使用,可以使用该命名空间下的全体成员,不需要加命名空间前缀
using namespace 命名空间名;

//方法三:在使用该内容前用,提示使用空间中的局部内容名
using 命名空间名::局部内容名;

数据类型

屏幕截图 2026-01-01 154613

  • bool类型(逻辑型)只有两个值:true(真)false(假)
  • string类可以处理内存管理,提供某种越界检查、复制和比较,还支持连接字符串、查找字符串、提取子串或字符替换等处理。注意:使用string类时,必须添加头文件<string>

屏幕截图 2026-01-01 155921

<string><cstring>这两个头文件不一样

  • const数据类型说明符定义常类型,声明语句如下:
    const 数据类型说明符 常量名 = 常量值;
    或者
    数据类型说明符 const 常量名 = 常量值;

这种修饰的常量称为符号常量,符号常量在声明时应立刻进行初始化,一旦初始化,值不能被修改

new 和 delete

运算符new用于内存分配的最基本语法形式:指针变量 = new 类型名;
运算符delete用于释放new分配的存储空间:delete 指针变量;,然后清空:指针变量 = NULL;

int* func()
{
	//在堆区开辟内存
	int *p = new int(10);
}

void test()
{
	//在堆区开辟数组长度为10的数组
	int *arr = new int[10];
	
	for(int i = 0;i < 10;i ++)
	{
		arr[i] = i + 100;
	}
	
	for(int i = 0;i < 10;i ++)
	{
		cout << arr[i] << endl;
	}
	
	//释放数组(要加中括号)
	delete[] arr;
}

int main()
{
	int *p = func();
	//堆区数据由程序员管理开辟,由程序员管理释放
	cout << *p << endl;
	
	//释放内存,即此处内存失效
	delete p;
	p = NULL;
	
	return 0;
}

引用:给变量起别名

本质:在 C++ 内部实现是一个指针常量(指针的指向是固定的,指针指向的值可以更改)

语法:数据类型 &别名 = 原变量名;(别名与原变量访问同一块地址)

注意事项:

  1. 与指针一样,两者必须是同类型才可以引用。
  2. 除非做函数的返回值或形参时,其余定义引用类型的同时就要初始化!
  3. 引用初始化时,只能绑定左值,不能绑定常量值
  4. 引用一旦初始化,其值就不能再更改,即不能再做别的变量的引用
  5. 数组不能定义引用,因为数组是一组数据,无法定义其别名
int main()
{
	int a = 10;
	int c = 20;
	//初始化引用,int &b;(错误)
	int &b = a;//(正确),b与a指向同一块地址
	//复制操作,不熟更改引用
	b = c;
	
	cout << a << b << c << endl;
	return 0;
}

引用传参

函数传参方式:1.值传递 2.地址传递 3.引用传递

//值传递(参数为数值)——形参影响不了实参
void swap_1(int a,int b)
{
	
}

//地址传递(参数为指针)——形参能够影响实参
void swap_2(int *a,int *b)
{
	
}

//引用传递——形参能够影响实参
void swap_3(int &a,int &b)
{
	
}

引用做函数返回值

1.不要返回局部变量的引用

//注意:返回的对象需为全局对象或静态对象
//返回值为引用类型
int& test1()
{
	int a = 10;
	//a是局部变量(存放在栈区),函数执行完会被释放,返回a,则函数调用后接收a的变量同样被释放
	return a;
}

2.函数的调用可以作为左值

int& test2()
{
	static int a = 10;
	//a是静态变量(存放在全局区),程序结束后,由系统释放
	return a;
}

int main()
{
	int &ref = test2();
	cout << ref << endl;
	
	//原名赋值
	test2() = 1000;
	//别名访问内存
	cout << ref << endl;
	
	return 0;
}

函数

带默认参数的函数
进行函数调用时,编译器按从左向右的顺序将实参与形参相结合

注意:

  1. 若没有声明函数原型,参数的默认值可以在函数定义的头不进行设置,否则必须在函数原型中设置
  2. 在一个指定了默认值的参数的右边,不能出现没有指定默认值的参数,例如:int func(int a = 3,int b)错误
  3. 设置默认参数可使用表达式,但表达式中不可用局部变量,例如:int func(int a = 3,int b = a)错误

inline 内联

使用inline关键字声明一个函数,称为内嵌函数

引入内联函数的目的是为了消除函数调用时的系统开销,以提高运行速度。

内联函数具有一般函数的特性,它与一般函数所不同之处在于函数调用的处理。一般函数进行调用时,要讲程序执行权转导被调函数中,然后再返回到调用到它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。

格式如下:

inline <返回值类型><函数名>(<形参表>)
{
	<函数体>
}
示例:
#include<stdio.h>
#include<stdlib.h>

//关键字inline
inline int add(int x,int y);  //声明内联函数

inline int add(int x,int y)  //定义内联函数
{
   return x+y;
}

int main()
{
   int i,j,k;
   printf("请输入两个整数的值:\n");

   scanf("%d %d",&i,&j);

   k=add(i,j);
   printf("k=%d\n",k);

   return 0;
}

调用函数add时,该函数在编译时会将以上代码复制过来,而不是像一般函数那样是运行时被调用

注意:

  1. 递归函数不能定义为内联函数
  2. 内联函数一般不适合于含有switchwhile等复杂的结构,且只有1~5条语句的小函数,否则编译系统将该函数视为普通函数(即不当作内联函数)
  3. 对内联函数也不能进行异常接口声明
  4. inline只是建议编译器将函数嵌入到调用处,如果函数长度、复杂度不符合,编译器还是不会把它作为内联函数

函数重载

作用:函数名可以相同,提高复用性

满足条件:

  • 同一作用域下
  • 函数名称相同
  • 函数参数类型不同或者个数不同或者顺序不同

注意:函数的返回值不可以作为函数重载的条件

#include <iostream>
using namespcae std;

void func()
{
	cout << "func的调用" << endl;
}

void func(int x)
{
	cout << "输入的数为: " << x << endl;
}

int main()
{
	func();
	func(3);
	return 0;
}
#include <iostream>
using namespcae std;

//注意事项:
//1.引用作为重载条件
void func(int &a)
{
	cout << "func(int &a)的调用" << endl;
}

//限定可读
void func(const int &a)
{
	cout << "func(const int &a)的调用" << endl;
}

//2.函数重载碰到默认参数
void func2(int a)
{
	cout << "func2(int a)的调用" << endl;
}

void func2(int a,int b = 10)
{
	cout << "func2(int a,int b = 10)的调用" << endl;
}

int main()
{
	int a = 10;
	func(a);
	func(5);
	
	//会出现二义性(歧义)
	func(10);
	
	return 0;
}

异常处理机制

程序的错误通常包括:语法错误逻辑错误运行异常

异常处理的代码形式如下:

try
{
	//正常程序执行语句
	throw(异常类型表达式);//抛出异常
}
catch(异常类型1)//捕获异常
{
	//异常处理代码
}
catch(异常类型2)
{
	//异常处理代码
}
catch(异常类型3)
{
	//异常处理代码
}
//若是未找到匹配(即无法捕捉到异常,例如除数为0的异常),则自动调用terminate()结束函数,默认功能是abort()终止程序

//拓展:可以捕获任何可被捕捉异常的catch子句,放到最后,否则,引发编译错误

catch(...)
{
	//异常处理代码
}

父类与子类异常

如果多个catch子句联立并且catch子句接收参数的类型之间存在派生和继承关系,则

接收子类型参数的catch子句应当在前面

接收父类型参数的catch子句应当在后面

否则,会产生编译警告/错误,而且当接收子类型参数的catch子句实际上不起作用

屏幕截图 2026-01-13 101733

标准异常处理类

如图,所有的异常类都继承于exception基类,包括两个大类:逻辑类错误运行时错误

注意:使用 C++ 自带的标准异常类时,需要包含对应头文件

posted @ 2026-01-26 09:37  魏图图  阅读(12)  评论(0)    收藏  举报