c++(一)


在这里插入图片描述

C与C++有什么区别

<1>都是编程语言
<2>C是面向过程的,C++是面向对象的
<3>第一个字母都是相同,在C语言中只要是合法的C语言语句,在C++中都是可以使用的(C++完全兼容C)
<4>++:在C的基础上增加了一些新的内容(新特性、关键字、数据类型等等)
<5>C是面向过程的编程语言;C++是面向对象的编程语言!C是注重过程的!C++注重的是结
果!!!C也有在面向对象编程,是通过结构体,但是因为C里面的结构体中只能描述属性,不能有函数,所以面向对象编程不够彻底,引入C++来解决这个问题!

命名空间

理解成是一个容器,可以放数据类型、函数、变量!
为了解决:在C语言中,能出现同名的函数吗?能出现同样的自定义的数据类型吗? 在同一个作用域内能出现同名的变量吗? 都不可以的!
作用:解决命名冲突,命名冲突的情况: 函数、数据类型、变量!

格式: namespace 命名空间的名字
{
函数;
数据类型;
变量
}


namespace s1
{
	int count = 10;
	struct STU_T
	{
		int sno;
		char name[20];
	};
	void print()
	{
		printf("s1中的count=%d\n", count);
	}
}
namespace s2
{
	int count = 10;
	struct STU_T
	{
		int sno;
		char name[20];
	};
	void print()
	{
		printf("s2中的count=%d\n", count);
	}
}

使用

方法1 命名空间::函数();

int main()
{
	//使用方法1
	s1::print();
	s2::print();
	printf("hello world\n");
	return 0;
}

方法2 将命名空间搞成全局变量,访问时只需要变量前面加上::(域运算符)

using namespace s1; //切换到这个命名空间中===》把命名空间中的内容做成全局
int main()
{
	//使用方法2
	::print();
	printf("%d\n", count);
	//使用方法1
	s2::print();
	printf("hello world\n");
	return 0;
}

在这里插入图片描述

输入输出流

流: 以字节为单位, 连续不断,方向统一的
C中标准输入输出函数: printf()、scanf()、 putchar()、getchar()、 gets()、puts()。这些函数在C++中仍然是可以使用的!除此之外,C++中引入了新的可以做输入输出的方法:

//之前需要引用
#include  <iostream>
using namespace std;
输入:cin >> 变量;
输出:cout << 变量;

在这里插入图片描述
在这里插入图片描述

引用

是一种数据类型,用来给变量起别名

弱化指针(在C中可以用指针来实现的,在C++中都可以使用引用来替换)
减少临时空间的分配

指针和引用的区别

1. 指针可以定义后不初始化,但引用定义后必须初始化;
2. 指针定义时,需要开辟内存空间;引用和变量公用同一块内存空间,不会重新分配内存空间;
3. 指针是存储某个实例的地址;引用是实例的别名
4. 指针变量的值可以为空;引用没有空引用;
5. 理论上指针级数没有限制,但引用只有一级,不存在引用的引用,但可以有指针的指针
6. 不可以对函数的局部变量或对象以引用或者指针的方式返回
7. ++引用与++指针效果不同,对指针变量的操作会使指针指向下一个实体的地址,而不是改变所指实体的内容
8. 对指针变量使用“sizeof”得到的是指针变量的大小,对引用使用“sizeof”得到的是变量的大小
9. 指针变量作为形参时需要测试合法性进行判空,引用不需要判空
10. 指针使用时要加 “ * ”,引用可以直接使用
11. 指针是可以改变指向的; 引用是不可以改变指向的 引用比指针安全

定义

数据类型 &别名 = 变量名;
//注意:引用必须初始化,一旦初始化之后再不能给引用赋值

在这里插入图片描述
在这里插入图片描述

拓展

int a = 10;
const int &a_pt = a;
a_pt = 20;//error(不能对引用再次赋值)
const int &m = 200;// 等价于 #define m 200

函数重载

解决命名困难的问题
概念:函数功能相似,函数名相同,参数不同,与返回值类型无关的一组函数,互为重载
参数不同: 参数个数不同、参数类型不同、参数类型的顺序不同

例子

#include <iostream>
using namespace std;

int sum(int a, int b)
{
	cout << "int,int" << endl;
	return a + b;
}
int sum(int a, double b)
{
	cout << "int, double" << endl;
	return a + b;
}
int sum(double a, int b)
{
	cout << "double, double" << endl;
	return a + b;
}
int sum(int a)
{
	cout << "int" << endl;
	return a + 0;
}
double sum(double a, double b)
{
	cout << "double, double" << endl;
	return a + b;
}
char sum(char a, char b)
{
	cout << "char, char" << endl;
	return a + b;
}
string sum(string a, string b)
{
	cout << "string,string" << endl;
	return a + b;
}

int main()
{
	//调用的函数名是相同的,只是传入了不同的参数,他根据传入的参数的类型匹配了对应的函数去执行了
	cout << sum(5) << endl;
	cout << sum(5,6) << endl;
	cout << sum(5.3, 6) << endl;
	cout << sum(5, 6.8) << endl;
	cout << sum(5.3, 6.8) << endl;
	cout << sum('A', '\0') << endl;
	cout << sum("123", "abc") << endl;
	//如上执行了不同的代码块,根据函数调用的原理,说明每一个调用函数的地方,函数地址都是不同的,也就说明
	// 函数名应该是不一样的! 函数名不一样,那是因为用的编译器不同了! gcc / g++
	return 0;
}

在这里插入图片描述

1.函数调用原理:在调用函数的地址其实保存的是函数的地址,执行的时候会根据函数地址到对应的内存空间,然后执行对应的代码块;
2.当代码块执行完之后再返回到调用函数的地址,继续向下执行!

测试

同一个.c文件,分别使用gcc和g++进行编译,使用nm 可执行文件名
在这里插入图片描述
gcc编译后的结果,函数名没有变
在这里插入图片描述
g++编译后的结果, 函数名发生变化了: 根据函数名的长度、函数名、参数的个数以及参数的类型进行重命名,名字发生了变化,对应函数的地址也就不同,执行的时候就根据不同的地址执行不同代码块!

函数重载原理

使用g++编译后,函数名根据函数名的长度、参数个数、数据类型进行了重命名,函数名变了地址也就
变了,调用时执行的就是不同的函数体

参数默认值

简化代码:
函数重载:当只有参数个数不同的情况下造成的代码冗余

什么是参数默认值

在定义/声明的时候给形参进行初始化
int sum(int a = 0,int b = 0,int c = 0)

注意

  • 写默认参数的时候是从右至左,因为调用的时候实参给的顺序是从左至右
    在这里插入图片描述
  • 没有给默认参数传参时,就按默认值处理
  • 给默认参数传参时,就按传入的实参进行处理

在这里插入图片描述

  • 二义性:函数重载有默认参数时
  • 解决:保留参数个数最多的,且有默认值的函数
    在这里插入图片描述
    -== 当声明和定义同时存在时,参数默认值只能放在函数声明中==
    在这里插入图片描述

在c++中如何引入c的库

<1>如果c中标准的头文件的话,直接#include引入
<2>C中自定义的库要引入到c++中
以静态库为例
使用gcc编译
在这里插入图片描述
在这里插入图片描述
使用g++编译
在这里插入图片描述
问题:使用g++编译时函数的名称发生了改变
解决:使用g++编译器编译时函数的名称不能发生改变
在这里插入图片描述
问题:如何判断是gcc还是g++编译器
方法1:通过宏来判断

__cplusplus

在这里插入图片描述

在这里插入图片描述
方式2:通过单个字符来测试

在c里面单个字符当做整型来用,长度是四个字节
在c++里面单个字符占一个字节

在这里插入图片描述

动态内存分配

在C语言中,使用malloc做动态内存分配, 使用free去做释放!

int main()
{
	int* p = nullptr;
	p = (int *)malloc(4 * 4);
	if (p==nullptr)
	{
		printf("malloc error\n");
		return -1;
	}
	else
	{
		memset(p, 0, sizeof(int)*4);
		*p = 100;
		*(p+1) = 200;
		*(p + 2) = 300;
		*(p + 3) = 400;
		free(p);
	}
	return 0;
}

在C++中引入新的方式来动态内存分配 new运算符开空间 delete 运算符释放空间

语法:
一块空间分配与释放:
数据类型 *变量 = new 数据类型; //不初始化
delete 变量;
数据类型 *变量 = new 数据类型();//有初始化
delete 变量;
连续空间分配与释放:
数据类型 *变量 = new 数据类型[几块]; //不初始化
delete [] 变量;
数据类型 *变量 = new 数据类型[元素个数]();//括号
int main()
{
	int* p = nullptr;
	//去堆区分配了4字节的内存空间
	p = new int;
	cout << *p << endl; // 随机数----没有初始化
	int* pp = nullptr;
	//去堆区分配了4字节的内存空间
	pp = new int(6);
	cout << *pp << endl; // 自动进行了初始化,不			传值,默认值为0;传了值进来,就按传进来的值进行初始化
	char* ptr = new char[10]; //连续分配了10char类型的空间
	cout << ptr << endl;
	delete p; //释放一块空间
	delete [] ptr; //释放连续空间
	return 0;
}

在这里插入图片描述

new、delete与malloc、free的区别?

  1. new/delete是c++的操作符,而malloc/free是库函数

  2. new 在调用时会先为对象分配内存,再调用对象的构造函数,而malloc不会;

    delete 在调用时会调用析构函数,而free不会

  3. 使用malloc为对象指针分配内存,要明确指定分配内存大小,而new不需要

  4. new作为操作符,可以被重载,而malloc不行

  5. new分配内存成功,则返回对象指针;而malloc分配成功会返回void*类型指针

  6. new如果分配内存失败会抛出bad_alloc异常;而malloc分配内存会返回NULL指针

  7. new从自由存储区为对象分配内存;malloc从堆上分配内存(自由存储区可以在堆也可以在其他地方(比如静态存储区),这取决于编译器从哪里为new的使用分配内存。)

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值