前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >c++基础(1)

c++基础(1)

作者头像
用户11039545
发布2024-07-17 08:20:27
490
发布2024-07-17 08:20:27
举报
文章被收录于专栏:c语言

c语言是结构化和模块化的语言,用于处理规模较小的程序。当问题需要高度抽象和建模时,c语言不适合。c++是基于c语言产生的,既可以进行c语言过程化程序设计,又可以以抽象数据类型为特点的基于对象的程序设计,还可以进行面向对象的程序设计

namespace关键字:使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染。

如果像下面这种情况,在c语言中是解决不了的:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
int rand = 10;
int main()
{
  printf("%d\n", rand);
  return 0;
}

编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

命名空间定义

命名方法:使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{} 中即为命名空间的成员。

我们有不同的命名空间定义方法:

1、正常的命名空间定义

命名空间中可以定义变量/函数/类型

代码语言:javascript
复制
namespace pearl
{
   int rand=10;
   int Add(int left, int right)
   {
      return left + right;
    }
   Struct Node
   {
      Struct Node* next;
      int val;
    };
}

2、命名空间可以嵌套

//test.cpp

代码语言:javascript
复制
namespace pearl1
{
   namespace pearl2
   {
      int Add(int a,int b)
      {
         return a+b;
      }
    }
}

3、同一个工程中可以出现命名相同的空间,并且编译器最终会合成在同一个命名空间当中

//test.h

代码语言:javascript
复制
namespace pearl1
{
   int Sub(int a,int b)
   {
      return a-b;
    }
}

注意:一个命名空间就定义了一个作用域,命名空间所有的内容都局限在该命名空间当中

命名空间的使用

比如我们在命名空间当中定义了一个变量,我们该如何把它调用出来呢?

代码语言:javascript
复制
namespace pearl
{
   int a=1;
   int b=0;
   int rand=10;
   int Add(int left, int right)
   {
      return left + right;
    }
   Struct Node
   {
      Struct Node* next;
      int val;
    };
}
int main()
{
   printf("%d",a);
   return 0;
}

// 编译报错:error C2065: “a”: 未声明的标识符

命名空间的使用有三种方法:

1、加空间名称以及域作用限定符

代码语言:javascript
复制
int main()
{
    printf("%d\n", pearl1::a);
    return 0;
}

2、使用using将某个空间成员引入

代码语言:javascript
复制
using pearl::b;
int main()
{
    printf("%d\n", b);
    return 0; 
}

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

代码语言:javascript
复制
using namespce pearl;
int main()
{
    printf("%d\n", pearl::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

这里a和b都能够被正常打印出来。 

c++输入和输出

代码语言:javascript
复制
#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
   cout<<"Hello world!!!"<<endl;
   return 0;
}

注意:

使用cout(标准输出对象(控制台))和cin(标准输入对象(键盘))时,必须包含<iostream>标准头文件以及按照命名空间使用方法使用std。

cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

是流插入运算符,>>是流提取运算符。并且在c++中的输入和输出可以自动识别变量的类型。

std命名空间的使用惯例

在日常练习中,建议直接using namespace std即可。

如果在大型的开发项目当中,直接展开,会出现比较多的问题,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式就可以了。

缺省参数

概念

是在C++声明或定义函数时,为函数的参数指定一个默认值。在调用该函数时,如果没有为某个参数指定实参(即没有显式地传递一个值给这个参数),则该函数将自动采用该参数的默认值。如果调用时提供了实参,则使用指定的实参值。

分类

全缺省参数
代码语言:javascript
复制
void Func(int a = 10, int b = 20, int c = 30)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }
半缺省参数
代码语言:javascript
复制
void Func(int a, int b = 10, int c = 20)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }
注意事项

1半缺省参数必须从右往左给,不能跳着给。

2缺省参数不能在定义和声明中同时出现。

如果声明与定义位置同时出现缺省参数,恰巧两个位置提供的值不同,那编译器就无法确定到底用哪个缺省值。

3缺省值必须是常量或者全局变量

函数重载

概念

在同一作用域,使用相同名称且功能类似的同名函数,这些同名函数的形参列表不同,来处理不同数据类型的问题。

1、参数类型不同
代码语言:javascript
复制
#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
 cout << "int Add(int left, int right)" << endl;
 return left + right;
}
double Add(int left, int right)
{
 cout << "double Add(int left, int right)" << endl;
 return left + right;
}
2、参数个数不同
代码语言:javascript
复制
void Add()
{
   cout << "f()" << endl;
}

void Add(int a)
{
   cout << "f(int a)" << endl;
}
3、参数顺序不同
代码语言:javascript
复制
void f(int a, char b)
{
 cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
 cout << "f(char b, int a)" << endl;
}

那么为什么c语言支持函数重载,而c++不支持呢

review:一个程序需要运行起来,需要经过预处理,编译,汇编,链接这四个过程。

实际的项目通常由多个源文件和多个头文件组成,在编译后链接前,当addB.obj中调用的函数地址只在addA.obj(在addA.cpp中定义)中存在,我们就会进行链接。链接器在看到addB.obj调用obj时,就会到addA.obj中的符号表找到Add的地址,然后链接到一起。

每个编译器都有自己的命名规则,那么链接器会在哪儿寻找Add函数呢?

c语言

在Linux下,采用gcc编译后,函数名的修饰不发生改变。

c++

在Linux下,采用g++编译后,函数名的修饰发生改变。 会在编译过程中将函数的参数类型信息(以及其他可能需要的信息,如模板参数等)添加到函数的名字中。

引用

定义

引用不是定义一个新的变量,而是原有的变量有了新的别名,并不需要为这个别名开辟一个新的空间,它和引用的变量公用一块存储空间。

规则 :引用类型&引用变量名=引用实体名;

代码语言:javascript
复制
int &ra=a;

引用变量必须和引用实体是同种类型的。

引用特性

1引用前必须初始化

2一个实体可以被多次引用

3一个引用变量名只能使用一次,不能再引用其他实体

常引用

下面我将会逐个讲解下面代码错误的地方,以及如何修正

代码语言:javascript
复制
void TestConstRef()
{
    const int a = 10;
    int& ra = a;  
    const int& ra = a;
    int& b = 10; 
    const int& b = 10;
    double d = 12.34;
    int& rd = d; 
    const int& rd = d;
}

 const int a = 10;     int& ra = a;     错误 ,不能将非常量引用绑定到常量对象上。

   const int& ra = a;  正确

2  int& b = 10; 

错误,不能将非常量引用绑定到字面量上

 const int& b = 10; 正确

3      double d = 12.34;       int& rd = d;     错误,类型不同

const int&rd=d; 正确

权限可以缩小,但不能被放大。

用法

1作为参数
代码语言:javascript
复制
void swap(int&left,int&right)
{
   temp=left;
   left=right;
   right=temp;
}
2作为函数的返回值
代码语言:javascript
复制
int &count()
{
  static int n=0;
  n++;
  return n;
}
代码语言:javascript
复制
int& Add(int a, int b)
{
    int c = a + b;
    return c;
}
int main()
{
    int& ret = Add(1, 2);
    Add(3, 4);
    cout << "Add(1, 2) is :"<< ret <<endl;
    return 0;
}

Add函数运行结束之后,栈帧就被销毁了,c变量就没有意义了。但是空间被回收指的是空间不能使用,仍然可以通过引用找到这个值。 

在调用函数结束后,如果返回对象还在(未还给系统),可以使用引用返回,如果返回对象已经还给系统,就要使用传值返回。

传值传址效率比较

采用传值返回时,返回的并不是值本身,而是该实参或者返回变量的一份临时拷贝,因此效率非常低下。

在语法层面上,引用是不占空间的。

但是在底层逻辑层面,引用需要占一块空间。

代码语言:javascript
复制
int main()
{  
   int a=10;
   int &ra=a;
   ra=20;
   
   int *p=&a;
   *p=20;
   return 0;
}

引用和指针的区别

1 引用必须要初始化,指针可以不用初始化

2 引用在引用时只能引用一个实体,而多个指针可以指向同一个实体

3sizeof的结果不同,引用中计算的是引用内容的大小,而指针是地址空间的大小

4引用中+1是引用的实体加一,而指针是偏移一个类型大小

5指针需要显示解引用,指针只需要自己处理

6引用比指针更加安全

内联函数

概念

以inline修饰的函数叫作内联函数,在gcc编译器下,只有内联函数才会展开

auto关键字

编译器会通过变量初始化的表达式来推断变量的类型。(编译器在编译时期推导而得)它并不是一种类型的声明,而是一种类型的占位符。编译器在编译时期会替换成实际的类型。

auto的使用细则

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 命名空间定义
    • 1、正常的命名空间定义
      • 2、命名空间可以嵌套
        • 3、同一个工程中可以出现命名相同的空间,并且编译器最终会合成在同一个命名空间当中
        • 命名空间的使用
          • 1、加空间名称以及域作用限定符
            • 2、使用using将某个空间成员引入
              • 3、使用using namespace命名空间名称引入
              • c++输入和输出
                • std命名空间的使用惯例
                • 缺省参数
                  • 概念
                    • 分类
                      • 全缺省参数
                      • 半缺省参数
                      • 注意事项
                  • 函数重载
                    • 概念
                      • 1、参数类型不同
                      • 2、参数个数不同
                      • 3、参数顺序不同
                  • 引用
                    • 定义
                      • 引用特性
                        • 常引用
                          • 用法
                            • 1作为参数
                            • 2作为函数的返回值
                          • 传值传址效率比较
                            • 引用和指针的区别
                            • 内联函数
                              • 概念
                              • auto关键字
                                • auto的使用细则
                                相关产品与服务
                                云硬盘
                                云硬盘(Cloud Block Storage,CBS)为您提供用于 CVM 的持久性数据块级存储服务。云硬盘中的数据自动地在可用区内以多副本冗余方式存储,避免数据的单点故障风险,提供高达99.9999999%的数据可靠性。同时提供多种类型及规格,满足稳定低延迟的存储性能要求。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档