c++入门

本文详细介绍了C++编程中的命名空间、命名空间的使用、为何使用、合并命名空间、缺省参数、全缺省函数、半缺省函数、函数重载、引用的概念与特性、内联函数以及auto关键字的运用,帮助读者理解这些关键概念和最佳实践。
摘要由CSDN通过智能技术生成


命名空间

1.命名空间的标准使用格式

什么是命名空间呢,简单来说当我们定义一些变量或者函数时会与头文件发生重复,为了使自己的变量或者函数能够正常使用,我们会将这些变量或者函数写进自己的命名空间中,以便于后续调用

#include<stdio.h>
#include<iostream>
namespace SN
{
	int x = 5;
	
	int Add(int a, int b)
	{
		return a + b;
	}
	
	struct A
	{
		int a = 2;
		int b = 3;
		int Add(int a, int b)
		{
			return a + b;
		}
	};
}
//对于主函数来说,不能直接使用命名空间中的变量和函数,如果想要使用,下面有三种使用方式:

//第一种使用方式,全部展开:公开命名空间中的权限,之后我们就能正常使用这些变量,函数等写入命名空间的东西。
using namespace SN;

//第二种使用方式,部分展开:顾名思义,与全部展开的区别就是只公开部分权限
using SN::x;

int main()
{
	printf("%d",x);
	//第三种使用方式,在使用时展开
	printf("%d",SN::x);
	struct SN::A a;
	return 0;
}
//这三种使用方式可以同时使用,一般来说系统不会冲突
//个人建议第二种使用方式,因为第三种太过于繁琐,第一种方式会与系统函数产生冲突,下面会讲



2.为什么要使用命名空间

(一)为了防止与头文件包含的函数或者其他文件中的变量、函数等发生重名
(二)

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<iostream>

namespace SN
{
	int x = 4;
	int Add(int a, int b)
	{
		return a + b;
	}
	struct A
	{
		int a = 2;
		int b = 3;
		int Add(int a, int b)
		{
			return a + b;
		}
	};
}

int Add(int x, int y)
{
	return (x + y) * 10;
}

//第三种
using SN::Add;
//展开之后全局范围中的函数Add会与局部变量中的Add函数发生冲突,无法编译

int main()
{
	//第一种情况,调用范围为全局的函数,不会与命名空间冲突
	printf("%d\n",Add(1,2));
	//第二种,范围只在这次调用时展开
	printf("%d\n",SN::Add(1, 2));
}

第一和第二种均在没有全部和部分展开之下进行


3.using namespace std;

我们经常会在c++的开头写上这么一句,那么为什么要写上,这一句的作用又是什么?
1.std是c++标准库的命名空间
2.避免与自己的命名空间发生冲突

#include<iostream>
//因为头文件iostream里面使用了命名空间来定义cout,如果不加上这句话,即使包含头文件,cout无法使用
using namespace std;
/*namespace std
{
	...
}*/

int main()
{
	cout << "hello world" << endl;
	//当然如果不想展开也可以这么使用(或者部分展开)
	std::cout << "hello world" << std::endl;
	return 0;
}

4.命名空间的合并

当我们在两个不同头文件(A.h、B.h)里定义了同一名称的命名空间,当我们在源文件(test.c)包含之后,这两个文件中的命名空间的内容会合并在一起(当然要避免定义重复)


缺省参数

以下规则记住就行

全缺省函数

#include<stdio.h>
#include<iostream>
#include<iostream>
using namespace std;

//全缺省函数:相比以往函数,每个形参都给了值
//其特点是,即使调用时没有给相对应的值也能调用
//注意点:调用时必须从左到右依次给值,可以不给值,但是不能跳着给值
void Func1(int a = 1, int b = 2, int c = 3)
{
	cout << "a=" << a  ;
	cout << "b=" << b  ;
	cout << "c=" << c << endl;
}

void Func2(int a, int b, int c)
{
	cout << "a=" << a ;
	cout << "b=" << b ;
	cout << "c=" << c << endl;
}

int main()
{
	Func1();
	Func1(7);
	Func1(7,8);
	Func1(7,8,9);
	/*错误调用例子
	Func1(,8,9);*/
	Func2(4, 5, 6);
	return 0;
}

半缺省

//半缺省函数的形参必须从右向左给值,同样不能跳着给值
#include<iostream>
using namespace std;
//半缺省函数
void Func1(int a, int b, int c = 3)
{
	cout << "a=" << a;
	cout << "b=" << b;
	cout << "c=" << c << endl;
}
void Func2(int a, int b = 2, int c = 3)
{
	cout << "a=" << a;
	cout << "b=" << b;
	cout << "c=" << c << endl;
}
int main()
{
	/*错误案例
	Func1(4)*/
	Func1(4, 5);
	Func1(4, 5, 6);
	Func2(7);
	Func2(7,8);
	Func2(7,8,9);
	return 0;
}


缺省函数声明和定义

如果缺省参数声明和定义分离,那么声明时要给缺省参数,定义不给缺省参数。


函数重载

C语言不允许同名函数,但是c++可以,但是需要构成函数重载。
函数重载的特点:函数名相同,参数不同(顺序,类型,个数)


引用


引用概念

引用不是重新定义一个变量,只是为被引用的变量起了个别名,因此,引用一个变量也不会开辟一块空间,实际上引用创建的对象和引用的对象共用一块空间。
具体格式
类型& 引用变量名 = 引用实体

int main()
{
	int a=1;
	int& b=1;
	int* p;
	int* &pp=p;
	//a,b指向同一块空间
	printf("%p",&a);
	printf("%p",&b);

	b++;
	//随着b的改变,a也发生改变
	printf("%d",a);
	printf("%d",b);
}

引用特性

1.引用在定义时先要初始化(不给实体赋值也能引用);
2.一个变量可以有多个别名;
3.引用一旦引用一个实体,就不能引用其他实体了;

int main()
{
	/*错误案例
	int &a;*/
	int a = 10;
	int& b = a;
	int& c = b;
	return 0;	
}

引用作返回值

//传值返回
int A()
{
	int n=10;
	//由于n属于局部变量,n在A的调用结束后销毁
	return n;
}

int main()
{
	//n虽然已经销毁,但是ret仍然能够被赋值与n相同的值
	//因为n在销毁之前拷贝到寄存器中,寄存器又充当返回值赋值给ret
	int ret =A();
	return 0;
}

//传引用返回
int& A()
{
	int n=10;
	return n;
}

int main()
{
	//因为传引用返回了n的别名,n已经在A的调用结束时销毁  
	//由于不同环境下,n可能被置成随机值,也可能保留原值。无论如何,这种调用方式是不安全的、不规范的
	int ret =A();
	return 0;
}

传值传参和传引用传参的效率对比

传引用传参(任何时候都可以用):
1.提高效率
2.输出型参数(形参的修改,影响的实参)

传引用返回(出了函数作用域对象还在才可以使用)
1.提高效率
2.修改返回对象


引用过程注意点

//引用过程中
//权限可以平移
//权限可以缩小
//权限不可以放大
int main()
{
	const int a = 0;
	//权限的放大
	//int& b = a;
	
	//权限的平移
	const int& c = a;
	
	//权限的缩小
	int x = 0;
	const int& y = x;
	return 0;
}

小知识:

int main()
{
	int i = 0;
	/*错误案例
	double& b = i*/
	//这里的i首先会传给一个临时变量,由于临时变量具有常属性,所以要注意引用使用注意事项
	const double& b = i;
}

内联函数(inline)

标准格式:inline 返回值 函数名(参数);
内联函数不能声明和定义分离,会出现链接错误。


auto关键字

int main()
{
	//自动推导类型
	int a = 0;
	auto b = a;
	auto c = &a;
	auto& d = a;
	//一般场景没有什么价值
	//类型很长,就会有价值,简化代码
	std::vector<std::string> v;
	std::vector<std::string>::inerator it = v.begin();
	auto it = v.begin();
}

1.auto不能作为函数的参数

void TestAuto(auto a)
{}

2.auto不能直接用来声明数组

void TestAuto()
{
	int a[]={1,2,3}
	auto b[]={4,5,6};

3.获取类型名称

int main()
{
	int a;
	double b;
	float c;
	cout << typeid(a).name() <<endl;
	cout << typeid(b).name() <<endl;
	cout << typeid(c).name() <<endl;
}

4.遍历数组

int main()
{
	int arr[]={1,2,3,4,5}
	//这里i只是拷贝,这里arr是数组
	for(auto i : arr)
	{
		x+=2;
	}
	//通过引用可以改变里面的值 
	for(auto& i : arr)
	{
		x+=2;
	}
	for(auto i : arr)
	{
	cout << i << " ";
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值