C++语法知识点合集:1.入门概念part


一、命名空间

目的:c语言无法解决命名冲突问题,避免命名冲突或名字污染
一个命名空间就定义了一个新的作用域

1.定义命名空间

namespace n1
{
    int a;
    int b;
    int add(int left, int right)
    {
        return left + right;
    }
    struct node
    {
        int val;
        node *next; // c++可以不用重命名了
    };

}
namespace n2
{
    int c;
    int d;
    int minus(int left, int right)
    {
        return left - right;
    }
}
// rumen.c++和rumen.h中若分别有同一个命名空间 编译器会合并成一个

2.使用命名空间

// 使用方式
// 3. 2.
using namespace n2;
using n1::b;
int main()
{
    // 1. ::
    printf("%d", n1::a);
    // 2.using 引入命名空间中的成员
    printf("%d\n", b);
    // 3.using 引入整个命名空间
    printf("%d\n", c);
    return 0;
}

二、C++输入和输出

cout标准输出对象(控制台),cin标准输入对象(键盘),cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,它们都包含在< iostream >头文件中。

1.输入

#include <iostream>
// std是C++标准库的命名空间名
using namespace std;
int main()
{
    int a;
    //可以自动识别变量类型
    cin >> a;
    cout << a << endl;
    return 0;
}

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

2.输出

#include <iostream>
// std是C++标准库的命名空间名
using namespace std;
int main()
{
    cout << "hello world"
         << endl;
    return 0;
}
// 在io需求比较高的地方,如部分大量输入的竞赛题中,加上以下3行代码
// 可以提高C++IO效率
	ios_base::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);

三、缺省函数

1.概念

缺省函数是声明或定义函数时为参数制定一个缺省值,调用函数时,若无指定实参就用缺省值。

2.分类

全缺省函数:

void f1(int a = 1, int b = 2, int c = 3)
{
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << "c=" << endl;
    return;
}

半缺省函数:

半缺省函数的缺省参数必须从右向左给出,不能间隔给出。缺省参数不能在函数声明和定义中同时出现,值必须是常量或全局变量。

void f2(int a, int b = 2, int c = 3)
{
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << "c=" << endl;
}

四、函数重载

C++允许在同一作用域中声明几个功能类似的同名函数,这些函数的形参列表(形参个数,类型,类型顺序)不同,常用于处理实现功能类似但数据类型不同的问题

1、参数类型不同

// 1、参数类型不同
int Add(int left, int right)
{
    cout << "int Add(int left, int right)" << endl;
    return left + right;
}

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

void Swap(int *px, int *py)
{
}

void Swap(double *px, double *py)
{
}

2、参数个数不同

// 2、参数个数不同
void f()
{
    cout << "f()" << endl;
}
void f(int a)
{
    cout << "f(int a)" << endl;
}

3、参数类型顺序不同

// 3、参数类型顺序不同
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;
}

4.命名空间不同

namespace n1
{
    void f1()
    {
        cout << "f()" << endl;
    }
}
void f1()
{
    cout << "f()" << endl;
}

5、错误案例

// 下面两个函数构成重载
// f() 但是调用时,会报错,存在歧义,编译器不知道调用谁

void f1()
{
    cout << "f()" << endl;
}

void f1(int a = 10)
{
    cout << "f(int a)" << endl;
}
// 返回值不同不能作为重载条件,因为调用时也无法区分
void fxx()
{
}

int fxx()
{
    return 0;
}

6.名字修饰——C++支持函数重载的原理

在C/C++中,程序运行需要预处理->编译->汇编->链接
每个编译器都有自己的函数名修饰规则,编译完成后,函数名字被修饰(添加了参数信息),C语言并不支持。

两个函数名字和参数若一致,但返回值不同,不构成重构。编译器修饰后的函数名仍然一致,调用时编译器无法区分

五、引用

引用是给已存在变量取个别名,和引用的变量共用同一内存空间
类型&引用对象名=引用实体

void ref()
{
    // 引用类型必须和引用实体同一类型
    int a = 10;
    int &ra = a;
}

1.引用特性

引用在定义时必须初始化,一个变量可以有多个引用,一个引用只有一个实体

	int a = 10;
    int &ra = a;
    int &rra = a;
    // int &ra; 是错的

2.常引用

	const int &b = 210;
 // 编译通常可以成功通过,因为编译器允许基本数据类型之间的隐式转换
    double d = 12.34;
    const int &rd = d;

3.引用的使用

  • 主要用于引用传参和引用做返回值中减少拷贝,提高效率;改变引用对象的同时改变被引用对象
  • 引用传参和指针传参功能类似
  • 引用自加是引用的实体+1,指针自加是指针向后偏移一个类型的大小

六、内联函数

实现一个ADD宏函数的常见问题

#define ADD(int a, int b) return a + b;
#define ADD(a, b) a + b;
#define ADD(a, b) (a + b)

正确的宏实现

#define ADD(a, b) ((a) + (b))
  • 为什么不能加分号?
    分号通常用于结束语句,但在宏定义里,如果在 ((a) + (b)) 后加上分号,宏会被解释成两个独立的操作,即 (a) + (b);,而不是期望的加法操作。
  • 为什么要加外面的括号?
    使用外层括号是为了明确表达式范围,防止宏展开后的代码因为上下文解析而出现问题。如果不使用括号,像 ADD(a, b) 可能会与后续的代码混淆,导致意想不到的结果。加了括号之后,(a) + (b) 就被视为一个整体。
  • 为什么要加里面的括号?
    内层括号是必要的,因为它确保了 + 运算符优先级高于自变量 a 和 b。如果没有括号,a 和 b 直接跟在运算符后面可能会按照较低的优先级解析,这可能导致错误的结果。

1.使用和特性

inline int Add(int x, int y)
{
    int ret = x + y;
    return ret;
}
int main()
{
    int ret = Add(1, 2);
    cout << Add(1, 2) * 5 << endl;
    cout << ret << endl;
    return 0;
}
  • inline是以空间换时间,在编译阶段,会用函数体替换函数调用。可能会使目标文件变大,但是少了调用开销,提高效率
  • 函数规模较小,不是递归,不频繁调用的函数可以选择用inline修饰
  • inline 声明和定义不要分离,会导致链接错误
  • inline函数会在调用的地方展开,所以符号表中不会有inline函数的符号名,不存在链接冲突。可以在同一个项目的不同源文件内定义函数名相同但实现不同的inline函数。
  • 使用inline关键字的函数不一定会被编译器在调用处展开,inline只是一种建议,需要看此函数是否能够成为内联函数。比较长的函数,递归函数就算定义为inline,也会被编译器忽略。

2.替代宏

  • 宏的优缺点?
    优点:
    1.增强代码的复用性。
    2.提高性能。
    缺点:
    1.不方便调试宏。(因为预编译阶段进行了替换)
    2.导致代码可读性差,可维护性差,容易误用。
    3.没有类型安全的检查,
  • C++有哪些技术替代宏?
    1.常量定义 换用const enum
    2.短小函数定义 换用内联函数
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值