c++.初篇01

1.c++关键字

c++统计63个关键字,c语言32个关键字(此篇仅列出)

2.命名空间

2.0命名空间引入

在c/c++中,变量,函数以及类都是大量存在的,其名称将都存在于全局作用域中,可能导致很多命名冲突。命名空间的引入目的便是对标识符的名称进行本地化,从而避免命名冲突或名字污染。namespace关键字的出现便是针对这类问题的。

例如c中出现问题

#include<stdio.h>
#include<stdlib.h>
int rand=10;
//c语言无法解决类似这样的命名冲突问题,所以c++提出了namespace来解决
int main()
{
printf("&d\n",rand);
return 0;

}
//编译后报错:error c2365:"rand":重定义:以前的定义是“函数”

2.1命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间大名字,然后接一对{}即可,{}中即为命名空间的成员。

//1.正常的命名空间的第一
namespace gjy
{
//命名空间中可以定义变量、函数、类型
int rand =10'
int Add(int left,int right)
 {
  return left +right;
 }
struct Node
   {
    struct Node*next;
    int val;
  }

}

//2.命名空间可以嵌套
namespace N1
{
int a;
int b;
int Add(int left,int right)
 {
 return left+right;
 }
 namespace N2
 {
int c;
int d;
int Sub(int left,int right)
  {
  return left-right;
  }
 }
}
// 3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。(一个工程中的test.h和上面test.cpp中两个N1会被合并成一个)
 





注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中。

2.2命名空间使用

使用命名空间的方式一般有两种:

1.使用using指令指定要使用的命名空间中的成员(一般情况下使用此种较多):

#include <iostream>

// 使用std命名空间中的cout和endl
using std::cout;
using std::endl;

int main() {
    cout << "Hello World!" << endl;
    return 0;
}
 

上面的代码中,使用了using指令指定了要使用std命名空间中的coutendl,这样在代码中就可以直接使用coutendl,而不必在前面加上std::

2.使用using namespace指令把整个命名空间引入当前作用域:

#include <iostream>

// 把std命名空间引入当前作用域
using namespace std;

int main() {
    cout << "Hello World!" << endl;
    return 0;
}
 

面的代码中,使用了using namespace指令把整个std命名空间引入了当前作用域,这样在代码中就可以直接使用std命名空间中的所有成员,而不必再加上std::

需要注意的是,使用using namespace指令引入整个命名空间可能会导致名称冲突,因此建议只在全局作用域和局部作用域中使用。在命名空间内部不应使用using namespace指令

3.加命名空间名称及作用域限定符

int main()
{
printf("&d\n",N::a);
return 0;

}

注:

在C++编程中,通常将程序分成头文件和源文件两部分。头文件通常包含函数声明和类定义等信息,而源文件包含函数实现等具体代码。头文件是编译单元的一部分,可以被多个源文件包含。

在头文件中使用using namespace std语句会将std命名空间中的所有名称引入当前作用域,这意味着在引入头文件的源文件中,会出现与其他命名空间中的名称冲突的可能性,这可能导致编译错误。

因此,一般不建议在头文件中使用using namespace std语句,而是在源文件(谨慎使用,避免出现命名冲突)中使用或者直接使用std命名空间限定符。这样可以避免命名冲突,并保证源文件间的独立性和可重用性。

std命名空间的使用惯例

3.c++输入&输出

#include<iostream>
//std是c++标准库的命名空间名,c++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
cout<<"Hello World"<<endl;
return 0;
}

说明:

5.实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等1知识。io流用法及原理后续

注:

#include<iostream>
using namespace std;
int main()
{
int a;
double b;
char c
//可以自动识别变量的类型
cin>>a;
cin>>b>>c;
cout<<a<<endl;
cout<<b<<" "<<c<<endl;
return 0;

}

关于cout,cin还有很多复杂的用法,比如控制浮点数输出精度,控制输出进制格式等。c++兼容c,可用c中方式处理。

4.缺省参数

4.1缺省参数概念

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参就采用该形参的缺省值,否则使用指定的实参。

4.2缺省参数分类

·全缺省参数

void Func(int a=10,int b=20,int c=30)
{
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl;

}

·半缺省参数

void Func(int a,int b=20,int c=30)
{
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl;

}

注意:

1.半缺省参数必须从右往左依次来给,不能间隔给

C++ 的半缺省参数必须从右向左依次设置,不能间隔设置原因是为了避免语义不明确的问题。如果允许间隔设置半缺省参数,那么调用函数时就可能会出现歧义,导致编译出错或者运行时发生错误。

例如,在下面的代码中,如果允许间隔设置半缺省参数,那么调用函数 `f` 的语义将不明确:

void f(int a, int b=0, int c, int d=0);
f(1, 2, 3); // 这里 b 的值应该是 2 还是 0?
 

在上面的代码中,函数 `f` 定义了半缺省参数 `b` 和 `d`,但是参数 `c` 没有设置默认值。当调用函数 `f(1, 2, 3)` 时,由于半缺省参数必须从右向左依次设置,因此参数 `c` 可以被正确赋值为 3,但是参数 `b` 的值应该是 2 还是 0 就不确定了,这会导致调用 `f` 函数时语义不明确。

因此,C++ 规定半缺省参数必须从右向左依次设置,在调用函数时就可以明确每个参数的值,避免语义不明确的问题。

2.缺省参数不能在函数声明和定义中同时出现(同时出现若两个位置提供的值不同,那编译器就无法确定到底用哪个缺省值)

3.缺省值必须是常量或者全局变量

4.c语言不支持(编译器不支持)

5.函数重载

引入:在不同语境中,一个词可能会有不同的意思,具体对应具体环境,通过上下文来判断该词真实含义,即该词被重载了。

5.1函数重载概念

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型顺序)不同,常用来处理实现功能类似数据类型不同的问题

#include<iostream>
using namespace std;
//1.参数类型不同
 int Add(int left,int right)
{
cout<<"int Add(int left,int right)"<<endl'
return left+right;
}
double Add(double left,double right)
{
cout <<"double Add(double left,double right)"<<endl'
return left +right;
}

//2.参数个数不同
void f()
{
cout<<"f()"<<endl;
}
void f(int a)
{
cout<<"f(int a)"<<endl;
}
//3.参数类型顺序不同

void f(int a,char b)
{
cout<<"f(int a,char b)"<<endl;
}
void f(char b,int a)
{
cout<<"f(char b,int a)"<<endl;
}

int main()
{
Add(10,20);
Add(10.1,20.2);
f();
f(10);
f(10,'a');
f('a',10);
return 0;

}

5.2c++支持函数重载的原理--名字修饰(name Mangling)

一个问题:为什么c++支持函数重载,而c语言不支持函数重载呢?

答:简而言之,就是在程序运行起来的链接阶段编译器对函数的查找规则,在这里每个编译器都有自己的函数名修饰规则(如在linux下,采用g++编译完成后,函数名字的修饰发生改变,编译器将函数参数类型信息添加到修改后的名字中,如Add(1,2)查找<_Z3Addii>);对于c的话,同名函数无法区分,而c++是通过函数修饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载。

更多知识:

在c,c++中,一个程序要运行起来,需要进过以下几个阶段:预处理,编译,汇编,链接

3.那么链接时,面对Add函数,链接器会使用哪个名字去找呢?每个编译器有自己的函数名修饰规则。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值