C到C++入门基础知识

news2025/1/18 3:47:12

一:命名空间:namespace

(一):命名空间的定义

注:命名空间只能定义在全局,不能定义在函数内部。

(1)类似于C语言的结构体,C语言的命名空间定义为:

namespace  name{    // name是命名空间的名字
//  
}

(2)命名空间里成员可以是:变量/函数/自定义类型变量/类,等。

namespace xs {
	int age;
	char name[10];
	int ID;

	struct xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}
};

(3)命名空间可以嵌套定义:

namespace xs {
	int age;
	char name[10];
	int ID;

	struct xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}

    // 嵌套一个老师的命名空间
	namespace teacher {
		char* subject;
		int work_year;
		char* name;
	}
};

(4)在不同文件中定义同一个名字相同的命名空间会被编译器识别为同一个命名空间:

例如同一个项目中分别有两个.cpp文件,两个文件都有xs这命名空间,在编译的时候不会报错,编译器会将他们识别为同一个命名空间。

(5)C++的标准库的命名空间是std(standard).

(二):命名空间的使用

如果我们在命名空间中定义了变量,函数,类或者结构体等,如果我们像C语言一样在外部函数使用时:

namespace xs {
	int age;
	char name[10];
	int ID;

	struct xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}

	namespace teacher {
		char* subject;
		int work_year;
		char* name;
	}
};

int main()
{
	int a = 1;
	int b = 2;

	swap(&a, &b);

	return 0;
}

在使用命名空间域内定义的变量的时候有以下几种方法:

(1)指定命名空间访问:

:: 符号被称为作用域解析运算符

#include <stdio.h>

namespace xs {
	int age;
	char name[10];
	int ID;

	struct xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}

	namespace teacher {
		char* subject;
		int work_year;
		char* name;
	}
};

int main()
{
	int a = 1;
	int b = 2;

	// 这里指定xs这个命名空间域
	xs::swap(&a, &b);

	printf("a = %d \nb = %d", a, b);

	return 0;
}

(2)使用using关键字将命名空间中的某个成员展开

#include <stdio.h>

namespace xs {
	int age;
	char name[10];
	int ID;

	struct xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}

	namespace teacher {
		char* subject;
		int work_year;
		char* name;
	}
};

// 展开xs中的swap函数
using xs::swap;
int main()
{
	int a = 1;
	int b = 2;

	// 这里我们去掉xs::不会报错
	swap(&a, &b);

	printf("a = %d \nb = %d", a, b);

	return 0;
}

(3)展开命名空间中的全部成员:这种方式容易产生命名冲突等问题

#include <stdio.h>

namespace xs {
	int age = 10;
	char name[10] = "小明";
	int ID;

	struct _xs{
		int height;
		char* hobies;
	};

	void swap(int* num1,int*num2)
	{
		int tmp = *num1;
		*num1 = *num2;
		*num2 = tmp;
	}

	namespace _teacher {
		char* subject;
		int work_year;
		char* name;
	}
};

// 展开命名空间中的全部成员,可以不用域解析::就可以随便访问命名空间内的所有成员了
using namespace xs;
int main()
{
	printf("age:%d\n name:%s", age, name);

	return 0;
}

(三):命名空间的价值

(1).解决命名冲突问题

(2).命名空间的本质是开出一个独立的域空间,C++中域有函数局部域全局域命名空间域类域;域影响的是编译时语法查找⼀个变量/函数/类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲就解决了。局部域和全局域除了会影响编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。

二:输入输出:cout / cin

说明:cout和cin是c++的标准输入输出类的对象,他们是标准库<iostream>中定义的,用于窄字符(narrowcharacters(oftypechar))的输入输出。

(1)同C语言相比cout和cin不需要格式化,他们支持任意类型的输入输出,会自动将其他类型转换成字符串类型

(2)cout/cin/(换行endl)等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以要通过命名空间的使⽤⽅式去⽤他们。

(3)有些编译器<iostream>会间接包含printf和scanf

#include <iostream>

using namespace std;

int main()
{
	int age;
	char name[10];
	cin >> age >> name;

	// 这里没有包含<stdio.h>printf也可以正常使用
	printf("age:%d\tname:%s\n", age, name);

	cout << age << endl;
	cout << name << endl;

	return 0;
}

三:缺省参数

定义:在定义函数的时候给予参数一个默认的缺省值。

(1)可分为半缺省,全缺省。

半缺省:部分形参给予默认值。C++规定半缺省参数必须从右往左
依次连续缺省,不能间隔跳跃给缺省值。

全缺省:全部形参给予默认值。

(2)带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。

(3)含缺省参数的函数调用的时候,没有传参使用默认值,传参使用传递的值。

#include <iostream>

// 半缺省
int Add1(int b, int c, int a = 0)
{
	return a + b + c;
}

// 全缺省
int Add2(int a = 0, int b = 0)
{
	return a + b;
}

using namespace std;

int main()
{
	int n1 = 2;
	int n2 = 3;

	cout << Add1(n1,n2) << endl;
	// 全缺省的
	cout << Add2() << endl;

	return 0;
}

(4)函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省值。

我们将.c文件的两个函数声明放到,h文件.c文件依然给缺省值

编译器报错:

所以应该将.c文件中的缺省参数去掉

四:内联函数:inline

使用inline关键字修饰的函数被调用时会在调用处将函数定义展开

(1)加上inline的函数,如果函数代码较多或者是递归,编译器会忽视不展开代码。

(2)使用inline的本质是替换函数调用,提高程序执行的效率(因为函数调用需要建立函数栈帧,需要开辟空间等消耗),和C语言定义的宏是一个道理。

(3)inline不建议声明和定义分离到两个⽂件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错

使用inline也很简单,直接在函数的前面加个inline就可以了。

inline int add(int a, int b)
{
    return a + b;
}

五:函数重载

函数重载:其实就是同名函数,类的多态行为。

满足函数重载的条件:

1.函数的形参不同

2.函数的参数个数不同

3.形参的类型不同

4.形参类型顺序不同

// 函数的形参不同以及形参个数不同
int add(int a, int b,int c = 1)
{
	return a + b;
}
double add(double a, double b, int c = 1)
{
	return a + b + c;
}

// 形参不同和形参类型顺序不同
void func(char c, int n)
{
	cout << c << "  " << n << endl;
	printf("形参不同\n");

}

void func(int n, char c)
{
	cout << c << "  " << n << endl;
	printf("形参类型顺序不同\n");
}


int main()
{
	// 名字一样调用的是两个函数
	func('a', 4);
	func(4, 'a');

	cout << add(1, 2) << endl;
	cout << add(1.0, 2.0, 3) << endl;

	return 0;
}

但是返回值不同不可以

六:引用

(一)引用的定义和特性

(1)引用就是给一个对象起别名,不开辟内存空间。

其基本格式为:类型& 引⽤别名 = 引⽤对象; (这里的&不是取地址)

#include <iostream>
using namespace std;


int main()
{
	int a = 0;
	int c = 5;

	int& ra = a;
	int& rc = c;

	// 对引用进行++
	ra++;
	rc++;

	cout << "ra++后a:" << a << endl;
	cout << "rc++后c:" << c << endl;

	cout << "ra的地址为:" << &ra << endl;
	cout << "a的地址为:" << &a << endl;
	cout << "rc的地址为:" << &rc << endl;
	cout << "c的地址为:" << &c << endl;

	return 0;
}

(2)引用定义的时候必须要初始化:看吧。

(3)⼀个变量可以有多个引⽤:跟一个人有多个绰号差不多

#include <iostream>
using namespace std;


int main()
{
	int a = 0;
	int c = 5;

	int& ra = a;
	int& rra = a;
	int& rc = c;

	return 0;
}

(4)引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体:

(5)引用可以引用引用;

int a = 0;

int& ra = a;

// 这样是可以的
int& rra = ra;

(二)引用的使用

(1)引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变被引⽤对象

例如在函数传参的时候

void fun(int& x)
{
	x++;
}

int main()
{
	int a = 0;
	fun(a);
	// 这里相当于将a取了一个别名,然后函数里面根据这个别名找到对应的对象进行运算
	cout << a << endl;

	return 0;
}

(三)const修饰引用

(1)const修饰引用可以使权限缩小,但是不能使权限放大,当然const修饰的应用对象是不能被修改的。

// 定义一个变量
const int a = 8;

// 权限放大,不允许,会报错的
int& ra = a;

// 权限平替,这样可以
const int& ra = a;

int b = 0;
// 权限缩小
int& rb = b;
// 不允许
rb++;
// 允许
b++;

// 权限缩小只是缩小引用的权限缩小,而不会影响引用的对象的权限。

(2)引用可以引用临时对象:

临时对象:在程序运行中产生的用于转换的值或者其他对象,例如:类型转换,函数传参(函数传参是临时拷贝,传地址就不会产生临时对象)。这期间就会产生临时对象。

临时对象具有常性:

void fun(int& x)
{
	x++;
}

void fun2(int x)
{
	int& rx = x;

	x++;

	cout << rx << endl; // 这输出3
}

int main()
{
	int a = 0;
	fun(a);

	// 这里相当于将a取了一个别名,然后函数里面根据这个别名找到对应的对象进行运算
	cout << a << endl;

	const int n = 2;

	int rn = n;
	n++;  // 这里不允许

	// 这里int向double转换的时候产生了临时变量,权限被放大了。
	const double& rm = n * 3;

	// n是const修饰的变量,传递给函数,传递的是它的一份临时拷贝
	fun2(n);

	cout << rm << endl; // 这里输出6
	return 0;
}

(四)指针和引用的区别

(1)指针需要开辟空间,指针变量存储的是空间的地址。引用不需要开空间,他是所引用对象的另一个别名。

(2)引用定义的时候就必须要初始化,指针可以不用

int& r;

// 指针不初始化没问题,编译器不会初始化,但是这样就成了野指针,不建议这样搞
int* ptr;

(3)指针容易出现空指针和野指针,引用不容易出现空引用,引用比指针更安全。

空引用:

(4)引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。

(5)引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。

int main()
{
	int a = 0;
	int& b = a;
	int d = 5;
	b = d;

	int* p = &a;
	cout << p << endl;
	p = &d;
	cout << p << endl;

	cout << "a和b的地址" << endl;
	cout << &a << endl;
	cout << &b << endl;


	return 0;
}

(6)sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台下占4个字节,64位下是8byte)

七:nullptr和NULL的区别

NULL在C++中被定义为了宏0,容易导致和整型的0混淆使用,而nullptr不会出现这种情况,C语言支持NULL不支持nullptr。C++都支持。

int main()
{
	// 这里明着给int类型的a赋值指针但是没报错
	int a = NULL;
	printf("%d", a);

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2132645.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java Enterprise System 体系结构

本章概述了 Java Enterprise System 部署所基于的体系结构概念。 章中描述了一个框架,在此框架内从三维角度对 Java Enterprise System部署体系结构进行了分析,它们分别是:逻辑层、基础结构服务级别和服务质量。这三维在下图中以图解形式显示为正交坐标轴,它们有助于在体系…

Word使用手册

修改样式 编辑word文档时&#xff0c;标题和正文文本通常有不同的格式&#xff0c;如果能将这些格式保存为样式&#xff0c;下一次就能直接调用样式&#xff0c;而不需要重复手动设置格式。 可以将样式通常保存为不同的 样式模板.docx&#xff0c;要调用不同样式集&#xff0…

看Threejs好玩示例,学习创新与技术

我把在一些好玩的ThreeJS的效果&#xff0c;认真分析技术&#xff0c;写成博客&#xff0c;欢迎大家去看。 后面慢慢补充。 看Threejs好玩示例&#xff0c;学习创新与技术(一)https://mp.weixin.qq.com/s/eJeGmnla0D4zEMl4AwFsVw

波克城市 x NebulaGraph|高效数据血缘系统在游戏领域的构建实战

关于波克城市和作者‍‍ 波克城市&#xff0c;一家专注于研发精品休闲游戏的全球化公司&#xff0c;连续七年入选中国互联网综合实力百强&#xff0c;2023 年位列 17 位。波克城市旗下拥有《捕鱼达人》《猫咪公寓2》等精品休闲游戏&#xff0c;全球注册用户超 5 亿&#xff0c;…

AB 1756-L62 与 AB 5069 通过串口通信

PLC AB L62 控制器 插槽2 Path, RS232=2, 3 PLC Compactlogix 5069-SERIAL 配置

【提示词】浅谈GPT等大模型中的Prompt

Prompt是人工智能&#xff08;AI&#xff09;提示词&#xff0c;是一种利用自然语言来指导或激发人工智能模型完成特定任务的方法。在AI语境中&#xff0c;Prompt是一种自然语言输入&#xff0c;通常指的是向模型提出的一个请求或问题&#xff0c;这个请求或问题的形式和内容会…

【QT】系统-上

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;折纸花满衣 &#x1f3e0;个人专栏&#xff1a;QT 目录 &#x1f449;&#x1f3fb;事件QWidget中常见的事件 &#x1f449;&#x1f3fb;处理鼠标事件&#xff1a;leaveEvent和enterEvent&#x1f449;&a…

epoll接口使用 -- 非阻塞式网络io(仅读事件)

目录 epoll接口使用 思路 注意点 代码 封装epoll接口 epoll.sever.hpp 运行结果 epoll接口使用 接口epoll原理介绍 -- epoll接口介绍,epoll模型介绍原理,接口和模型的关系,epoll优点(和select/poll进行对比)-CSDN博客 思路 我们可以先将系统提供的epoll简单封装一下…

Java 入门指南:Java 并发编程模式 —— 生产者-消费者模式

文章目录 生产者-消费者问题解决方案 生产者-消费者模式模式的核心问题基本原理生产者消费者 优点实现方式使用阻塞队列示例代码 使用 wait/notify 机制wait()notify()notifyAll()示例代码 使用 Exchanger示例代码 应用场景总结 生产者-消费者问题 生产者消费者问题是一个经典…

Java项目: 基于SpringBoot+mybatis+maven旅游管理系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven旅游管理系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

【SqlServer】SQL Server Management Studio (SSMS) 下载、安装、配置使用及卸载——保姆级教程

超详细的 SQL Server Management Studio (SSMS) 下载、安装、连接数据库配置及卸载教程 SQL Server Management Studio (SSMS) 是微软提供的图形化管理工具&#xff0c;主要用于连接、管理和开发 SQL Server 数据库。以下是详细的 SSMS 下载、安装、连接数据库以及卸载的完整教…

CLIP:Learning Transferable Visual Models From Natural Language Supervision

论文:https://arxiv.org/abs/2103.00020 代码:https://github.com/openai/CLIP 官博:https://openai.com/index/clip/ 复现:https://github.com/mlfoundations/open_clip 基础知识 InfoNCE loss

S7-1500T分布式同步功能

1. 功能描述工控人加入PLC工业自动化精英社群 在一些实际应用中&#xff0c;会需要很多轴进行同步运行&#xff0c;如印刷机、纸尿裤生产线等。由于一个 PLC 的运动控制资源有限&#xff0c;控制轴的数量也是有限的&#xff0c;就会需要多个 PLC 间协调实现轴工艺对象的跨CPU的…

使用Cerbot---Let’s Encrypt生成免费的ssl证书,并设置自动更新证书

安装Certbot客户端 yum install certbot 获取证书 certbot certonly --webroot -w /var/www/demo.com -d demo.com 按照步骤 输入邮箱 同意条例 成功申请证书 修改对应的nginx的conf文件 server {listen 80;listen [::]:80;server_name demo.com;# 将 HTTP 请求重定向到 H…

分布式事务学习笔记(一)分布式事务问题、CAP定理、BASE理论、Seata

文章目录 1 分布式事务问题1.1 本地事务1.2 分布式事务1.3 创建分布式事务演示案例 2 理论基础2.1 CAP定理2.2 BASE理论2.3 解决分布式事务的思路2.4 Seata 1 分布式事务问题 1.1 本地事务 本地事务&#xff0c;也就是传统的单机事务&#xff0c;它必须要满足以下四个原则&am…

RabbitMQ延迟消息——DelayExchange插件

什么是死信以及死信交换机 当一个队列中的消息满足下列情况之一时&#xff0c;可以成为死信&#xff1a; 1. 消费者使用basic.reject或 basic.nack声明消费失败&#xff0c;并且消息的requeue参数设置为false 2. 消息是一个过期消息&#xff0c;超时无人消费 3. 要投递的队列消…

【JavaSE】--方法的使用

文章目录 1. 方法概念及使用1.1 什么是方法1.2 方法定义1.3 方法调用的执行过程1.4 实参和形参的关系&#xff08;重要&#xff09;1.5 没有返回值的方法 2. 方法重载2.1 方法重载概念2.2 方法签名 3. 递归3.1 递归的概念3.2 递归执行过程分析3.3 递归练习 1. 方法概念及使用 1…

解码3D数字人及AIGC产品,如何赋能医美行业全场景业务增长

9月13日&#xff0c;第六届“医美小小聚”暨医美信息与服务创新发展大会在热烈的氛围中拉开帷幕。此次盛会汇聚了医美行业的顶尖精英与前瞻者&#xff0c;他们围绕“聚焦营销&#xff0c;合规增长&#xff0c;融合共创”的主题&#xff0c;深入剖析了行业的新趋势、新机遇与新挑…

SpringBoot开发——整合SSL证书启用HTTPS协议

文章目录 1、https协议2、SpringBoot项目启用HTTPS协议过程2.1 创建SpringBoot项目2.2 准备SSL证书2.3SpringBoot设置2.4启动项目 1、https协议 网站使用的协议包括&#xff1a;http协议和https协议。http协议就是网址以http://开头的&#xff0c;https协议就是网址以https://…

http连接github远程仓库密码问题解决办法

目录 一、问题&#xff1a;使用http连接失败 二、解决办法&#xff1a;使用个人访问令牌。 1、生成访问令牌&#xff1a; 步骤 1: 登录 GitHub 步骤 2: 进入设置页面 步骤 3: 生成新的访问令牌 步骤 4: 配置访问令牌 步骤 5: 复制令牌 2. 使用访问令牌 一、问题&#…