首页 > 编程语言 >C++入门

C++入门

时间:2024-12-13 22:30:36浏览次数:6  
标签:ps 入门 rs int namespace 缺省 C++

目录

1.C++的第一个程序

2.命名空间

2.1namespace

2.2命名空间的嵌套

2.3多文件定义同名namespace默认合并

2.3.1Stack.h

2.3.2Stack.cpp

2.3.3test.cpp

2.4使用

3.C++输入&输出

4.缺省参数

4.1全缺省、半缺省

4.2多文件缺省参数使用

4.2.1Stack.h

4.2.2Stack.cpp

4.2.3test.cpp

5.函数重载

5.1参数类型不同

5.2参数个数不同

5.3参数类型顺序不同

5.4问题

6.引用

6.1特性

6.2使用

6.2.1引用替代指针传参

6.3const引用

6.4指针和引用关系


1.C++的第一个程序

C++兼容C语⾔绝⼤多数的语法,所以C语⾔实现的hello world依旧可以运⾏,C++中需要把定义⽂件代码后缀改为.cpp

C++版本的hello world:

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

2.命名空间

将变量、函数和类的名称全都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以此避免命名冲突或名字污染。

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

2.1namespace

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

· namespace本质是定义出⼀个域,这个域跟全局域各⾃独⽴,不同的域可以定义同名变量,所以    下⾯的rand不在冲突了。

· namespace只能定义在全局,也可以嵌套定义。

· 项目中多⽂件中定义的同名namespace会认为是⼀个namespace,不会冲突。

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

#include<iostream>

namespace shen
{
    //命名空间中可以定义变量/函数/类型
    int rand = 20;
    int Add(int left, int right)
    {
        return left + right;
    }
    
    struct Node
    {
        struct Node* next;
        int val;
    };
}

int main()
{
    printf("%d\n",shen::rand);//指定shen命名空间中的rand
    return 0;
}

2.2命名空间的嵌套

namespace shen
{
    namespace jie
    {
        int rand = 10;
        
        int Add(int left, int right)
        {
            return left + right;
        }
    }

    namespace yu
    {
        int rand = 20;
        
        int Add(int left, int right)
        {
            return (left + right) * 10;
        }
    }

}

int main()
{
    printf("%d\n",shen::jie::rand);//10
    printf("%d\n",shen::yu::rand);//20

    printf("%d\n",shen::jie::Add(10,20));//30
    printf("%d\n",shen::yu::Add(10,20));//300

    return 0;
}

2.3多文件定义同名namespace默认合并

2.3.1Stack.h

#pragma once
#include<iostream>
#include<assert.h>

namespace shen
{
    typedef int STDatatype;
    typedef struct Stack
    {
        STDatatype* a;
        int top;
        int capacity;
    }ST;

    void STInit(ST* ps, int n);//栈初始化
    void STPush(ST* ps,STDatatype x);//栈插入
}

2.3.2Stack.cpp

#include"Stack.h"
namespace shen
{
    void STInit(ST* ps, int n)
    {
        assert(ps);

        ps->a = (STDatatype*)malloc(n * sizeof(STDatatype));
        ps->top = 0;
        ps->capacity = n;
    }

    void STPush(ST* ps, STDatatype x)
    {
        assert(ps);
    
        if(ps->top == ps->capacity)
        {
            printf("扩容\n");
            int newCapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
            STDatatype* tmp = (STDatatype*)realloc(ps->a, newcapcity * sizeof(STDatatype));
            if(tmp == NULL)
            {
                perror("realloc fail");
                return;
            }
            ps->a[ps->top] = x;
            ps->top++;
    }
}

2.3.3test.cpp

#include"Stack.h"
int main()
{
    shen::ST st;
    shen::STInit(&st);
    shen::STPush(&st, 1);
    shen::STPush(&st, 2);

    return 0;
}

2.4使用

编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间⾥⾯去查找。所以 下⾯程序会编译报错。所以我们要使⽤命名空间中定义的变量/函数,有三种⽅式:

· 指定命名空间访问,项⽬中推荐这种⽅式。

· using将命名空间中某个成员展开,项⽬中经常访问的不存在冲突的成员推荐这种⽅式。

· 展开命名空间中全部成员,项⽬不推荐,冲突⻛险很⼤,⽇常⼩练习程序为了⽅便推荐使⽤。

#include<iostream>
namespace shen
{
    int a = 20;
    int b = 10;
}

编译报错

int main()
{
    printf("%d\n",a);//未定义的标识符a
    return 0;
}

指定命名空间访问

int main()
{
    printf("%d\n",shen::a);
    return 0;
}

using将命名空间中某个成员展开

using shen::a;
int main()
{
    printf("%d\n",a);
    return 0;
}

展开命名空间中全部成员

using namespace shen
int main()
{
    printf("%d\n",a);
    printf("%d\n",b);
    return 0;
}

3.C++输入&输出

·  <iostream> 是 Input Output Stream 的缩写,是标准的输⼊、输出流库,定义了标准的输⼊、输      出对象。

· std::cin 是 istream 类的对象,它主要⾯向窄字符(narrow characters (of type char))的标准输      ⼊流。

· std::cout 是 ostream 类的对象,它主要⾯向窄字符的标准输出流。

· std::endl 是⼀个函数,流插⼊输出时,相当于插⼊⼀个换⾏字符加刷新缓冲区。

· <<是流插入运算符,>>是流提取运算符。

· C++的输⼊ 输出可以⾃动识别变量类型,最重要的是 C++的流能更好的⽀持⾃定义类型对象的      输⼊输出。

· cout/cin/endl等都属于C++标准库,C++标准库都放在⼀个叫std(standard)的命名空间中,所以      要通过命名空间的使⽤⽅式去⽤他们。

#include<iostream>
using namespace std;
int main()
{
    int rand = 10;
    char c = 'x';

    cout << rand << " " << c << endl;//打印 10 x
    std::cout << rand << " " << c << std::endl;

    //可以自动识别变量的类型
    cin >> rand;
    cin >> c;

    cout << rand << endl;
    cout << c << endl;

    return 0;
} 

4.缺省参数

· 缺省参数是声明或定义函数时为函数的参数指定⼀个缺省值。在调⽤该函数时,如果没有指定实    参则采⽤该形参的缺省值,否则使⽤指定的实参,缺省参数分为全缺省和半缺省参数。

· 全缺省就是全部形参给缺省值,半缺省就是部分形参给缺省值。C++规定半缺省参数必须从右往    左依次连续缺省,不能间隔跳跃给缺省值。

· 带缺省参数的函数调⽤,C++规定必须从左到右依次给实参,不能跳跃给实参。

· 函数声明和定义分离时,缺省参数不能在函数声明和定义中同时出现,规定必须函数声明给缺省    值。

#include<iostream>
using namespace std;

void Func(int a = 0)
{
    cout << a << endl;
}

int main()
{
    Func();   // 0  没有传参,使用参数的默认值
    Func(10); // 10 传参,使用指定的实参

    return 0;
}

4.1全缺省、半缺省

#include<iostream>
using namespace std;

//全缺省
void Func1(int a = 10, int b = 20, int c = 30)
{
    cout << "a = " << a <<endl;
    cout << "b = " << b <<endl;
    cout << "c = " << c <<endl;
}

//半缺省
void Func2(int a, int b = 20, int c = 30)
{
    cout << "a = " << a <<endl;
    cout << "b = " << b <<endl;
    cout << "c = " << c <<endl;
}

int main()
{
    Func1();     //10 20 30
    Func1(1);    //1  20 30
    Func1(1,2);  //1  2  30
    Func1(1,2,3);//1  2  3

    Func2(1);    //1  20 30
    Func2(1,2);  //1  2  30
    Func2(1,2,3);//1  2  3

    return 0;

}

4.2多文件缺省参数使用

4.2.1Stack.h
#include<iostream>
#include<assert.h>
using namespace std;

typedef int STDatatype;
typedef struct Stack
{
    STDatatype* a;
    int top;
    int capacity;
}ST;

void STInit(ST* ps, int n = 4);//不给参数时要开辟空间的大小
4.2.2Stack.cpp
#include"Stack.h"

//缺省参数不能声明和定义同时给,只能给声明
void STInit(ST* ps, int n)
{
    assert(ps && n > 0);
    
    ps->a = (STDatatype*)malloc(n * sizeof(STDatatype));
    ps->top = 0;
    ps->capacity = n;
}
4.2.3test.cpp
#include<iostream>
int main()
{
    ST st1;
    STInit(&st1);//初始化开辟4个int大小的空间

    ST st2;
    STInit(&st2,1000);//初始化开辟1000个int大小的空间

    return 0;

}

5.函数重载

C++⽀持在同⼀作⽤域中出现同名函数,但是要求这些同名函数的形参不同,可以是参数个数不同或者 类型不同。这样C++函数调⽤就表现出了多态⾏为,使⽤更灵活。C语⾔是不⽀持同⼀作⽤域中出现同名函数的。

5.1参数类型不同

int Add(int left, int right)
{
    std::cout << "int Add(int left, int right)" << std::endl;
    return left + right;
}

double Add(double left, double right)
{
    std::cout << "double Add(double left, double right)" <<std::endl;
    return left + right;
}

5.2参数个数不同

void f()
{
    std::cout << "f()" << std::endl;
}

void f(int a)
{
    std::cout<< "f(int a)" << std::endl;
}

5.3参数类型顺序不同

void f(int a, char b)
{
    std::cout << "f(int a, char b)" << std::endl;
}

void f(char a, int b)
{
    std::cout << "f(char a, int b)" << std::endl;
}

5.4问题

返回值不同不能作为重载条件,因为调用时也无法区分

void fxx()
{}

int fxx()
{
    return 0;
}

缺省参数

//下面两个函数构成重载
//但是调用时,会报错,存在歧义,编译器不知道调用谁
void f1()
{
    std::cout << "f1()" << std::endl;
}

void f1(int a = 10)
{
    std::cout << "f1(int a)" << std::endl;
}

6.引用

引⽤不是新定义⼀个变量,⽽是给已存在变量取了⼀个别名,编译器不会为引⽤变量开辟内存空间, 它和它引⽤的变量共⽤同⼀块内存空间。

类型& 引用别名 = 引用对象;

#include<iostream>
using namespace std;

int main()
{
    int a = 0;

    int& b = a;
    int& c = b;

    c++;
    
    //此打印的地址是相同的
    cout << &a << endl;
    cout << &b << endl;
    cout << &d << endl;
    return 0;
} 

6.1特性

· 引⽤在定义时必须初始化

· ⼀个变量可以有多个引⽤

· 引⽤⼀旦引⽤⼀个实体,再不能引⽤其他实体

6.2使用

· 引⽤在实践中主要是于引⽤传参和引⽤做返回值中减少拷⻉提⾼效率和改变引⽤对象时同时改变    被引⽤对象。

· 引⽤传参跟指针传参功能是类似的,引⽤传参相对更⽅便⼀些。

· 引⽤和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。

//指针方法
void Swap(int* rx, int* ry)
{
    int tmp = *rx;
    *rx = *ry;
    *ry = tmp;
}

//引用方法
void Swap(int& rx, int& ry)
{
    int tmp = rx;
    rx = ry;
    ry = tmp;
}

int main()
{
    int x = 0, y = 1;
    std::cout << x << " " << y << std::endl;
    
    Swap(x, y);
    std::cout << x << " " << y << std:: endl;

    return 0;
}

6.2.1引用替代指针传参

//栈实现
#include<iostream>
using namespace std;

typedef int STDatatype;
typedef struct Stack
{
    STDatatype* a;
    int top;
    int capacity;
}ST;

void STInit(ST& rs, int n = 4)
{
    rs.a = (STDatatype*)malloc(n * sizeof(STDatatype));
    rs.top = 0;
    rs.capacity = n;
}

void STPush(ST& rs, STDataType x)
{
    assert(ps);

    if (rs.top == rs.capacity)
    {
        printf("扩容\n");
        int newcapacity = rs.capacity == 0 ? 4 : rs.capacity * 2;
        STDataType* tmp = (STDatatype*)realloc(rs.a, newcapacity * sizeof(STDatatype));
        if (tmp == NULL)
        {
            perror("realloc fail");
            return;
        }
        rs.a = tmp;
        rs.capacity = newcapacity;
    }
        rs.a[rs.top] = x;
        rs.top++;
}

int& STTop(ST& rs)
{
    assert(rs.top > 0);
    return rs.a[rs.top];
}

int main()
{
    ST st1;
    STInit(st1);
    STPush(st1, 1);
    STPush(st1, 2);

    cout << STTop(st1) << endl;

    STTop(st1) += 10;

    cout << STTop(st1) << endl;

    return 0;
}

6.3const引用

· 可以引⽤⼀个const对象,但是必须⽤const引⽤。const引⽤也可以引⽤普通对象,因为对象的      访问权限在引⽤过程中可以缩⼩,但是不能放⼤。

· 不需要注意的是类似 int& rb = a*3; double d = 12.34; int& rd = d; 这样⼀些场景下a*3的和结果        保存在⼀个临时对象中, int& rd = d 也是类似,在类型转换中会产⽣临时对象存储中间值,也        就是时,rb和rd引⽤的都是临时对象,⽽C++规定临时对象具有常性,所以这⾥就触发了权限放      ⼤,必须要⽤常引⽤才可以。

· 所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象,     C++中把这个未命名对象叫做临时对象。

int main()
{
    const int a = 10;
    int ra = a;//错误,无法从"const int"转换为"int&",对a权限放大    

    const int& ra = a;//正确

    int b = 20;
    const int& rb = b;//正确,对b访问权限的缩小

    const int& rc = a * 3;//a * 3的结果保存在临时对象中,具有常性,触发权限放大,需要常引用
    
    double d = 12.34;
    const int& rd = d;//d类型从double转换为int时,结果保存在临时对象中

    return 0;
}

6.4指针和引用关系

· 语法概念上引⽤是⼀个变量的取别名不开空间,指针是存储⼀个变量地址,要开空间。

· 引⽤在定义时必须初始化,指针建议初始化,但是语法上不是必须的。

· 引⽤在初始化时引⽤⼀个对象后,就不能再引⽤其他对象;⽽指针可以在不断地改变指向对象。

· 引⽤可以直接访问指向对象,指针需要解引⽤才是访问指向对象。

· sizeof中含义不同,引⽤结果为引⽤类型的⼤⼩,但指针始终是地址空间所占字节个数(32位平台    下占4个字节,64位下是8byte)

· 指针很容易出现空指针和野指针的问题,引⽤很少出现,引⽤使⽤起来相对更安全⼀些。


标签:ps,入门,rs,int,namespace,缺省,C++
From: https://blog.csdn.net/sjyioo/article/details/144458906

相关文章

  • C/C++实例汇集(1)
    1、用代码判断一个系统是16位系统还是32位系统?以下是几种常见编程语言中判断系统是16位还是32位的代码示例C语言:#include<stdio.h>intmain(){//方法一:利用sizeofif(sizeof(int)==2){printf("16位系统\n");}elseif(sizeof(int)==4){......
  • C++哈希表
    哈希表教程目录哈希表是什么怎么用哈希表插入键值对查找元素删除元素遍历哈希表count检查是否存在某个键怎么用哈希表1.包含头文件首先,你需要包含unordered_map的头文件:#include<unordered_map>2.创建哈希表std::unordered_map<KeyType,ValueType>hashTableKey......
  • 在CodeBolcks+Windows API下的C++编程教程——给你的项目中添加资源文件和图标
    0.前言我想通过编写一个完整的游戏程序方式引导读者体验程序设计的全过程。我将采用多种方式编写具有相同效果的应用程序,并通过不同方式形成的代码和实现方法的对比来理解程序开发更深层的知识。了解我编写教程的思路,请参阅体现我最初想法的那篇文章中的“1.编程计划”:学习编程......
  • C++ 计算日期差
     #include<iostream>usingnamespacestd;//定义日期结构体,用于存放年、月、日这三个日期相关的信息structDate{intyear;intmonth;intday;};intmain(){Dated1,d2;//从标准输入(控制台)读取第一个日期的年、月、日信息cin>>d......
  • 深入计算机语言之C++:STL之list的模拟实现
    ......
  • 想通过自学入门Java,推荐看谁的课程?
    自学Java时,选择合适的课程非常重要。以下是一些知名的Java教学资源和讲师,他们的课程广受好评,适合初学者入门:1.**尚硅谷**-张晓峰 -尚硅谷的Java基础课程非常适合初学者,张晓峰老师的讲解深入浅出,课程内容全面。2.**极客时间**-老男孩 -老男孩的Java基......
  • C++_快慢指针在业务开发中的应用-数据结构与算法
    报错的解决vector不是模板问题,第一是由于没有添加#include<vector>。第二是需要添加命名空间。命名空间添加有两种,第一是直接在vector前面加上std::,第二是开头加入usingnamespacestd;加入vector后,std命名空间没有vector的问题--C++版本问题其他快慢下标......
  • 【ROS机器人入门】ROS的安装和更新,学不会头提给你
    打开官网www.ros.org,或者直接登录http://wiki.ros.org/noetic/Installation/Ubuntu进行所有操作前,先更新终端输入:sudoapt-getupdate终端输入:sudoapt-getupgrade 1.1ConfigureyourUbunturepositories 这一步配置ubuntu的软件仓库,一般在不熟悉的时候不动1......
  • pytest入门一:用例的执行范围
    从一个或多个目录开始查找,可以在命令行指定文件名或目录名。如果未指定,则使用当前目录。测试文件以test_开头或以_test结尾测试类以Test开头,并且不能带有init方法测试函数以test_开头断言使用基本的assert即可所有的包pakage必须要有__init__.py文......
  • pytest入门四:参数化
    当测试数据和期望结果不一样,但操作步骤是一样的测试用例可以用上参数化。@pytest.mark.parametrize(argnames,argvalues,indirect=False,ids=None)参数说明:argnames:一个或多个参数名,用逗号分隔的字符串,如"arg1,arg2,arg3",参数名与用例入参数一致。argvalues:参数值,必......