Re:从零开始的C++世界——(一)入门基础

07-14 1390阅读

文章目录

  • C++发展历史
  • 1.命名空间
    • 1.1 namespace的价值
    • 1.2 namespace的定义
    • 1.3 命名空间使⽤
    • 2.C++输⼊&输出
    • 3.缺省参数
      • 3.1 缺省参数的概念
      • 3.2 缺省参数的分类
      • 4.函数重载
      • 5.引⽤
        • 5.1引⽤的概念和定义
        • 5.2 引⽤的特性
        • 5.3 const引⽤
        • 5.4 使用场景
        • 5.5 指针和引⽤的关系
        • 6.内联函数
          • 6.1内联函数概念
          • 6.2 内敛函数的特性
          • 7.指针空值nullptr
            • 7.1 C++98中的指针空值
            • 7.2 C++11中的指针空值
            • 8 **总结**

              C++发展历史

              C++的起源可以追溯到1979年,当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普,这个翻译的名字不同的地⽅可能有差异)在⻉尔实验室从事计算机科学和软件⼯程的研究⼯作。⾯对项⽬中复杂的软件开发任务,特别是模拟和操作系统的开发⼯作,他感受到了现有语⾔(如C语⾔)在表达能⼒、可维护性和可扩展性⽅⾯的不⾜。

              1983年,Bjarne Stroustrup在C语⾔的基础上添加了⾯向对象编程的特性,设计出了C++语⾔的雏形,此时的C++已经有了类、封装、继承等核⼼概念,为后来的⾯向对象编程奠定了基础。这⼀年该语⾔被正式命名为C++。

              Re:从零开始的C++世界——(一)入门基础

              语言的发展是一个初步递进、由浅入深的过程。

              Re:从零开始的C++世界——(一)入门基础

              Re:从零开始的C++世界——(一)入门基础

              目前,C++还在不断向后发展中。

              1.命名空间

              1.1 namespace的价值

              在C/C++中,变量、函数和后⾯要学到的类都是⼤量存在的,这些变量、函数和类的名称将都存在于全局作⽤域中,可能会导致很多冲突。使⽤命名空间的⽬的是对标识符的名称进⾏本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。

              c语⾔项⽬类似下⾯程序这样的命名冲突是普遍存在的问题,C++引⼊namespace就是为了更好的解决这样的问题。

              #include 
              #include 
              int rand = 10;
              int main()
              {
              	// 编译报错:error C2365: “rand”: 重定义;以前的定义是“函数”
              	printf("%d\n", rand);
              	return 0;
              }
              

              1.2 namespace的定义

              • 定义命名空间,需要使⽤到namespace关键字,后⾯跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等。

               // 普通的命名空间
              namespace N1 // N1为命名空间的名称
              {
              	//  命名空间中的内容,既可以定义变量,也可以定义函数
              	int a;
              	int Add(int x, int y) 
              	{
              		return x + y;
              	}
              }
              

              • namespace只能定义在全局,当然他还可以嵌套定义。

              // 命名空间可以嵌套
              namespace N1 // 定义一个名为N1的命名空间
              {
              	int a;
              	int b;
              	namespace N2 // 嵌套定义另一个名为N2的命名空间
              	{
              		int c;
              		int d;
              	}
              }
              

              •项⽬⼯程中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。

              // 定义一个N1
              namespace N1
              {
              	int a;
              	int Add(int x, int y) {
              		return x + y;
              	}
              }
              // 再定义一个N1
              namespace N1
              {
              	int Mul(int left, int right)
              	{
              		return left * right;
              	}
              }
              

              其它特征:

              • namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以下

              ⾯的rand不在冲突了。

              • C++中域有函数局部域,全局域,命名空间域,类域;域影响的是编译时语法查找⼀个变量/函数/

              类型出处(声明或定义)的逻辑,所有有了域隔离,名字冲突就解决了。局部域和全局域除了会影响

              编译查找逻辑,还会影响变量的⽣命周期,命名空间域和类域不影响变量⽣命周期。

              • C++标准库都放在⼀个叫std(standard)的命名空间中。

              1.3 命名空间使⽤

              编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以下⾯程序会编译报错。

              #include
              namespace bit
              {
              	int a = 0;
              	int b = 1;
              } 
              int main()
              {
              	// 编译报错:error C2065: “a”: 未声明的标识符
              	printf("%d\n", a);
              	return 0;
              }
              

              所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

              (1)加命名空间名称及作用域限定符,项⽬中推荐这种⽅式。

              符号 :: 在 C++中叫做作用域限定符。
              

              我们通过 命名空间名称 :: 命名空间成员 便可以访问到命名空间中相应的成员。

              #include 
              // 加命名空间名称及作用域限定符
              namespace N
              {
              	int a;
              	float b;
              }
              int main()
              {
              	N::a = 10; // 将命名空间中的成员a赋值为10
              	N::b = 5.55; // 将成员b赋值为5.55
              	printf("%d\n", N::a); // 打印a
              	printf("%.2f\n", N::b); // 打印b
              	return 0;
              }
              

              (2)使用 using 将命名空间中成员引入

              我们还可以通过 using 命名空间名称::命名空间成员 的方式将命名空间中指定的成员引入。

              这样语句之后的代码中就可以直接使用引入的成员变量了。项⽬中经常访问的不存在冲突的成员推荐这种⽅式。

              #include 
              // 使用using将命名空间中的成员引入
              namespace N
              {
              	int a;
              	float b;
              }
              using N::a; // 将命名空间中的成员a引入
              using N::b; // 再将b引入
              int main()
              {
              	a = 10; // 将命名空间中的成员a赋值为10
              	b = 5.55; // 将b赋值为5.55
              	printf("%d\n", a); // 打印成员a
              	printf("%.2f\n", b); // 打印成员b
              	return 0;
              }
              

              (3) 使用 using namespace 命名空间名称引入

              最后一种方式就是通 using namespace 命名空间名称 将命名空间中的全部成员引入。

              这样语句之后的代码中就可以直接使用该命名空间内的全部成员了,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

              #include 
              // 使用 using namespace 命名空间名称引入
              namespace N
              {
              	int a;
              	float b;
              }
              using namespace N; // 将命名空间N的所有成员引入
              int main()
              {
              	a = 10; // 将命名空间中的成员a赋值为10
              	printf("%d\n", a); // 打印命名空间中的成员a
              	return 0;
              }
              

              2.C++输⼊&输出

              在学习任何语言的时候,我们首先会向 世界问好!也就是会在屏幕上打印 hello world!

              那么用 C++ 如何打印呢?很简单。

              #include 
              using namespace std;
              int main()
              {
              	cout 
              	// 在io需求⽐较⾼的地⽅,如部分⼤量输⼊的竞赛题中,加上以下3⾏代码
              	// 可以提⾼C++IO效率
              	ios_base::sync_with_stdio(false);
              	cin.tie(nullptr);
              	cout.tie(nullptr);
              	
              	return 0;
              }
              
              	cout 
              	Func(); // 没有传参时,使⽤参数的默认值
              	Func(10); // 传参时,使⽤指定的实参
              	return 0;
              }
              
                  cout 
                  Test();
                  Test(10);
                  Test(10, 20);
                  Test(10, 20, 30);
                  return 0;
              }
              
                  cout 
                  cout 
              	cout 
              	cout 
              	cout 
              	cout 
              	cout 
              	return a + b;
              }
              double Test(double a, double b) {
              	return a + b;
              }
              double Test(int a, double b) {
              	return a + b;
              }
              int main()
              {
              	cout 
              // return 0;
              //}
              //
              //int fxx()
              //{
              // return 0;
              //}
              
              	int a = 0;
              	// 引⽤:b和c是a的别名
              	int& b = a;
              	int& c = a;
              	// 也可以给别名b取别名,d相当于还是a的别名
              	int& d = b;
              	++d;
              	// 这⾥取地址我们看到是⼀样的
              	cout 
              	const int a = 10; //变量a是只读的
              	//这里的b属于权限的放大,编译会报错
              	int& b = a; //b是a的别名,但b是可读可写的
              	const int& c = a; //c是a的别名,和a一样,c是只读的
              	return 0;
              }
              
              	int a = 10; //可读可写
              	const int& b = a; //只读权限
              	//打印b(读权限)
              	cout 
              	double d = 2.2;
              	
              	int& a = d; //编译不通过,会报错
              	
              	const int& b = d;
              	return 0;
              }
              
              	int temp = *p1;
              	*p1 = *p2;
              	*p2 = temp;
              }
              void Swap2(int& rx, int& ry) {
              	int temp = rx;
              	rx = ry;
              	ry = temp;
              }
              int main()
              {
              	int x = 3, y = 5;
              	Swap1(&x, &y); // C传参
              	Swap2(x, y); // C++传参
              	return 0;
              }
              
              	static int n = 0;
              	n++;
              	return n;
              }
              int main()
              {
              	int ret = Cout();
              	cout 
              	static int n = 0;
              	n++;
              	return n;
              }
              int main()
              {
              	int ret = Cout();
              	cout 
              	return x + y;
              }
              int main()
              {
              	int ret = 0;
              	ret = Add(1, 2);
              	return 0;
              }
              
              	return x + y;
              }
              int main()
              {
              	int ret = 0;
              	ret = Add(1, 2);
              	return 0;
              }
              
               cout 
               f(10);
               return 0;
              }
              
               	int* p1 = NULL;
               	int* p2 = 0;
              }
              
              	cout 
              	cout 
              	f(0); //调用f(int)
              	f(NULL); //也是调用f(int)
              	return 0;
              }
              
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]