C++速查笔记
目录
结构体、类、指针、引用
class
中默认private
, struct
中默认是public
堆栈空间
- 代码是存到内存空间中的,所有的函数调用都是在栈空间中,局部变量都是定义到栈空间中的,静态变量和数组全部定义到堆空间中。
- 局部变量初始是随机值,全局变量初始全是
0
;(这是因为开在栈空间里的变量没有赋值,所以是不确定的;开到堆空间里的变量全部默认为0
。
&
和*
&
:引用、取地址符*
:指针、解引用符
某些符号有多重含义;像&
和*
这样的符号;- 在声明语句中,
&
和*
用于组成符合类型(&
引用,*
指针) - 在表达式中,它们的角色又转变成运算符。(
&
取地址符,*
解引用符)
int i = 42;
int &r = i;// & 紧随类型名出现,因此是声明的一部分,r 是一个引用
cout << r << endl;//42,引用就是一个别名,修改r,i也会随之变化
cout << &r << endl;// 获得r的地址,也就是i的地址
int* p; // * 紧随类型名出现,因此是声明的一部分,p 是一个指针
cout << p << endl;//p的随机地址,因为是局部变量,在栈空间中
p = &i;// & 出现在表达式中,是一个取地址符
cout << p << endl;// 取到i的地址
cout << *p << endl;// 42,通过i的地址得到i的值
*p = i;// * 出现在表达式中,是一个解引用符
cout << p << endl;// i的地址
cout << *p << endl;//解引用: i的值42
int &r2 = *p;// & 是声明的一部分,是一个引用;* 是一个解引用符
cout << r2 << endl;// 42,引用
cout << (r2==r) << (r==i) <<endl;
输出结果为:
42
0x7fffaa03df44
0x7fffaa03e040
0x7fffaa03df44
42
0x7fffaa03df44
42
42
11
指针、数组名
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[5] = {1,2,3,4,5};
cout << a << endl;// 数组名是数组的首地址
cout << *a << endl;// 1
for (int i = 0; i < 5; i++) cout << *(a + i) << ' ';
cout << endl;
char c = '1';
cout << (void*) &c << endl;// 地址:0x7fff55b6082b
for (int i = 0; i < 5; i++)
cout << (void*)&a[i] << endl;
/*
0x7fff5dd31b70
0x7fff5dd31b74
0x7fff5dd31b78
0x7fff5dd31b7c
0x7fff5dd31b80
隔了4个字节是因为每个int型变量有4个字节
如果是char类型的字符数组,则每个地址差1而不是4*/
return 0;
}
链表
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4;
//定义链表结构体
struct Node
{
int val;// 链表的值
Node* next; // 指向链表的下一个节点
// 构造函数:初始化链表的值,下一个节点指向NULL
Node(int _val):val(_val),next(NULL) {};
};
int main()
{
// 定义三个链表节点,初始化值
Node* p = new Node(1);
Node* q = new Node(2);
Node* o = new Node(3);
// p节点指向q节点
p->next = q;
q->next = o;
// 定义头节点,头节点就是p节点
Node* head = p;
// 在头节点前面添加节点4
Node* u = new Node(4);
u->next = head;// 把新节点插在头节点之前
head = u;
// 删除节点4
// head = head->next;
// 删除节点1
head->next = head->next->next;
// 遍历链表,i是指针,运行条件是 i!=NULL
for (Node* i = head; i; i = i->next)
cout << i->val << endl;
return 0;
}
给定节点指针,删除指定节点
输入:链表 1->4->6->8
删掉节点:第2个节点即6(头节点为第0个节点)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
void deleteNode(ListNode* node) {
// 当前node指向6这个节点
node->val = node->next->val;
node->next = node->next->next;
}
};
合并两个递增的链表,合并后仍递增
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode* dummy = new ListNode(0);// 记录头节点位置
ListNode* cur = dummy;
while(l1&&l2)
{
if (l1->val < l2->val)// l1的值小
{
cur->next = l1;
l1 = l1->next;
}
else// l2的值小
{
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;// 向后移动一位
}
// 如果有一个链表没有遍历完,就加在最后
if(l1) cur->next = l1; //l1不为NULL
if(l2) cur->next = l2; //l2不为NULL
return dummy->next;
}
};
全排列函数
bool next_permutation(iterator start,iterator end):
- next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数
- next_permutation()求的是
当前排列
的下一个排列
,同时并改变当前排列的值 - 返回值:当
当前序列
不存在下一个排列时,返回false, 否则返回true
class Solution {
public:
vector<vector<int>> permutation(vector<int>& nums) {
// next_permutation()在使用前需要对欲排列数组按升序排序,否则只能找出该序列之后的全排列数
sort(nums.begin(), nums.end());
vector<vector<int>> res;
res.push_back(nums);// 先将排好序的数组放入res中
// bool next_permutation(iterator start,iterator end):
// 求的是当前排列的下一个排列,同时并改变当前排列的值
// 返回值:当 当前序列 不存在下一个排列时,返回false, 否则返回true
while (next_permutation(nums.begin(), nums.end()))
{
res.push_back(nums);// 将每次生成的新排列放入 res 中
}
return res;
}
};
c++ string 总结
// str.back():获取string的最后一个字符
// str.pop_back():删除str中最后一个字符
// str.back = '!';修改最后一个字符
// str.front();获取字符串第一个字符
string a="abcd";
1.获取字符串最后一个字符
auto b=a.back(); //结果为 b='d';
2.修改字符串最后一个字符
a.back()='!'; //结果为 a="abc!";
3.获取字符串第一个字符
auto b=a.front(); //结果为 b='a';
4.修改字符串第一个字符
a.front()='!'; //结果为 a="!bcd";
str.erase(0);//删除字符
str.find("ab",index);//返回ab在字符串中第一次出现的位置(从index开始查找)
str.substr(index,length);// 返回从index开始,长为length的子字符串;若没有指定长度,则返回从index开始剩余所有字符串
signed main 和 int main 的区别?
int
本来就是signed int
。int = signed int = signed
,就像unsigned = unsigned int
当你不确定过程中会不会爆 int 的时候,可以这么写。
总结:
头文件声明#define int long long
,防止爆int
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef long long ll;
signed main(){
return 0;
}
#pragma Gcc optimize(3,"inline","Ofast");
#include<bits/stdc++.h>
using namespace std;
#define int long long
typedef long long ll;
signed main(){
double d;cin>>d;
printf("%.1f",d/59535);
}
printf保留小数
printf("%6.2f".floatNum)# 保留两位小数
说明:%6.2f 表明待打印的数(floatNum)至少占6个字符宽度(包括两位小数和一个小数点),且小数点后面有2位小数,小数点占一位,所以整数部分至少占3位。
注意:这里的6是待打印的数至少占据的字符宽度,包括两位小数(如果小数不够两位用0补位,例如100.1打印出来为100.10)和一个小数点,所以整数部分至少占3个字符宽度。
原文链接