【C++】c++语法基础

news2024/11/15 7:03:26

引入,第一个c++程序

这是用c++写的helloworld程序

#include<iostream>
using namespace std;
int main()
{
	cout << "hello,world\n" << endl;

	return 0;

}

接下来我们将根据上述的代码来学习c++的基本语法。

命名空间(namespace)

在c语言中函数被包含在不同的头文件中,但是,这样会出现一个问题,当我们定义的变量与头文件中的变量重名时,在调用时就会出现问题。

#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
    printf("%d\n", rand);
    return 0;
}

 此时编译器就不能区分rand究竟是什么了。

为了解决这一问题,c++引入了命名空间这一概念。c++中将函数,变量封装在命名空间中。

定义命名空间,需要用到namespace关键字,后面跟命名空间的名字,然后接⼀对{}即可,{}中 即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以不同的命名空间中同名的变量就不在冲突了。

#include <iostream>

namespace A {
    int x = 5;
    void printX() {
        std::cout << "x in namespace A: " << x << std::endl;
    }
}

namespace B {
    int x = 10;
}

int main() {
    A::printX(); // 输出:x in namespace A: 5
    B::x = 15; // 修改命名空间B中的变量x的值
    A::printX(); // 输出:x in namespace A: 5,命名空间A中的x并未受到影响

    return 0;
}

A和B这两个命名空间中的X不会相互影响 。

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

namespace只能定义在全局,当然它还可以嵌套定义。

#include <iostream>
using namespace std;
namespace YG 
{
	int x = 5;
	namespace XIN 
	{
		int x = 2;
	}
}
int main()
{
	cout << YG::x << endl;
	cout << YG::XIN::x << endl;

	return 0;
}

项目工程中多文件中定义的同名namespace会认为是⼀个namespace,不会冲突。

C++标准库都放在⼀个叫std(standard)的命名空间中 。

命名空间的使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。所以 下⾯程序会编译报错。所以我们要使用命名空间中定义的变量/函数,有三种方式

指定命名空间访问,项目中推荐这种方式。通过作用域解析运算符(::)来精确访问。

#include <iostream>
using namespace std;
namespace YG 
{
	int x = 5;
	namespace XIN 
	{
		int x = 2;
	}
}
int main()
{
	cout << YG::x << endl;
	cout << YG::XIN::x << endl;

	return 0;
}

using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式。

//展开命名空间的某个成员
#include <iostream>
using namespace std;
namespace YG
{
	int x = 5;
	namespace XIN
	{
		int y = 2;
	}
}
using YG::x;
int main()
{
	cout << x << endl;
	cout << YG::XIN::y  << endl;

	return 0;
}

展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。

//展开整个命名空间
#include <iostream>
using namespace std;
namespace YG
{
	int x = 5;
	namespace XIN
	{
		int y = 2;
	}
}
using namespace YG;
using namespace YG::XIN;
int main()
{
	cout << x << endl;
	cout << y << endl;

	return 0;
}

在这里我们可以发现嵌套定义的命名空间,只展开最高层的命名空间并不能直接访问其包含的其他命名空间中的变量。若要访问其下层的命名空间也需要单独展开。

C++输入&输出

在C++中,iostream 是一个标准库,用于处理输入(input)和输出(output)。它提供了一种方便的方式来进行控制台输入输出操作和文件操作。

具体来说iostream提供了以下主要的类和对象:

• std::cin 是istream类的对象,它主要面向窄字符(narrowcharacters(oftypechar))的标准输入流。

• std::cout 是ostream类的对象,它主要面向窄字符的标准输出流。

• std::endl 是⼀个函数,流插入输出时,相当于插入⼀个换行字符加刷新缓冲区。

• >>是流提取运算符。(C语言还用这两个运算符做位运算左移/右移)

• 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动动指定格式,C++的输入输出可以自动识别变量类型(本质是通过函数重载实现),其实最重要的是 C++的流能更好的支持自定义类型对象的输入输出。


#include <iostream>
using namespace std;
int main()
{
	int a = 0;
	double b = 0.1;
	char c = 'x';

	cout << a << " " << b << "  " << c << endl;
	printf("%d %lf  %c\n", a, b,c);
	// 可以自动识别变量的类型

	cin >> a;
	cin >> b >> c;
	cout << a << endl;
	cout << b << "  " << c << endl;
	return 0;
}

缺省参数

在 C++ 中,缺省参数(默认参数)允许在函数声明中为一个或多个参数指定默认值。这意味着在调用函数时,如果没有显式提供该参数的值,编译器将使用预先定义的默认值。默认参数的声明使得函数调用更加灵活,并且可以简化函数重载的需求。缺省参数分为全缺省和半缺省参数。


#include <iostream>
#include <assert.h>
using namespace std;
void Func(int a = 0)
{
	cout << a << endl;
}
int main()
{
	Func();
	//没有传参时,使用参数的默认值

	Func(10);  
	// 传参时,使用指定的实参

	return 0;
}

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

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

#include <iostream>
using namespace std;
//全缺省

void Func1(int a = 10, int b = 20, int c = 30)
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}
//半缺省

void Func2(int a, int b = 10, int c = 20)//半缺省必须从右往左缺省
{
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl << endl;
}
int main()
{
	Func1();
	Func1(1);
	Func1(1, 2);
	Func1(1, 2, 3);
	Func2(100);
	Func2(100, 200);//传参必须从左往右依次传。Func2(,200,300)这样是错误的
	Func2(100, 200, 300);
	return 0;
}

函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省 值。这样可能会出现歧义,如下:

// 声明和定义中分别提供默认参数的情况(非法)
void example(int a, int b = 10); // 声明

void example(int a, int b = 20) { // 定义
    // 函数体
}

函数重载

在 C++ 中,函数重载(Function Overloading)是指允许在同一个作用域内定义多个具有相同函数名但参数列表不同的函数。具体来说,函数重载可以通过以下几种方式实现:

  1. 参数个数不同: 在同一个作用域内,可以定义参数个数不同的同名函数。例如:

    void print(int a);
    void print(int a, int b);

    这里的 print 函数根据参数个数的不同,可以调用不同的实现。

  2. 参数类型不同: C++ 允许定义参数类型不同的同名函数。例如:

    void display(int a);
    void display(double a);

    这里的 display 函数根据参数的类型(整数或浮点数)来决定调用哪一个版本。

  3. 参数顺序不同: 参数的类型和个数相同,但顺序不同的函数也可以重载。例如:

    void drawLine(int x1, int y1, int x2, int y2);
    void drawLine(int x1, int x2, int y1, int y2);

    这里的 drawLine 函数定义了两个版本,分别用于不同顺序的坐标参数。

  4. 常量性区别: 如果一个函数的参数是常量引用(const 引用),那么可以通过区分参数是否为常量来实现重载。例如:

    void process(const int& x);
    void process(int& x);

    这里的 process 函数区分了参数 x 是常量引用还是非常量引用。

  5. 函数重载与返回类型无关: C++ 中,函数的返回类型不能作为重载的标志。也就是说,不能仅仅依靠返回类型的不同来重载函数。

    int calculate(int a, int b) {
        return a + b;
    }
    
    float calculate(int a, int b) {
        return a * b; // 错误:与前一个函数的返回类型相同,不允许重载
    }

    这样的两个函数是非法的,不构成函数重载。

引用

在 C++ 中,引用(Reference)是一个允许程序员使用别名访问变量或对象的机制。引用提供了对变量或对象的另一种名称,通过这个名称可以直接访问到原始的变量或对象,而不是其副本。这样可以解决一些指针的问题但不能替代指针。与指针不同的时,指针不指代变量本身,不能直接修改变量。

#include<iostream>
using namespace std;
int main()
{
	int a = 0;
	// 引用:b和c是a的别名

	int& b = a;
	int& c = a;
	// 也可以给别名b取别名,d相当于还是a的别名

	int& d = b;
	++d;
	// 这里取地址我们看到是⼀样的

	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	cout << &d << endl;
	return 0;
}

引用只是给变量起了一个别名,所有的别名都只指那一个变量。

引用的特性

引用在定义时必须初始化 

在c语言中,指针在定义时,初始化是非强制的,但在c++的引用中,初始化是一种强制的行为。

⼀个变量可以有多个引用

引用⼀旦引用⼀个实体,再不能引用其他实体

#include<iostream>
using namespace std;
int main()
{
	int a = 10;
	
	//int& ra;//编译会报错,引用必须初始化
	int& b = a;
	int c = 20;
	b = c;
	//这里并非让b引用c,因为C++引用不能改变指向,
	//这里是赋值,a,b的值都变为20
	cout << &a << endl;
	cout << &b << endl;
	cout << &c << endl;
	return 0;
}

引用的使用 

引用在实践中主要是于引⽤传参和引⽤做返回值中减少拷贝提高效率和改变引用对象时同时改变被 引用对象。

引用传参跟指针传参功能是类似的,引用传参相对更方便⼀些

void Swap(int& rx, int& ry)
 {
 int tmp = rx;
 rx = ry;
 ry = tmp;
 }
 int main()
 {
 int x = 0, y = 1;
 cout << x <<" " << y << endl;
 Swap(x, y);
 cout << x << " " << y << endl;
 return 0;
 }

const引用

在 C++ 中,const引用是一种特殊类型的引用,其声明中包含了const关键字,const引用允许我们通过引用访问对象,同时确保在引用生命周期内不会修改所引用的对象(只读不写)。

int main()
{
	const int a = 10;
	// 编译报错:error C2440 : “初始化” :⽆法从“const int”转换为“int& ”
	//这里的引用是对a访问权限的放大

	//int& ra = a;
	//这样才可以

	const int& ra = a;
	// 编译报错:error C3892 : “ra”:不能给常量赋值

	//ra++;
	//这里的引用是对b访问权限的缩小

	//rb++;
	int b = 20;
	const int& rb = b;
	// 编译报错:error C3892 : “rb”:不能给常量赋值

	return 0;
}

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

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

相关文章

PHP:连接钉钉接口-钉钉回调事件,本地测试数据

前置数据参考 数据说明:参见官方文档回调事件消息体加解密 - 钉钉开放平台 (dingtalk.com) URL后面带的参数: signature=5a65ceeef9aab2d149439f82dc191dd6c5cbe2c0&timestamp=1445827045067&nonce=nEXhMP4r Post参数: { "encrypt":"1a3NB…

日常开发记录分享——C#控件ToolTip实现分栏显示内容

文章目录 需求来源实现思路实施请看VCR等等别走&#xff0c;有优化 需求来源 需要在鼠标浮动到指定位置后提示出详细的信息&#xff0c;一开始使用的tooltip实现&#xff0c;但是里面的内容效果并不理想&#xff0c;需要有条理性&#xff0c;于是就想到能不能将展示的东西分列…

邮件推送API如何集成到现有系统发送邮件?

邮件推送API安全性策略&#xff1f;如何选择邮件推送API服务商&#xff1f; 在当今数字化时代&#xff0c;邮件通信是企业和个人交流的重要方式之一。集成邮件推送API到现有系统可以大大提升通信效率和自动化程度。AokSend将介绍如何将邮件推送API集成到现有系统中&#xff0c…

关于P2P(点对点)

P2P 是一种客户端与客户端之间&#xff0c;点对点连接的技术&#xff0c;在早前的客户端都是公网IP&#xff0c;没有NAT的情况下&#xff0c;P2P是较为容易实现的。 但现在的P2P&#xff0c;实现上面会略微有一些复杂&#xff1a;需要采取UDP打洞的技术&#xff0c;但UDP打出来…

自动控制: 时间最优的PID控制算法

自动控制&#xff1a; 时间最优的PID控制算法 在计算机控制系统中&#xff0c;时间最优控制旨在使系统从一个初始状态转到另一个目标状态所经历的过渡时间最短。利用最大值原理&#xff0c;可以设计出控制量只在 u ( t ) ≤ 1 u(t) \leq 1 u(t)≤1范围内取值的时间最优控制系…

(39)智能电池

文章目录 前言 1 通过任务规划器进行设置 2 补充信息 3 限制条件 4 参数说明 前言 虽然还不是很普遍&#xff0c;但智能电池更容易从飞行器上安装和拆卸&#xff0c;并且能够提供更多关于电池状态的信息&#xff0c;包括容量、单个电池电压、温度等。 ArduPilot 支持几种…

【分布式系统】 单机架构 | 分布式架构 | 集群 | 主从架构 | 分库分表 | 冷热分离 | 微服务

文章目录 [toc] 分布式系统一、单机架构二、分布式系统三、应用服务器集群四、读写分离 / 主从分离架构五、引入缓存/冷热分离架构六、垂直分库七、微服务架构——业务拆分代价优势 八、名词解释1.应用&#xff08;Application&#xff09;/系统(System)2.模块&#xff08;Mode…

解决“QtCreator无法呼出搜狗输入法“问题

由于在Ubuntu系统上&#xff0c;QtCreator软件默认使用IBus类型的输入法&#xff0c;而搜狗输入法是fcitx类型的&#xff0c;所以需要在Linux的系统设置 -->区域与语言 里 -->勾选 fcitx类型&#xff0c;如图(1)所示。     这里以QtCreator 4.5.2Ubuntu 18为例&#xf…

学习测试14-实战3-复习-使用CANoe打开半成品

数据 链接: https://pan.baidu.com/s/1k0SFq0luDvEbqimFgtfyKg?pwd9a5t 提取码: 9a5t 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 1&#xff0c;导入信号、报文、节点 2&#xff0c;导入数据库 3&#xff0c;导入can代码 4&#xff0c;导入环境变量 5&#x…

RTP协议基础

概述 1. 基本概念 RTP协议&#xff0c;全称为Real-time Transport Protocol&#xff08;实时传输协议&#xff09;是一种用于在IP网络上传输音频、视频等实时数据的网络协议。 在流媒体&#xff08;流媒体就是指可在线/实时观看音视频的互联网产品&#xff09;数据传输过程中&…

抄作业-跟着《React通关秘籍》捣鼓React-playground-上集

文章目录 前言1. 搭建react 开发环境2、react hooks 知识3. 目标&#xff1a;跟着小册实现 react-playground3.1 整体布局初始化项目使用Alloment 来实现左右分屏的拖拉功能 3.2 代码编辑器Monaco Editor 3.3 实现了多文件的切换用 useContext 来共享数据。优化 tab的样式&…

Vue响应式的原理

一. Vue响应式原理的核心概念 1. Vue响应式原理基于以下核心概念&#xff1a; ① 响应式对象&#xff1a;Vue使用Object.defineProperty()来 reactive&#xff08;反应&#xff09;对象中的属性&#xff0c;使其变化可以被检测。 注意&#xff1a; ★ Object.definePropert…

Python字符串处理技巧:一个小技巧竟然能省下你一半时间!

获取Pyhon及副业知识&#xff0c;关注公众号【软件测试圈】 效率翻倍的秘密&#xff1a;Python字符串操作的5个惊人技巧 在Python编程中&#xff0c;字符串处理在数据分析、Web开发、自动化脚本等多个领域都有广泛应用。Python提供了一系列强大的字符串处理函数&#xff0c;能够…

蚓链数字化生态平台:构建城市智能商业,引领协同发展新潮流

​在当今数字化飞速发展的时代&#xff0c;城市商业的运行模式正在经历着数字化变革。蚓链数字化生态平台应运而生&#xff0c;以其强大的功能和创新的理念&#xff0c;成为构建城市智能商业枢纽中心的关键力量&#xff0c;推动着平台互通、业务贯通、管理协同的全新发展格局。…

MySQL数据库-索引和视图

一、视图 1.什么是视图 MySQL中的视图&#xff08;view&#xff09;是一种虚拟表&#xff0c;其内容由查询定义&#xff0c;视图本身并不包含数据。视图看起来和真实的表完全相同&#xff0c;但其中的数据来自定义视图时用到的基本表&#xff0c;并且在打开视图时动态生成&am…

【JavaWeb项目】——外卖订餐系统之登入、登入后显示餐品信息、用户注册、注销部分

&#x1f3bc;个人主页&#xff1a;【Y小夜】 &#x1f60e;作者简介&#xff1a;一位双非学校的大二学生&#xff0c;编程爱好者&#xff0c; 专注于基础和实战分享&#xff0c;欢迎私信咨询&#xff01; &#x1f386;入门专栏&#xff1a;&#x1f387;【MySQL&#xff0…

什么是内网ip地址?如何查询电脑内网ip地址

在数字化时代&#xff0c;互联网已经成为我们日常生活和工作中不可或缺的一部分。无论是家庭网络还是企业办公环境&#xff0c;每台接入网络的设备都需要一个独特的标识来区分彼此&#xff0c;这个标识就是IP地址。IP地址全称为“互联网协议地址”&#xff0c;是设备在网络中的…

springboot整合junit-用于测试用例

package impl;public interface BookDao {public void save(); }第一步&#xff1a;打开软件&#xff0c;点击file&#xff0c;点击new 然后选择module&#xff0c;在右侧选择springboot 第二步&#xff1a;选择配置和JDK以及java版本 ①选择maven类型 ②选择JDK1.8版本 ③选…

react中路由懒加载

// 1.引入方法&#xff0c;用于创建路由实例 // createBrowserRouter是用于创建history模式 // createHashRouter是用于创建hash模式 // 路由模式的切换只需要更改创建路由实例的方法就行了&#xff0c;其他地方不需要更改 import { createBrowserRouter,createHashRouter } fr…

deployment

一.deployment rc和rs控制器都是控制pod的副本数量的&#xff0c;但是&#xff0c;他们两个有个缺点&#xff0c;就是在部署新版本pod或者回滚代码的时候&#xff0c;需要先apply资源清单&#xff0c;然后再删除现有pod&#xff0c;通过资源控制&#xff0c;重新拉取新的pod来实…