[c++语法学习]Day 9:
1. 命名空间
#include<iostream>
int a = 0;namespace bit
{// 可以定义变量,函数等// 不需要分号int a = 1;
}
// 命名空间的嵌套
namespace N1
{int a = 10;int N1 = 11;int add(int a, int b) {return a + b;}namespace N2{int a = 20;}
}
// 同名的命名空间会合并
namespace N1
{void ppp() {printf("我是N1 中的 N1 = %d\n",N1);}
}// 命名空间的展开
// 实际是不太好的,可能会造成命名冲突
// 在项目中还是不要展开,建议指定访问
// using namespace bit;// 可以展开常用的
using std::cout;
using std::endl;
using std::cin;
int main()
{// 优先访问局部作用域// 局部-》全局-》展开的命名空间int a = 2;// 域作用限定符 ::// 相当于去说明在哪一个域进行访问,默认是全局printf("%d\n",a);printf("%d\n", ::a);printf("%d\n", bit::a);printf("%d\n", N1::N2::a);N1::ppp();// 自动识别类型 cout << "指定展开" << endl;cin >> a;return 0;
}
2. 预处理-编译-汇编-链接(简化版)
stack.h stack.cpp test.cpp
1.预处理
在预处理阶段包含:头文件展开/宏替换/条件编译/去注释…
注意此时将不存在.h文件,此时已经将对应的头文件进行展开
2.编译(stack.i test.i)
检查语法错误,生成汇编代码
3.汇编(stack.s test.s)
汇编代码转为二进制机器码
4.链接(stack.o test.o)
链接为可执行程序(.exe .out)在未链接之前,所有的函数声明都只是声明,还没有具体的实现,只有链接才将具体的实现实现起来(就像是兑现承诺)
3.缺省参数
// 3.缺省参数(默认参数)
// 没有传参时,使用默认的参数
// 全缺省
// 半缺省(部分缺省)---从右往左缺省void Func(int a ,int b = 10,int c = 20) {cout << "a = " << a << endl;cout << "b = " << b << endl;cout << "c = " << c << endl;}
// 预处理 编译 链接 注意这里最后才链接
// 只有声明时给出缺省参数才有用
// 因为编译时函数实现还没被链接起来,因此不知道默认值是多少
// 所以在这里应该是声明给出缺省值
struct Stack {int* a;int top;int capacity;
};
void StackInit(struct Stack* pst, int defaultcapacity = 4);
void StackInit(struct Stack* pst, int defaultcapacity) {pst->a = (int*)malloc(sizeof(int) * defaultcapacity);if (pst->a == NULL) {perror("malloc fail");return;}pst->top = 0;pst->capacity = defaultcapacity;
}
4.函数重载
// 4.函数重载
// 在同一作用域的同名函数可以重名
// 可以通过参数类型不同,参数个数不同,参数类型顺序不同 进行区分
// 返回值没有要求int add(int left = 0, int right = 0) {cout << "left + right = " << left + right << endl;return left + right;
}double add(double left, double right) {cout << "left + right = " << left + right << endl;return left + right;
}int add(int a, int b, int c) {cout << "a+b+c = " << a+b+c << endl;return a+b+c;
// 为什么 c 不支持重载 ,CPP 支持?
// 编译链接过程
// 函数名修饰规则
// 主要是 c 只通过函数名称对函数进行区分
// 而 c++ 在进行汇编时对不同的函数名进行修饰
// addii adddd addiii
// 会把参数的名字带入
/*
// 通过这里就理解了C语言没办法支持重载,因为同名函数没办法区分。而C++是通过函数修
// 饰规则来区分,只要参数不同,修饰出来的名字就不一样,就支持了重载
*/
5. 引用
// 引用:就相当于起一个别名,因此引用必须初始化
int a = 0;
int& b = a;
int& c = b;cout << &a << endl;
cout << &b << endl;
cout << &c << endl;
// 错误❌
int& d;
int x = 10;
// 这里是赋值,不是修改引用,引用不能修改
b = x;
// 3.引用交换
// 引用形参
void Swap(int& a, int& b)
{int temp = a;a = b;b = temp;
}
// 应用:链表
// 这里为什么使用双指针或者指针的引用?
/*
void ListPushBack_Wrong(ListNode* phead, int x) {ListNode* newNode = createNode(x);if (phead == NULL) {phead = newNode; // 问题在这里!// 这只是在函数内部修改了局部变量phead// 外部的head指针没有被改变} else {// 找尾节点插入...}
}
*/
typedef struct ListNode
{int val;struct ListNode* next;
}LTNode,*PLTNode;
ListNode *p = NULL;
void ListPushBack(struct ListNode*& phead, int x);
void ListPushBack(struct ListNode** phead, int x);
void ListPushBack(struct PLTNode& phead, int x);