C++:入门基础语法

发布于:2025-09-06 ⋅ 阅读:(20) ⋅ 点赞:(0)

C++:入门基础语法

1.命名空间
2.C++的输入输出
3.缺省参数
4.函数重载
5.引用
6.inline
7.nullptr

1.命名空间

在C/C++中,变量、函数和类的名称都存在于全局作用域中,易导致命名冲突或名字污染。例如:

#include<stdio.h>
#include<stdlib.h>
int rand=10;

int main()
{
    printf("%d\n",rand);//报错
    return 0;
}

上述代码中,在stdlib.h文件中rand为求随机数的函数,与全局变量rand冲突了。

namespace的定义和使用

为解决命名冲突,C++引入了关键字namespace。

  • 定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。
namespace name1
{
    int a=10; //变量
    int Add(int x,int y) //函数
    {
        return x+y;
    }
    struct Student //类型
    {
        char id[20];
        int score;
    };
}  //不用加分号
  • namespace只能定义在全局,可以嵌套定义。
namespace name1
{
    int a=1;
    int Add(int x,int y) 
    {
        return x+y;
    }
    namespace name2
    {
        char ch;
        double d;
    }
}
  • 使用命名空间中的成员要用到运算符 :: ,即 命名空间的名字 :: 成员 ,若是要使用嵌套命名空间中的成员,如要使用上面代码name2的变量d,则name1 :: name2 :: d。
  • namespace本质是定义出一个域,这个域跟全局域各自独立,不同的域可以定义同名变量。
#include<stdio.h>
#include<stdlib.h>
namespace name1
{
    int rand=10;
        int Add(int x,int y) 
    {
        return x+y;
    }
    struct Student 
    {
        char id[20];
        int score;
    };
}
int main()
{
    printf("%d\n",name1::rand);//这样就能打印出变量rand的值
    return 0;
}
  • 项目工程中多文件中定义的同名namespace会认为是一个namespace,不会冲突。
  • C++标准库都放在一个叫std(standard)的命名空间中。
  • 用using展开命名空间的成员或整个命名空间,项目中经常访问的不存在冲突的成员推荐这种方式,但对于展开整个命名空间,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。
#include<stdio.h>
namespace name1
{
   int a=1;
   int b=2;
}
int main()
{
    printf("%d\n",a);//报错
    return 0;
}
#include<stdio.h>
namespace name1
{
   int a=1;
   int b=2;
}
using name1::a;//展开命名空间的某个成员
int main()
{
    printf("%d\n",a);//不报错
    printf("%d\n",b);//报错
    return 0;
}
#include<stdio.h>
namespace name1
{
   int a=1;
   int b=2;
}
using namespace name1;//展开整个命名空间
int main()
{
    printf("%d\n",a);//不报错
    printf("%d\n",b);//不报错
    return 0;
}

2.C++的输入输出

  1. 是标准的输入、输出流库,定义了标准的输入、输出对象。
  2. std::cin 是 istream 类的对象,它主要面向窄字符的标准输入流。
  3. std::cout 是 istream 类的对象,它主要面向窄字符的标准输出流。
  4. std::endl 是一个函数,流插入输出时,相当于插入一个换行字符并刷新缓冲区。
  5. 流插入运算符<< ,流提取运算符>> 。
  6. C++的输入输出可以自动识别变量类型。
  7. cout/cin/endl等都属于C++标准库,要通过命名空间std来使用。
#include<iostream> //<iostream>间接包含了<stdio.h>
using namespace std; //一般⽇常练习中我们可以using namespace std,
int main()           //实际项⽬开发中不建议
{
    int a=0;
    double b=0.1;
    char c='x';
    printf("输入a:");
    cin>>a;
    cout<<"输出abc"<<"\n";
    cout<<a<<" "<<b<<" "<<c<<endl;
    std::cout<<a<<" "<<b<<" "<<c<<std::endl;//不展开整个命名空间std
    return 0;
}

在这里插入图片描述

3.缺省参数

  1. 调用函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
  2. 全缺省:全部形参给缺省值。 半缺省:部分形参给缺省值。
  3. 缺省参数必须从右往左依次缺省。
  4. 调用带缺省参数的函数,必须从左往右依次给实参。
  5. 函数声明和定义分离时,函数声明给缺省值。
#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()
{
    cout<<"Func1"<<endl;
    Func1();
    Func1(1,2,3);
    cout<<"Func2"<<endl;
    Func2(11);
    Func2(11,12,13);
    return 0;
}

在这里插入图片描述

4.函数重载

C++支持在同一作用域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者类型不同。这样C++函数调用就表现出了多态行为,使用更灵活。

  1. 参数类型不同
#include<iostream>
using namespace std;
int Add(int x,int y)
{
    return x+y;
}
double Add(double x,double y)
{
    return x+y;
}
int main()
{
    cout<<"Add(1,2)= "<<Add(1,2)<<endl;
    cout<<"Add(1.7,2.1)= "<<Add(1.7,2.1)<<endl;
    return 0;
}

在这里插入图片描述

  1. 参数个数不同
#include<iostream>
using namespace std;
void f()
{
    cout<<"f()"<<endl;
}
void f(int a)
{
    cout<<"f(int a)"<<endl;
}
int main()
{
    f();
    f(10);
    return 0;
}

在这里插入图片描述

  1. 参数类型顺序不同
#include<iostream>
using namespace std;
void f(int a,char b)
{
    cout<<"f(int a,char b)"<<endl;
}
void f(char a,int b)
{
    cout<<"f(char a,int b)"<<endl;
}
int main()
{
    f(10,'x');
    f('x',10);
    return 0;
}

在这里插入图片描述

  1. 返回值不同不能作为重载条件,因为调用时无法区分。
  2. 下面2个函数构成重载,但调用f()时存在歧义,会报错。
void f()
{
    cout<<"f()"<<endl;
}
void f(int a=10)//缺省参数
{
    cout<<"f(int a)"<<endl;
}

5.引用

引用不是新定义一个变量,而是给已存在变量取了一个别名,它和它引用的变量共用同一块内存空间。

类型& 引用别名=引用对象

#include<iostream>
using namespace std;
int main()
{
    int a=10;
    int& b=a;//给a取别名
    int& c=a;
    int& d=b;//给别名取别名
    cout<<&a<<endl;
    cout<<&b<<endl;
    cout<<&c<<endl;
    cout<<&d<<endl;
    return 0;
}

在这里插入图片描述
可以看到,引用确实没有开辟新空间。

在这里插入图片描述

引用的特性
  1. 引用在定义时必须初始化。
  2. 一个变量可以有多个引用。
  3. 引用一旦引用一个实体,再不能引用其他实体。
引用的使用
  • 引用在实践中主要是于引用传参引用做返回值中减少拷贝提高效率 和 改变引用对象时同时改变被引用对象。
  • 引用传参跟指针传参功能是类似的,引用传参相对更方便⼀些。
#include<iostream>
using namespace std;
void Swap(int& ra,int& rb)
{
    int t=ra;
    ra=rb;
    rb=t;
}
int main()
{
    int x=0,y=0;
    cin>>x>>y;
    Swap(x,y);
    cout<<x<<" "<<y<<endl;
    return 0;
}

在这里插入图片描述

const引用
  1. 可以引用一个const对象,但是必须用const引用。const引用也可以引用普通对象,对象的访问权限在引用过程中可以缩小,但是不能放大
const int a=10;
int& ra=a;//错误,对a的访问权限放大
const int& ra=a;//正确

int b=20;
const int& rb=b;//正确,这里的引用是对b访问权限的缩小
  1. 编译器需要一个空间暂存表达式的求值结果,而临时创建的一个未命名的对象,C++中称之为临时对象。临时对象具有常性
int a=10;
const int& ra=30;//常数取别名要加const
int& rb=a*3;//错误,a*3的结果放在临时对象中
const int& rb=a*3;//正确

double d=12.34;
int& rd=d;//错误,强转结果会放在临时对象中
const int& rd=d;//正确
指针和引用的关系

C++中指针和引用在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。

  1. 引用是一个变量的取别名,不开空间;指针是存储一个变量地址,要开空间。
  2. 引用在定义时必须初始化,指针不必须。
  3. 引用只能引用一个对象,指针可以不断改变指向对象。
  4. 引用可以直接访问指向对象,指针需要解引用后才能。
  5. sizeof(int&)=sizeof(int) ;sizeof(int*)=4或8 。
  6. 指针易出现空指针和野指针的问题,引用很少出现,较安全。

6.inline

用inline修饰的函数叫做内联函数,编译时C++编译器会在调用的地方展开内联函数,这样调用内联函数就需要建立栈帧了,就可以提高效率。

inline对于编译器而言只是一个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适用于频繁调用的短小函数,对于递归函数、代码相对多一些的函数,加上inline也会被编译器忽略。

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

7.nullptr

NULL实际是一个宏,在C中为((void*)0),在C++中为0。

nullptr是关键字,也是字面常量,nullptr只能被隐式地转为指针类型。以后C++中用nullptr代替NULL。

#include<iostream>
using namespace std;
void f(int x)
{
    cout<<"f()"<<endl;
}
void f(int* p)
{
    cout<<"f(int* p)"<<endl;
}
int main()
{
    f(NULL);
    return 0;
}

在这里插入图片描述

#include<iostream>
using namespace std;
void f(int x)
{
    cout<<"f()"<<endl;
}
void f(int* p)
{
    cout<<"f(int* p)"<<endl;
}
int main()
{
    f((int*)NULL);//将0强转为int*类型的指针
    return 0;
}

在这里插入图片描述

#include<iostream>
using namespace std;
void f(int x)
{
    cout<<"f()"<<endl;
}
void f(int* p)
{
    cout<<"f(int* p)"<<endl;
}
int main()
{
    f(nullptr);
    return 0;
}

在这里插入图片描述

拙作一篇,望诸位同道不吝斧正。


网站公告

今日签到

点亮在社区的每一天
去签到