C++入门——const、引用、内联、动态内存分配

本文详细介绍了C++中的const关键字,包括const常量的作用和与#define的区别。接着讨论了引用的概念,如数据交换、函数参数传递和返回值的应用。还讲解了内联函数的使用和注意事项,并对比了C和C++中的动态内存分配,如new运算符在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

const关键字

C++中const修饰的是一个常量

  1. const常量位于符号表中,正常情况下内存不会为其分配内存空间
  2. 使用常量的时候从符号表中取值
  3. 如果对const常量进行取地址操作,则编译器会为其分配一块空间,但是它本身不会使用

define回顾

定义常量宏常量建议用const进行替换
定义函数宏函数建议用内联函数进行替换

define与const的区别

  • define是预处理的处理,类型完全替换,会在程序中有多个备份
  • const是编译的时候处理,会进行变量的类型和作用域检测,只在符号表中有一个备份

引用

引用是空间的别名

int a = 10;
int &b = a; //a和b代表同一块空间

使用引用的时候必须要进行初始化

使用引用进行数据交换

引用可以在一定程度上替换指针

// 利用引用进行数交换
void mySwap(int &a, int &b)
{
    int tmp = a;
    a = b;
    b = tmp;// 利用引用进行数交换
}

使用引用进行函数传参

void printS(Student *ps);
void printS(Student &rs)
{
    re.结构体成员
}

函数返回值为引用

注意:不能返回局部变量的引用,可以返回静态变量或者全局变量的引用

  • 使用普通变量接收返回值,接收到变量的值,而不是变量空间
  • 使用引用接收返回值,接收到的是变量的空间(引用)
  • 如果函数返回值为引用,则可以作为左值使用
    func() = 200;
int &func() //函数的返回值是int &引用
{   
    static int sa = 0;  //静态变量
    sa++;
    printf ("func:sa = %d\n", sa);
    return sa;
}

int main()
{   
    // 不接收返回值
    func();//1
    
    // 使用普通变量接收返回值,接收到变量的值,而不是变量空间
    int a = func();//2
    cout << "a = " << a << endl;
    a = 50;
    func(); //3
    
    // 使用引用接收返回值,接收到的是变量的空间(引用)
    int &a2 = func(); //4
    a2 = 100;
    func(); //101
    // 如果函数返回值为引用,则可以作为左值使用
    func() = 200;//200
    func(); //201
    return 0;
}

指针引用

struct Student
{
	int id;
};

void func(Student **ps)
{
	//*ps是结构体指针
	*ps = (Student *)malloc(sizeof(Student) / sizeof(char));
	(*ps)->id = 40;
}

void func(Student* &rps)
{
	rps = (Student *)malloc(sizeof(Student) / sizeof(char));
	rps->id = 20;
}

int main()
{
	Student *ps = NULL;
	func(&ps);
	cout << "id = " << ps->id << endl;

	func(ps);
	cout << "id = " << ps->id << endl;

	getchar();

}

常引用

内联函数

  1. 内联函数: 在函数定义前加上inline关键字,在函数声明前加上inline是无效的
  2. 内联函数在函数调用的时候用函数定义去替换,避免了函数的入栈,出栈,跳转等开销
  3. 内联函数时在编译的时候处理的,**宏函数是在预处理的时候进行处理的 **

注意:

  1. 内联是一种请求,有可能内联不成功
  2. 程序运行的时候,内联函数时没有代码空间的,在编译的时候已经替换完了
  3. 因此,不能对内联函数进行取地址操作 ===> 不能作为回调函数 ===> 不可以调试
  4. 内联函数的函数体不要太大,不要超过5行
  5. 不要有任何形式的循环语句
  6. 不要有复杂的判断语
  7. 内联的实现:内联函数存放在符号表中,实际调用的时候从符号表中取值
#define MAX(a, b) a>b ? a:b
#define ADD(a, b) ((a)+(b))

动态内存分配

C中动态内存分配

  • malloc()和free()
  • 两者属于库函数

C++中动态内存分配

  • new和delete
  • 两者属于运算符

new申请单个变量空间

int main()
{
	// C malloc()  free()
	int *p1 = (int *)malloc(sizeof(int) / sizeof(char));
	if (NULL == p1)
	{
		cout << "malloc申请失败" << endl;
		return -1;
	}
	*p1 = 100;
	cout << "*p1 = " << *p1 << endl;
	free(p1);
	

	// C++ new delete运算符
	int *p2 = new int;	// 类型名* 变量名 = new 类型名(初始值)
	if (NULL == p2)
	{
		cout << "new申请失败" << endl;
		return -1;
	}
	*p2 = 10;
	cout << "*p2 = " << *p2 << endl;
	delete p2;


	// new在申请空间的时候可以对空间进行初始化
	char *pc = new char('A');
	cout << "c = " << *pc << endl;
	delete pc;

	// 
	getchar();
}

new申请数组

int main()
{
	// C malloc()  free()
	// int a[3][4];
	int *p1 = (int *)malloc(sizeof(int) / sizeof(char) * 10);
	if (NULL == p1)
	{
		cout << "malloc申请失败" << endl;
		return -1;
	}
	for (int i = 0; i < 10; i++)
	{
		p1[i] = i;
		cout << p1[i] << " ";
	}
	cout << endl;
	free(p1);


	// C++ new delete运算符
	int *p2 = new int[10];	// 类型名* 变量名 = new 类型名[个数],申请数组的时候不能进行初始化
	if (NULL == p2)
	{
		cout << "new申请失败" << endl;
		return -1;
	}
	for (int i = 0; i < 10; i++)
	{
		p2[i] = i;
		cout << p2[i] << " ";
	}
	// delete 释放数组的时候一定要[] 否则仅释放第一个元素,造成内存泄露
	delete[] p2;

	getchar();
}

new申请连续空间上的多维数组


// new申请连续空间上的多维数组
int main()
{
	// C
	//int a[3][4],
	//(*pa)[4]是指针,指向一个二维数组的指针,行指针,[4]说明每行有4个元素,[0]代表第一列的下标
	int(*p1)[4] = (int(*)[4])malloc(sizeof(int) / sizeof(char) * 12);
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			pa[i][j] = i * 4 + j;
			cout << p1[i][j] << " ";
		}
		cout << endl;
	}
	free(pa);

	// C++
	int(*p2)[4] = new int[3][4];
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4; j++)
		{
			pa[i][j] = i * 4 + j;
			cout << pa[i][j] << " ";
		}
		cout << endl;
	}
	delete[] p2;

	getchar();

	return 0;
}

new申请非连续空间上的多维数组

// 动态申请内存 不连续多维数组
int main()
{
	// C
	//int a[3][4],
	//(**pa)是二级指针,指向一个指针数组,每个指针数组元素指向一个int数组[4]
	int **pa = new int*[3];
	for (int i = 0; i < 3; i++)
	{
		pa[i] = new int[4];
	}

	for (int i = 0; i < 3; i++)
	{
		// 先释放掉int数组的空间
		delete[] pa[i];
	}
	// 再释放掉指针数组的空间
	delete[] pa;
	
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值