【C++入门】命名空间域

目录

命名空间-namespace

写命名空间的原因:

命名空间的使用:

命名空间建立:

如何使用命名空间域中的变量:

域作用限定符:::

命名空间使用规则:

命名空间可以嵌套使用:

实际应用:

展开命名空间:

展开std命名空间:

指定展开命名空间域:

变量搜索顺序:



C++兼容C语言的大部分语法,为弥补C语言的不足与实现面向对象和泛型出现了C++

回顾经典,对比C语言和C++

#include<stdio.h>
int main()
{
        printf("hello,world\n");
}

相同结果我们如何用C++的功能实现呢

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

为什么我们要多写一个using namespace std,这就涉及到我们的第一个知识点:命名空间域

命名空间-namespace

写命名空间的原因:

先看一个例子:

#include<stdio.h>
int rand = 0;//初始化一个全局变量rand
int main()
{
        printf("hello,world\n");
        printf("%d\n",rand);
        return 0;
}

注意,此时编译器正常运行

#include<stdio.h>
#include<stdlib.h>//新增头文件
int rand = 0;//初始化一个全局变量rand
int main()
{
        printf("hello,world\n");
        printf("%d\n",rand);
        return 0;
}


报错情况:新增头文件#include<stdlib.h>后报错为:rand重定义;以前的定义是函数

报错原因:命名冲突;与头文件stdlib.h库中函数冲突

命名冲突常见场景:

1.命名与库函数名冲突

2.所写函数名相互冲突

在c语言中会出现上列情况产生命名冲突,C++为了解决这一问题,设置了命名空间这一规则

命名空间的使用:

命名空间建立:

namespace name  //name:命名空间域名字

namespace A//设置一个命名空间(相当于隔离空间)
{
    int rand = 0;//依旧是全局变量,只是放入了命名空间域内
}//注意,这里不用加分号,与结构体和类进行区别
int main()
{
    printf("helloo world\n");
    printf("%d\n",rand);//注意这里的rand不一样,详看下解
    return 0;
}

此时不再报错,不产生命名冲突错误

但是,此时rand默认访问的是全局的rand,不是命名空间中的rand

会产生如下报错:

此时printf("%d\n",rand)中打印的是<stdlib.h>库中的函数,函数名代表函数指针

所以

namespace A
{
    int rand = 0;
}
int main()
{
    printf("helloo world\n");
    printf("%p\n",rand);//用%p,打印函数指针
    return 0;
}

如何使用命名空间域中的变量:

域作用限定符:::

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

命名空间使用规则:

命名空间可以嵌套使用:

  • 注意,使用的时候也要按层级寻找
namespace A
{
    int rand = 1;
    namespace a
    {
        int rand =2;
    }
}
int main()
{
    printf("%d\n",A::rand);
    printf("%d\n",A::a::rand);
}

实际应用:

为方便理解,暂时先用C语言的语法来写一个栈,让我们更加了解命名空间域使用中的作用吧

//Stack.h
#pragma once
#include<stdio.h>
namespace A//用同一个命名空间
{
        typedef struct Stack//建立一个栈
        {
                int top;
                int* a;
                int capacity;
        }ST;
        void StackInit(ST* ps);
        void StackPush(ST* ps, int x);
}
//Stack.cpp
#include"Stack.h"
namespace A//用同一个命名空间
{
        void StackInit(ST* ps)//栈的初始化
        {
                ps->top = 0;
                ps->capacity = 0;
                ps->a = NULL;
        }
        void StackPush(ST* ps, int x)
        {
                //......
        }
}
//Text.cpp
#include "Stack.h"
#include<stdio.h>
int main()
{
        A::ST s;//声明一个结构体变量,要加上命名空间域访问
        A::StackInit(&s);
        A::StackInit(&s,1);
        A::StackInit(&s,2);
        A::StackInit(&s,3);
        A::StackInit(&s,4);
        return 0;
}
  • 注意:两个相同名字的命名空间会默认为同一个命名空间(多个文件或同一个文件也相同)

展开命名空间:

但此时,使用下来会觉得使用命名空间域会过于麻烦,于是展开命名空间即可避免代码的累赘。

using namespace name//默认指定使用此命名空间,展开此命名空间

//Text.cpp
#include "Stack.h"
#include<stdio.h>
using namespace A//展开命名空间A
int main()
{
        ST s;//声明一个结构体变量,要加上命名空间域访问
        StackInit(&s);
        StackInit(&s,1);
        StackInit(&s,2);
        StackInit(&s,3);
        StackInit(&s,4);//可以省略访问前缀
        return 0;
}

注意:这里与“头文件的展开”不一样!

  • 头文件展开指的是在程序运行预处理阶段,把头文件的代码进行拷贝

  • 展开命名空间可以理解为把围起来的围墙拆掉,变量除了在全局中搜索也默认会去到命名空间中去搜索

展开std命名空间:

std是C++官方库定义的命名空间

#include <iostream>
using namespace std;//把C++官方库的命名空间展开

注意:在日常练习代码中为了方便可以直接展开,但是在做工程项目时,请不要随意展开。

指定展开命名空间域:

#include <iostream>
int main()
{
    int a = 10;
    int b = 20;
    std::cout<<a<<std::endl
    std::cout<<b<<std::endl
}

当我们频繁使用C++库中的函数时,每次都指定命名空间非常 不方便,如果使用using namespace std全部展开的话就会不安全

using std::cout;//展开我需要用到的函数
using std::endl;
#include <iostream>
int main()
{
    int a = 10;
    int b = 20;
    cout<<a<<endl
    cout<<b<<endl
}

变量搜索顺序:

#include<stdio.h>
using namespace A;
using namespace std;
int main()
{
    //....
}

1.全局变量中搜索

2.A空间域中搜索

3.std空间域中搜索

4.都没找到——>报错

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值