为什么会衍生出C++?
C语言是结构化和模块化的语言,适合处理较小规模的程序。对于复杂的问题,规模较大的程序,需要高度的抽象和建模时,C语言则不合适。为了解决软件危机,20世纪80年代,计算机界提出了00P(object oriented programming: 面向对象)思想,支持面向对象的程序设计语言应运而生。
1982年,Biarne Stroustrup博士在C语言的基础上引入并扩充了面向对象的概念,发明了-种新的程序语言。为了表达该语言与C语言的渊源关系,命名为C++。因此: C++是基于C语言而产生的,它既可以进行C语言的过程化程序设计(这也是C++兼容C语言的原因),又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计。
C++祖师爷的介绍
本贾尼·斯特劳斯特卢普(Bjarne Stroustrup,1950年6月11日-),丹麦人,计算机科学家,在德克萨斯A&M大学担任计算机科学的主席教授。他最著名的贡献就是开发了C++程序设计语言。
1982年,美国AT&T公司贝尔实验室的本贾尼博士在C语言的基础上引入并扩充了面向对象的概念,发明了—种新的程序语言。为了表达该语言与C语言的渊源关系,它被命名为C++。而本贾尼博士被尊称为C++语言之父。
#include<iostream>
using namespace std;
int main()
{
cout << "hello world" << endl;
return 0;
}
我们先不用看懂全部代码 比如using namespace std;cout <<endl是什么意思?
咱们不急,先听我娓娓道来,我会在下面解释到的,解开困惑的
第一个知识 命名空间 namespace
当我们用C语言运行这段代码会出现报错
#include<stdio.h>
#include<stdlib.h>
int rand = 10;
int main()
{
printf("%d ", rand);
return 0;
}
为什么呢?因为在头文件<stdlib.h>库里面就包含了rand函数,我们再次使用rand定义了全局变量,因此会出现命名冲突,但C语言无法解决这种命名冲突问题,所以C++祖师爷为了解决命名冲突问题提出了namespace来解决。
命名空间一般用namespace+自己定义名字
比如我使用的是namespace as (as就是命名空间的名字)
用%p访问rand是因为rand是头文件里面的rand函数 编译器会推荐用%p访问
#include<stdio.h>
#include<stdlib.h>
namespace as
{
int rand = 10;
}
int main()
{
printf("%p", rand);
return 0;
}
那怎么访问命名空间里面的rand的值呢?
使用 : :域作用限定符来访问
#include<stdio.h>
#include<stdlib.h>
namespace as
{
int rand = 10;
}
int main()
{
printf("%p", rand);
printf("%d", as::rand);
return 0;
}
命名空间相当于用围墙把rand"保护了起来"且留了一个入口,入口上面有牌匾"里面有恶犬 生人勿近 会咬人",只能有熟人进去喂"它(rand)"食物和与它互动。
#include<stdio.h>
#include<stdlib.h>
namespace as
{
int rand = 10;
struct Node
{
struct Node* next;
int val;
};
int Add(int left, int right)
{
return left + right;
}
}
int main()
{
printf("%p\n", rand);
printf("%d\n", as::rand);
printf("%d\n", as::Add(2, 3));
struct as::Node node;
return 0;
}
假设同一个命名空间有相同的变量会怎么样呢?会不会自己和自己打一架?
实际上命名空间是可以嵌套的
#include<stdio.h>
#include<stdlib.h>
namespace as
{
int rand = 10;
namespace as1
{
int rand = 30;
}
namespace as2
{
int rand = 20;
}
struct Node
{
struct Node* next;
int val;
};
int Add(int left, int right)
{
return left + right;
}
}
int main()
{
printf("%p\n", rand);
printf("%d\n", as::rand);
printf("%d\n", as::as1::rand);
printf("%d\n", as::as2::rand);
printf("%d\n", as::Add(2, 3));
struct as::Node node;
return 0;
}
比如你在公司需要写项目比如栈,为了防止与同事写的冲突就可以运用命名空间
Stack.h
#pragma once
#include<stdio.h>
#include<stdlib.h>
namespace fk
{
typedef struct Stack
{
int* a;
int sz;
int capacity;
}ST;
void STInit(ST* ps);
void STPush(ST* ps,int x);
}
test.cpp
#include"Stack.h"
namespace fk
{
void STInit(ST* ps)
{
ps->a = NULL;
ps->capacity = ps->sz = 0;
}
void STPush(ST* ps, int x)
{
//....
}
}
int main()
{
fk::ST st;
fk::STInit(&st);
fk::STPush(&st, 1);
fk::STPush(&st, 2);
fk::STPush(&st, 3);
}
那么它们运行起来不会冲突吗?
test.cpp
#include"Stack.h"
namespace fk
{
void STInit(ST* ps)
{
ps->a = NULL;
ps->capacity = ps->sz = 0;
}
void STPush(ST* ps, int x)
{
//....
}
}
using namespace fk;
int main()
{
ST st;
STInit(&st);
STPush(&st, 1);
STPush(&st, 2);
STPush(&st, 3);
}
只需要在test.cpp写上一句 using namespace fk;即可
那么using namespace std;是什么意思呢?
std是C++官网标准库的命名空间,当我们展开std时,库里面的函数就可以使用了
那么std库里面的函数能随意展开吗?答案是否定的
在我们平常练习C++时可以展开自己定义的命名空间和std库的命名空间,但在实际工程上是不能随意展开的,容易出现冲突。
#include<iostream>是C++的头文件 类似于C语言的#include<stdio.h>
i=In O=Out 输入与输出 <<是流插入
C++为了有自己的换行符有了endl endl=end line.
#include<iostream>
int main()
{
//<< 是流插入
int a = 10;
std::cout << a << "\n";
int b = 20;
double e = 13.14;
// << 可以自动识别数据类型
int c = 545;
std::cout << b<< "\n";
std::cout << e << "\n";
std::cout << c << std::endl;
return 0;
}
在我们不展开C++的库函数时,只能用域作用限定符来cout和endl,例如std::cout std::endl
但每次指定命名空间不方便,又害怕C++库里面函数全部暴露 又有风险冲突?
那么怎么办呢?我们可以指定展开命名空间 例如下图
#include<iostream>
using std::cout;
using std::endl;
int main()
{
//<< 是流插入
int a = 10;
cout << a << "\n";
int b = 20;
double e = 13.14;
// << 可以自动识别数据类型
int c = 545;
cout << b<< "\n";
cout << e << "\n";
cout << c << endl;
return 0;
}
cout中的C=console(控制台) cin是流提取 相当于C语言的scanf
#include<iostream>
using std::cout;
using std::endl;
int main()
{
int a = 20;
int b = 30;
cout << a << endl << b << endl;
std::cin >> a >> b;
return 0;
}
如果要控制数字精度怎么办呢?使用C,因为C++兼容C
#include<iostream>
using std::cout;
using std::endl;
int main()
{
int a = 20;
int b = 30;
double c = 13.1424;
cout << a << endl << b << endl;
//控制精度用C 因为C++兼容C
printf("%.1lf\n", c);
return 0;
}