C++入门基础(一)
感谢各位大佬对我的支持,如果我的文章对你有用,欢迎点击以下链接
🐒🐒🐒 个人主页
🥸🥸🥸 C语言
🐿️🐿️🐿️ C语言例题
🐣🐣🐣 python
🐓🐓🐓 数据结构C语言
🐔🐔🐔 C++
🐿️🐿️🐿️ 文章链接目录
C++关键字
C++总共有63个关键字,相对于C语言的32个关键字增加了接近一倍,并且C语言的关键字在C++也是可以用的
命名空间
在C/C++中,变量、函数和类都是经常出现的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。
使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
命名冲突例子
#include<stdio.h>
int rand = 1;
int main()
{
printf("%d", rand);
return 0;
}
这个代码中我们定义了一个整形rand,然后输出rand的值
运行结果输出也是1
但是当我们再增加一个头文件#include<stdlib.h>后就不一样了
这就是C语言中的命名冲突,因为包含了头文件#include<stdlib.h>后会展开,而rand函数就在这个头文件里,rand函数是一个全局函数,而代码中又定义了一个全局变量,所以在运行时会冲突
域的概念理解
不同的域是否可以定义同一个全局变量,我们来看看下面的代码
#include<stdio.h>
int x=1;
int main()
{
int x = 0;
printf("%d", x);
return 0;
}
不同的域是可以定义同一个变量的,但同一个域不可以定义两个相同的变量
因为C语言有就近原则,x=0在局部域,x=1在全局域,所以当运行程序的时候,编译器会优先查找最近的x,如果局部域没有找到x,那么就会去全局域找
如果全局域和局部域都定义了x,而我们只想打印全局域中x的值,那么有以下方法
方法一:定义一个函数,返回全局域x的值
方法二 域作用限定符
注意 ::x中的::左边是空的默认为全局域
有了域作用限定符后我们需要知道哪些可以成为域
C++有这几种域:全局域 局部域 命名空间域 类域
总结:命名冲突的原因就是程序员命名的函数或者变量与库中的函数和变量名称相同导致的(这里的库包括C语言自带的库和别人写的库),C语言中的域坚持就近原则,为了避免命名冲突,有了域作用限定符
命名空间定义
定义命名空间,需要使用到namespace(名字空间)关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
例子1
#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
namespace jack1
{
int x = 0;
}
namespace jack2
{
int x = 1;
}
int main()
{
printf("%d ", jack1::x);
printf("%d ", jack2::x);
return 0;
}
这里的两个x都是全局变量,只不过被封装起来放进不同的命名空间域中
命名空间域和全局域与局部域不同,全局域和局部域即会影响生命周期又会影响访问(全局域和局部域的生命周期不一样,并且访问的时候要指定),而命名空间域只是影响访问,不会影响生命周期
编译器有这样一个搜索原则
先搜索当前局部域,再搜索全局域,如果指定搜索了哪块域,就直接去指定域搜索
下面就是没有指定域,导致编译器找不到
例子2
两个命名空间的名字是可以一样的,只不过最后运行的时候会将名字一样的合并
namespace jack1
{
int x = 0;
}
namespace jack1
{
int y = 1;
}
int main()
{
printf("%d ", jack1::x);
printf("%d ", jack1::y);
return 0;
}
但是如果两个名字相同的命名空间,内部的变量名相同就会报错(因为最后会合并,导致同一个命名空间中有两个相同的变量)
例子3
命名空间里面可以定义函数和结构体…
需要注意的是结构体有点特殊,他并不是jack1::struct Node phead,而是struct jack1::Node phead
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
namespace jack1
{
int rand = 0;
int x = 1;
int Add(int a, int b)
{
return a + b;
}
struct Node
{
struct Node* next;
int val;
}nd;
}
int main()
{
printf("%d ", jack1::rand);
printf("%d ", jack1::x);
printf("%d ", jack1::Add(1,2));
struct jack1::Node phead;
phead.val = 4;
phead. next = NULL;
printf("%d ", phead.val);
return 0;
}
例子4
在写代码我们经常创建多个文件,这些文件中,也常常有命名冲突的问题
//Queue.h头文件
#pragma once
struct Queue
{
struct Node* head;
struct Node* tail;
int size;
};
struct Node
{
int val;
struct Node* next;
};
//List.h头文件
#pragma once
struct Node
{
int val;
struct Node* next;
struct Node* prev;
};
//test.cpp文件
#include<iostream>
using namespace std;
#include<stdio.h>
#include<stdlib.h>
#include"Queue.h"
#include"List.h"
int main()
{
return 0;
}
由于List.h和Queue.h两个头文件中有冲突的结构体定义,导致最后会报错
这个时候我们就需要定义命名空间
//Queue.h头文件
#pragma once
namespace jack1
{
struct Queue
{
struct Node* head;
struct Node* tail;
int size;
};
struct Node
{
int val;
struct Node* next;
};
}
//List.h头文件
#pragma once
namespace jack2
{
struct Node
{
int val;
struct Node* next;
struct Node* prev;
};
}
例子5
不同的文件也可以定义同一个命名空间,只要内部不冲突就行,在我们日常练习时,频繁展开命名空间会非常麻烦
int main()
{
struct jack2::Node node1;
struct jack2::Node node2;
struct jack2::Node node3;
return 0;
}
名次想要定义一个结构体时都要用一次域作用限定符,为了方便我们可以直接展开命名空间using namespace jack2,当展开后不需要域作用限定符就可以直接用里面的东西,也就是一次搞定
#include<iostream>
#include"Queue.h"
#include"List.h"
using namespace std;
using namespace jack2;
int main()
{
struct Node node1;
struct Node node2;
struct Node node3;
return 0;
}
代码中有一句using namespace std,std是C++所有库的命名空间,我们用一个例子来讲解
#include是c++的一个头文件,当我们包含了头文件后,按理说头文件里的东西是可以直接用的,但是运行时却报错了
当加上using namespace std后,程序就可以正常运行
如果我们不包含头文件,而只展开命名空间也是报了相同的错误
当我们单独用域作用限定符后,程序又可以正常运行了
根据上面的结果我们可以得出一个结论:
包含头文件后,头文件里面的东西被命名空间std给封装起来了,所以如果只包含了头文件,没有展开命名空间是用不了里面的东西
只展开命名空间,没有包含头文件,由于没有头文件,导致库里的东西我们无法使用
注意:命名空间展开后就相当于一个全局变量,如果存在一个局部变量和命名空间中变量名称相同,会优先使用局部变量
例子6
命名空间是可以嵌套的
#include<iostream>
//using namespace std;
using std::cout;
using std::endl;
namespace jack1
{
namespace jack2
{
namespace jack3
{
void printf3()
{
cout << "jack3" << endl;
}
}
}
namespace jack4
{
void printf4()
{
cout << "jack4" << endl;
}
}
}
int main()
{
jack1::jack2::jack3::printf3();
jack1::jack4::printf4();
return 0;
}
例子7
输入和输出在代码中是非常常见的操作,日常练习中我们可以用using namespace std去展开命名空间,但是在正式的项目中,如果直接展开命名空间,会导致命名冲突,为了减少这种情况的发生,C++可以选择只展开命名空间中常用的几个
#include<iostream>
//using namespace std;
using std::cout;
using std::endl;
int main()
{
cout << "hello world" << endl;
return 0;
}
C++输出与输入
输出
#include<iostream>
using std::cout;
using std::endl;
int main()
{
int i = 9;
i=i << 1;
cout <<"hello world " << i<<endl ;
return 0;
}
cout的意思为console out(控制台输出)就是将数据输出进控制台,而cout右边的<<为流插入符号,意思就是数据像流一样流入,流插入符号与C语言的左移操作符相同,并且C++中依然可以使用左移操作符,
C语言的输出为printf函数,根据上面的代码我们可以看到,C++支持连续输出,并且有着自动识别类型的功能(C语言在输出的时候,需要表明i的具体类型,而C++不需要)
上图中并没有’\n’,但是输出的结果却意外的换行了,其实是因为有endl=endline(结束线),我们可以把他等价于’\n’,所以endl可以换成’\n’
输入
cin>>表示输入,>>在C语言中为右移操作符,在C++的输入中表示流提取,意思就是将数据流入,然后提取出来
和输出相同,输入可以连续的流提取
在C语言中有时会涉及到精度问题,比如一个double类型的变量,要求精确到小数点后一位,C语言是用%.x来表示精确到小数点的第x位
C++也是可以的,只不过有点麻烦,但是C++是兼容C语言的,所有我们遇到这种情况可以直接用C语言的方法去解决
这里解释一下,图中没有包含#include<stdio.h>头文件,但是却可以用printf函数,是因为不同的平台的库实现是不一样的,可能VS中的#include < iostream>里面间接包含了printf函数,所以可以正常运行,但是在其他平台上就不一定了
原文地址:https://blog.csdn.net/2401_86956109/article/details/143446367
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!