C++——入门基础语法(2)


这里对上一篇的语法进行一点补充,在介绍新的语法

命名空间

我们知道,命名空间的作用是解决命名冲突,包括我们和C++库的冲突,程序员之间的冲突。那么,解决了命名冲突,如何对一个变量或函数进行查找呢?编译时系统会先在局部域内查找变量或函数,没有则去全局域查找

比如

#include<iostream>
using namespace std;
int x=0;
int main()
{
    int x=1;
    printf("%d",x);
    return 0;
}

当我们运行时,会打印一个1,因为局部域内有x这个变量。当把main函数内的x注释掉后,再运行代码,会打印一个0,这是因为局部域内没有x这个变量,而全局域内有。

但当我们定义了一个命名空间后,就多了一个命名空间域,此时对于变量或函数的查找顺序有了改变,具体顺序如下图。
在这里插入图片描述

#include<iostream>
using namespace std;

namespace T
{
	int z = 2;
}
using namespace T;

int y = 1;
int x = 1;

int main()
{
	int x = 0;
	printf("%d\n", x);
	printf("%d\n", y);
	printf("%d", z);
	return 0;
}

运行结果为0,1,2

当全局域和命名空间域存在同名变量,且命名空间被展开了,那么在访问这一变量或函数会有歧义。但是此时同名变量不会冲突,只是会存在访问的歧义,系统不知道你要访问哪一个,因此要么不展开命名空间,要么就指定访问。
比如这段代码

#include<iostream>
using namespace std;

namespace T
{
	int z = 2;
	int x = 2;
	int y = 2;
}
using namespace T;

int y = 1;
int x = 1;

int main()
{
	int x = 0;
	printf("%d\n", x);
	//printf("%d\n", y);//error 歧义
	printf("%d\n", ::y);//访问全局的y
	printf("%d\n", T::y);//访问命名空间的y
	printf("%d", z);
	return 0;
}

介绍到这时,using namespace std 是什么意思大家肯定知道了。std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中,日常编写代码时可以直接展开。

引用

介绍引用时,我们写了一个这样的交换函数

void swap(int& a, int& b)
{
	int c = a;
	a = b;
	b = c;
}

int& 和int* 很类似,也就是引用和指针很类似。那么它们有没有联系呢,在语法层面上,它们没有联系,引用和引用实体共同管理一块空间,引用没有自己的空间。在底层实现上,引用是按照指针的方式来实现的。

因此引用和指针的区别如下;

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址

  2. 引用在定义时必须初始化,指针没有要求(为了避免野指针,才需要初始化)

  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何
    一个同类型实体,即改变指向

  4. 没有NULL引用,但有NULL指针

  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32
    位平台下占4个字节,64位平台下占8字节)

  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

  7. 多级指针,但是没有多级引用

  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理

  9. 引用比指针使用起来相对更安全

引用在作为参数和返回值时有优势的,我们知道,函数的形参实际是实参的一份临时拷贝,拷贝就会造成消耗,而引用作为参数不需要拷贝。这里后面会仔细讲解。

缺省参数

当函数有缺省参数且声明和定义分离时,缺省值不能再声明和定义同时给,在声明或定义其中一个给缺省值就可以。

1. C++的输入和输出

C++的输入和输出分别用到**<<>>**运算符

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件
    以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行,他们都包含在 < iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。
    C++的输入输出可以自动识别变量类型

用法如下

cin>>变量名
cout<<输出内容

int main()
{
	int x ;
	char ch ;
	double d ;

	cin >> x >> ch >> d;

	cout << x << " " << ch << " " << d << "" << endl;
	return 0;
}

再键盘输出1,“a”,1.2 运行结果如图
在这里插入图片描述

关于IO流的概念,后续会介绍,这里只要先了解cout和cin的用法即可。

2. 内联函数

概念:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方将内联函数展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率

内联函数是一种以空间换时间的做法,在函数调用处将函数展开,因此缺点也很明显,使文件变大。并不是所有函数都建议用inline修饰,只有那些函数体小且频繁调用的函数才建议用inline修饰。另外,内联函数不能声明和定义分离,这是因为函数展开后就没有函数地址,会导致链接时找不到函数,产生链接错误。

如下
在这里插入图片描述

3. auto

当程序的代码量越来越多,不免某些变量的类型会变得很长很长,就会导致对变量类型的书写会产生错误。auto的作用为自动推导变量的类型。

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编译时会将auto替换为变量实际的类型。

int main()
{
	int a = 10;
	auto b = a;
	auto c = "abc";
	auto ptr = &c;

	cout << typeid(a).name() << endl;
	cout << typeid(b).name() << endl;
	cout << typeid(c).name() << endl;
	cout << typeid(ptr).name() << endl;
}

a和b的类型为int,c的类型为char*,ptr的类型为char**
运行结果如下图

在这里插入图片描述

通过调试也可以看到变量的类型

在这里插入图片描述

使用auto时需要注意几个点:
1. 在推导指针类型时,auto和auto*没有区别

int x=10
auto p=&x;
auto* px=&x;

都是正确的,但在推导引用类型时,必须使用auto&

int x=1;
auto y=x;//y的类型为int
auto& z=x;//z的类型为int&,z是x的别名

2. 连续定义变量时,这些变量必须是相同类型;

auto x=10,y=1.0;//错误
auto z=1,a=2;//正确

3. auto不能出现在函数的形参列表,也不能用来声明数组。

4. 范围for循环

之前我们遍历数组的方式都是,for(int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) { } 这样,循环条件可能会出错,从而导致数组越界或者遍历不全。范围for循环就不会产生这样的错误

语法

for(变量类型 变量 :数组名等)
{
操作
}

比如

int main()
{
	int arr[5] = { 0 };
	for (int& a : arr)
	{
		cin >> a;
	}

	for (auto b : arr)
	{
		cout << b << " ";
	}
}

变量类型可以写,也可以使用auto推导。变量可以是任意的名字。原理是,将数组或其他容器内的数据依次赋给变量,然后对变量进行操作。

范围for也有缺点,如不能逆向遍历。

关于C++基础的语法就介绍这些,随着后续内容的介绍,会对这些语法进行练习和使用,也会有更深的理解。

  • 30
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值