数据类型
整型
int(整型)
- Int8, 等于Byte, 占1个字节.
- Int16, 等于short, 占2个字节. -32768 32767
- Int32, 等于int, 占4个字节. -2147483648 2147483647
- Int64, 等于long, 占8个字节. -9223372036854775808 9223372036854775807
浮点型
浮点数
大小比较
- 小数比较大小要确定精度来进行(一般精确最少要到小数点后六位,更精确更好)
字符型
布尔型
string
#include <string>
find()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
//主要字符串是从0开始计数的
cout<<"ab在str中的位置:"<<str.find("ab")<<endl;
//返回第一次出现ab的位置,没有则返回一串乱码
cout<<"ab在str[2]到str[n-1]中的位置:"<<str.find("ab",2)<<endl;
//返回第一次从str[2]开始出现ab的位置,没有则返回一串乱码
cout<<"ab在str[0]到str[2]中的位置:"<<str.rfind("ab",2)<<endl;
//返回ab在str[0]到str[2]中的位置,没有则返回一串乱码
return 0;
}
输入1
sdefdwefdadabbababab
1
输出1
ab在str中的位置:11
ab在str[2]到str[n-1]中的位置:11
ab在str[0]到str[2]中的位置:18446744073709551615
Program ended with exit code: 0
输入2
abfeofihwabab
输出2
ab在str中的位置:0
ab在str[2]到str[n-1]中的位置:9
ab在str[0]到str[2]中的位置:0
Program ended with exit code: 0
输入3
asdfghjk
输出3
ab在str中的位置:18446744073709551615
ab在str[2]到str[n-1]中的位置:18446744073709551615
ab在str[0]到str[2]中的位置:18446744073709551615
Program ended with exit code: 0
substr()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"返回str[3]及其以后的子串:"<<str.substr(3)<<endl;
//若小于限制长度则报错
cout<<"从ste[2]开始由四个字符组成的子串:"<<str.substr(2,4)<<endl;
//若小于限制长度则报错
return 0;
}
输入1
asdfghjkl;'/.,mnbvcxz
输出1
返回str[3]及其以后的子串:fghjkl;'/.,mnbvcxz
从ste[2]开始由四个字符组成的子串:dfgh
Program ended with exit code: 0
replace()
示列1
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.find("@"), 1, ""); //从第一个@位置替换第一个@为空
cout<<line<<endl;
return 0;
}
输出
this is@ a test string!
Program ended with exit code: 0
示列2
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.begin(), line.begin()+6, ""); //用str替换从begin位置开始的6个字符
cout << line << endl;
return 0;
}
示列3
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(0, 5, str); //用str替换从指定位置0开始长度为5的字符串
cout << line << endl;
return 0;
}
输出
12345 is@ a test string!
Program ended with exit code: 0
insert()
#include <string>
#include <iostream>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"从2号位置插入字符串jkl并形成新的字符串返回:"<<str.insert(2, "jkl")<<endl;//会返回一个新的字符串,需要接收.
return 0;
}
输入
sdfgh
输出
从2号位置插入字符串jkl并形成新的字符串返回:sdjklfgh
Program ended with exit code: 0
append()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"在字符串str后面添加字符串ABC:"<<str.append("ABC")<<endl;
return 0;
}
输入
diguwhdcow
1
输出
在字符串str后面添加字符串ABC:diguwhdcowABC
Program ended with exit code: 0
swap()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1,str2;
cin>>str1>>str2;
cout<<"str1:"<<str1<<endl;
cout<<"str2:"<<str2<<endl;
swap(str1, str2);
cout<<"str1:"<<str1<<endl;
cout<<"str2:"<<str2<<endl;
}
输入
qwertyui
asdfghjk
输出
str1:qwertyui
str2:asdfghjk
str1:asdfghjk
str2:qwertyui
Program ended with exit code: 0
compare()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1,str2;
cin>>str1>>str2;
cout<<str1.compare(str2)<<endl;
return 0;
}
输入
diwguc
aschsdnv
输出
3
Program ended with exit code: 0
size()和length()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1;
cin>>str1;
cout<<str1.size()<<endl;
cout<<str1.length()<<endl;
return 0;
}
输入
dchiascnsc
输出
10
10
Program ended with exit code: 0
#include< string.h >
strcpy(s1,s2)
复制字符串s2到s1
strcat(s1,s2)
连接s2到s1的末尾
strlen(s1)
返回字符串s1的长度
strcmp(s1,s2)
若s1和s2是相同的,则返回0,s1< s2,返回值小于0,若s1>s2,返回值大于0
strchr(s1,ch)
返回一个指针,指向字符串s1中字符ch第一次出现的位置
strstr(s1,s2)
返回一个指针,指向字符串s1中字符串s2的第一次出现位置
memcpy (void *dest, const void *src, int size)
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
strcpy与memcpy的区别:
- 复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
- 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
- 用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
指针类型
引用
引用的定义
*对变量起另外一个名字(别名),这个名字就成为该变量的引用。
int a;
int &ref_a = a;
**ref_a并没有在内存中开辟单元,只是引用a的单元。
**地址相同,但有两个名字。
*引用在被定义时,必须要初始化
*引用只能被定义一次,不可改成其他变量的引用。(唯一)
*常数值对应的引用必须是常引用
const double &rPI = 3.14;
引用和指针的区别
- 指针通过地址间接访问变量;引用通过别名直接访问变量。
- 存储指针需要额外的内存空间。
- 引用一旦被初始化,不会再作为其他变量的别名。
引用用作函数实参
//具有读写权限,而不是副本/拷贝,只可读。
//实参是变量而不是地址
void swap(int &x, int &y){
}
*常量引用
const int &x;//防止通过引用修改数值。
引用用作函数返回值
****warning****
int& m4(int x){
int &y = x;
return y;
}
指针的作用/用途
指针可以保存一个地址
指针的定义
-
数据类型 * 指针变量名
int * p;
-
让指针记录变量的地址
p = &a;
-
解引用
*p = 123213; //修改指向地址的数值
指针的内存空间
- 在32位操作系统下,占4个字节
- 在64位操作系统下,占8个字节
指针类型的分类
空指针
- 定义:指针变量指向内存中编号为0的空间
- 用途:初始化指针变量
- 注意:空指针指向的内存不可以访问(0~255之间的内存编号是系统占用的,不可以访问)
野指针
- 定义:指针变量指向非法的内存空间
空指针和野指针都不是我们申请的空间,不要轻易访问
const修饰指针
const修饰指针 —常量指针
const int * p = &a;
特点:指针的指向可以修改,但是指针指向的值不可以修改
const修饰常量 —指针常量
int * const p = &a;
特点:指针的指向不可以改,指针指向的值可以改
const同时修饰指针和常量
const int * const p = &a;
特点:指针的指向不可以改,指针指向的值不可以改
指针和数组的结合
int arr[105];
int * const p = arr;
*因为数组的首地址不会更改,所以指针应用const修饰
*不用const修饰,可以用来遍历数组。
**int * p = arr; // arr是数组的首地址
**p++; // 指针向后偏移四个字节
point (*p)[3];point是类名,p为定义指向对象数组的指针。
point *p[3];point是类名,p为对象指针数组 。
指针和函数的结合
值传递
函数形参会发生改变,但是实参并没有发生改变
void max(int a){
}
max(a);
地址传递
void max(int *p){
}
max(&a);
数组类型
- 数组大小
sizeof()
结构体类型
结构体变量的定义
- 只是一种数据类型,不占用内存空间;只有定义结构体变量时,才开辟内存空间。
- 将不同类型的数据有序地组合在一起,构成一个新的数据类型,称为结构体。
struct Student
{
int num;
char name[20];
char sex;
}s1,s2;
Student s3,s4; //可在之后声明添加.
--------------------
struct
{
int num;
char name[20];
char sex;
}s1,s2;//不可以在之后声明添加.
--------------------
struct Student
{
int num;
char name[20];
char sex;
Date birthday;
}s1;
struct Date
{
int month;
int day;
int year;
};
//赋值时
s1.birthday.day = 25;
*注意
**结构体成员名与程序变量名不冲突,如s1.name与局部变量name不冲突。
**不能对结构体变量整体输入和输出,只能分别使用各个成员。
***wrong cin>>s1; cout<<s1;
结构体变量的赋值
struct Student
{
int num;
char name[20];
char sex;
};
Student s1 = {123,"lihua",'M'}; //初始化
Student s2 = s1;
*注意
**s2 = s1;
***java
两者指向同一块地址,同时修改。
***c++
将s1复制给s2,两者之后的更改互不影响。
结构体数组
struct Student
{
int num;
char name[20];
char sex;
}stu[3] = {
{123,"lihua",'M'},
{123,"lihua",'M'},
{123,"lihua",'M'}
};
*每个数组元素都是一个结构体的值,在内存中连续存放。
结构体变量的指针
*指向运算符 ->
Student stu,*p;
p = &stu;
直接访问 | 间接访问 | 基于指向运算符的间接访问 |
---|---|---|
stu.name | p->name |
结构体变量传参给函数
*结构体变量名作为参数,将实参值传递给形参,一般较少使用这种方法
**时间和空间开销大,但要传入基本数据类型时,可以采用。
**结构体拷贝,效率不高。
void print (Student s){
cout<<s.name<<endl;
}
*指向结构体变量的指针作为实参,将结构体变量的地址传给形参。
**时间和空间开销小,效率高
//只有可读权限,同上。
void print (const Student *p){
cout<<p->name<<endl;
}
*用结构体变量的引用变量作为函数参数(推荐)
**高效
**安全
**可读性强
void print (const Student &s){
cout<<s.name<<endl;
}
自定义新类型
用typedef定义新类型
*typedef 已定义的类型 新的类型
typeof float real
real x,y;//等同于float x,y;
*作用:有利于程序的通用和移植。
//无论什么平台,real都表示最高精度小数。
#ifdef_win64
typedef long double real;
#else
typedef double real;
#endif
real r1,r2;
*typedef VS #define
**typedef float real:编译时处理,定义(复杂)数据类型。
**#define real float:预编译处理,所有real替换为float。
*复杂使用方法
typedef char STRING[81];
STRING s1;//char s1[81];
*应用
**图像,图形行业
double img1[1920][1080];
typedef double IMAGE[1920][1080];
IMAGE imag1;
进制
- Oct 八进制 写在数字左边cout<<oct<<25;
- Hex 十六进制
- 0+数字是八进制
- 0x+数字是十六进制
- 判断是否为十六进制,使用 isxdigit()
- 注意其返回的整数值,不同环境不一样,
奇怪!
常量
实型常量
C/C++中的实型常量必须符合一定的格式要求,包括小数点、指数符号等。如果不符合这些要求,就无法被编译器正确解析,因此是非法的实型常量。例如,以下几种实型常量都是非法的:
- “3…14”:有两个小数点,不符合实型常量的格式要求。
- “1.2E3.4”:有两个指数符号,不符合实型常量的格式要求。相当于12E-1E3.4。
- “0x1.2p3”:这是一个十六进制的实型常量,但是十六进制实型常量必须以小数点或指数符号开头,不符合格式要求。
因此,编程时应该注意实型常量的格式要求,避免出现非法的常量。
变量
局部变量
Main
True
String
string
printf
While
main
都可以用来命名
自增运算
++ ++x
自增两次++x++
会报错x++ ++
会报错(++x)++
自增两次
类型转换
整型转换为字符串
-
to_string(int)
-
static_cast < type-id > ( expression ) 强制类型转换
-
(type-id)( expression )
double(a) + b / 2 //注意运算顺序
*数字的字符串形式转化为二进制字符串形式输出
cpp
string strToBinary(string str) {
int num = stoi(str);//stoi将字符串转化为整数
string binary_str;//空字符串binary_str,用于存储最终的二进制结果
while (num > 0) {
int last_bit = num & 1;//num & 1 与运算得到num的最后一位
binary_str = to_string(last_bit) + binary_str;
num >>= 1;//将num右移一位
}
return binary_str;
}
int main() {
string binary = strToBinary("255");
cout << binary << endl; // 11111111
}
----------------------------------------------------------------
cpp
string hexToBinary(string hex) {
int num = stoi(hex, 0, 16);
int binary_len = 8; // 设置二进制字符串长度为8位
string binary;
while (num > 0 || binary.length() < binary_len) {
if (num > 0) {
int last_bit = num & 1;
binary = to_string(last_bit) + binary;
num >>= 1;
} else { // 若num已转化完,则给binary补零
binary = "0" + binary;
}
}
return binary;
}
int main() {
string binary = hexToBinary("FF");
cout << binary << endl; // 11111111
}
-----------------------------------------------------------------
cpp
cout << setfill('0') << setw(8) << hex << endl;
//另一种补零方式
语法正确
;;;//;;;//正确
{{{ }}}//正确
((()))//错误
for(;;);//正确
do;while(0)//错误
do while(0);//错误
do;while(0);//正确
int a = 1, *p = &a; cout << (a/*p);//错误
常识
- a -> 97 A -> 65
头文件
#include <bits/stdc++.h> 万能头文件
#include <iostream> 输入输出
#include <cstring>
-
memset(sum,0,sizeof(sum)); = int sum[10] = {0};
-
int arr[1005] = {0};
-
int arr[1005];//都可以
#include <string>
- S.at()获取单个字符
- s.length()获取字符串长度
- 判断字符串相等"=="
#include <algorithm>
- sort (起始地址, 末尾地址+1, cmp)
- swap 交换函数
- 可参考【C++】蓝桥杯必备 算法竞赛常用STL万字总结
#include <cmath>
- Sqrt()开平方根
- Pow( ,2)平方
- Abs()绝对值
#include <iomanip>
-
Setw() 指定显示字段的宽度(对其后面的一个起作用,每次都要设置)。默认右对齐setiosflags(ios:left)设置为左对齐
-
Setfill(‘字符’ )设置用于在右对齐显示中填充空格的字符。
-
cout<<fixed<<setprecision(2)<<输出保留两位小数
转义字符
\t
\t
对应空格次数并不是固定的,并不是我们认为的4个空格或者8个空格
令 num = |n-8|%8, 其中n表示\t前面的字符占的位置(前面的字符也可能是转换说明,如%d,%10d等)。
- 当\t前面为123456时,后面有两个空格
- 当\t前面为1234567时,后面有1个空格
- 而当前面正好为12345678时,后面跟8个空格
- 当前面为123456781234时,后面的空格数量为 |12-8|%8=4
错误总结
Dev C++
编译错误
- [[Error] ‘stoi’ was not declared in this scope]([(90条消息) [Error] ‘stoi’ was not declared in this scope_stoi函数用不了_疯狂理工~~的博客-CSDN博客](https://blog.csdn.net/android_mangren/article/details/84930764?ops_request_misc=%7B%22request%5Fid%22%3A%22168010198916800188571516%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=168010198916800188571516&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-84930764-null-null.142v77insert_down38,201v4add_ask,239v2insert_chatgpt&utm_term=[Error] stoi was not declared in this scope&spm=1018.2226.3001.4187))
疑惑
算法知识汇总
各种排序总结
选择排序
#include<iostream>
using namespace std;
void SelectSort(int A[],int n)
{
for(int i = 0;i < n;i++){
int index =i;
for(int j = i+1;j < n;j++){ //查找最大元素所在位置与index索引比较即可
if (A[j] > A[index])
index =j;
}
int temp = A[index]; //交换无序后列中首元素与最大元素的位置
A[index] = A[i];
A[i] = temp;
}
}
数据类型
整型
int(整型)
- Int8, 等于Byte, 占1个字节.
- Int16, 等于short, 占2个字节. -32768 32767
- Int32, 等于int, 占4个字节. -2147483648 2147483647
- Int64, 等于long, 占8个字节. -9223372036854775808 9223372036854775807
浮点型
浮点数
大小比较
- 小数比较大小要确定精度来进行(一般精确最少要到小数点后六位,更精确更好)
字符型
布尔型
string
#include <string>
find()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
//主要字符串是从0开始计数的
cout<<"ab在str中的位置:"<<str.find("ab")<<endl;
//返回第一次出现ab的位置,没有则返回一串乱码
cout<<"ab在str[2]到str[n-1]中的位置:"<<str.find("ab",2)<<endl;
//返回第一次从str[2]开始出现ab的位置,没有则返回一串乱码
cout<<"ab在str[0]到str[2]中的位置:"<<str.rfind("ab",2)<<endl;
//返回ab在str[0]到str[2]中的位置,没有则返回一串乱码
return 0;
}
输入1
sdefdwefdadabbababab
1
输出1
ab在str中的位置:11
ab在str[2]到str[n-1]中的位置:11
ab在str[0]到str[2]中的位置:18446744073709551615
Program ended with exit code: 0
输入2
abfeofihwabab
输出2
ab在str中的位置:0
ab在str[2]到str[n-1]中的位置:9
ab在str[0]到str[2]中的位置:0
Program ended with exit code: 0
输入3
asdfghjk
输出3
ab在str中的位置:18446744073709551615
ab在str[2]到str[n-1]中的位置:18446744073709551615
ab在str[0]到str[2]中的位置:18446744073709551615
Program ended with exit code: 0
substr()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"返回str[3]及其以后的子串:"<<str.substr(3)<<endl;
//若小于限制长度则报错
cout<<"从ste[2]开始由四个字符组成的子串:"<<str.substr(2,4)<<endl;
//若小于限制长度则报错
return 0;
}
输入1
asdfghjkl;'/.,mnbvcxz
输出1
返回str[3]及其以后的子串:fghjkl;'/.,mnbvcxz
从ste[2]开始由四个字符组成的子串:dfgh
Program ended with exit code: 0
replace()
示列1
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.find("@"), 1, ""); //从第一个@位置替换第一个@为空
cout<<line<<endl;
return 0;
}
输出
this is@ a test string!
Program ended with exit code: 0
示列2
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
line = line.replace(line.begin(), line.begin()+6, ""); //用str替换从begin位置开始的6个字符
cout << line << endl;
return 0;
}
示列3
#include <iostream>
#include <string>
using namespace std;
int main()
{
string line = "this@ is@ a test string!";
char* str = "12345";
line = line.replace(0, 5, str); //用str替换从指定位置0开始长度为5的字符串
cout << line << endl;
return 0;
}
输出
12345 is@ a test string!
Program ended with exit code: 0
insert()
#include <string>
#include <iostream>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"从2号位置插入字符串jkl并形成新的字符串返回:"<<str.insert(2, "jkl")<<endl;//会返回一个新的字符串,需要接收.
return 0;
}
输入
sdfgh
输出
从2号位置插入字符串jkl并形成新的字符串返回:sdjklfgh
Program ended with exit code: 0
append()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str;
cin>>str;
cout<<"在字符串str后面添加字符串ABC:"<<str.append("ABC")<<endl;
return 0;
}
输入
diguwhdcow
1
输出
在字符串str后面添加字符串ABC:diguwhdcowABC
Program ended with exit code: 0
swap()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1,str2;
cin>>str1>>str2;
cout<<"str1:"<<str1<<endl;
cout<<"str2:"<<str2<<endl;
swap(str1, str2);
cout<<"str1:"<<str1<<endl;
cout<<"str2:"<<str2<<endl;
}
输入
qwertyui
asdfghjk
输出
str1:qwertyui
str2:asdfghjk
str1:asdfghjk
str2:qwertyui
Program ended with exit code: 0
compare()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1,str2;
cin>>str1>>str2;
cout<<str1.compare(str2)<<endl;
return 0;
}
输入
diwguc
aschsdnv
输出
3
Program ended with exit code: 0
size()和length()
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1;
cin>>str1;
cout<<str1.size()<<endl;
cout<<str1.length()<<endl;
return 0;
}
输入
dchiascnsc
输出
10
10
Program ended with exit code: 0
#include< string.h >
strcpy(s1,s2)
复制字符串s2到s1
strcat(s1,s2)
连接s2到s1的末尾
strlen(s1)
返回字符串s1的长度
strcmp(s1,s2)
若s1和s2是相同的,则返回0,s1< s2,返回值小于0,若s1>s2,返回值大于0
strchr(s1,ch)
返回一个指针,指向字符串s1中字符ch第一次出现的位置
strstr(s1,s2)
返回一个指针,指向字符串s1中字符串s2的第一次出现位置
memcpy (void *dest, const void *src, int size)
从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
strcpy与memcpy的区别:
- 复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
- 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
- 用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
指针类型
引用
引用的定义
*对变量起另外一个名字(别名),这个名字就成为该变量的引用。
int a;
int &ref_a = a;
**ref_a并没有在内存中开辟单元,只是引用a的单元。
**地址相同,但有两个名字。
*引用在被定义时,必须要初始化
*引用只能被定义一次,不可改成其他变量的引用。(唯一)
*常数值对应的引用必须是常引用
const double &rPI = 3.14;
引用和指针的区别
- 指针通过地址间接访问变量;引用通过别名直接访问变量。
- 存储指针需要额外的内存空间。
- 引用一旦被初始化,不会再作为其他变量的别名。
引用用作函数实参
//具有读写权限,而不是副本/拷贝,只可读。
//实参是变量而不是地址
void swap(int &x, int &y){
}
*常量引用
const int &x;//防止通过引用修改数值。
引用用作函数返回值
****warning****
int& m4(int x){
int &y = x;
return y;
}
指针的作用/用途
指针可以保存一个地址
指针的定义
-
数据类型 * 指针变量名
int * p;
-
让指针记录变量的地址
p = &a;
-
解引用
*p = 123213; //修改指向地址的数值
指针的内存空间
- 在32位操作系统下,占4个字节
- 在64位操作系统下,占8个字节
指针类型的分类
空指针
- 定义:指针变量指向内存中编号为0的空间
- 用途:初始化指针变量
- 注意:空指针指向的内存不可以访问(0~255之间的内存编号是系统占用的,不可以访问)
野指针
- 定义:指针变量指向非法的内存空间
空指针和野指针都不是我们申请的空间,不要轻易访问
const修饰指针
const修饰指针 —常量指针
const int * p = &a;
特点:指针的指向可以修改,但是指针指向的值不可以修改
const修饰常量 —指针常量
int * const p = &a;
特点:指针的指向不可以改,指针指向的值可以改
const同时修饰指针和常量
const int * const p = &a;
特点:指针的指向不可以改,指针指向的值不可以改
指针和数组的结合
int arr[105];
int * const p = arr;
*因为数组的首地址不会更改,所以指针应用const修饰
*不用const修饰,可以用来遍历数组。
**int * p = arr; // arr是数组的首地址
**p++; // 指针向后偏移四个字节
point (*p)[3];point是类名,p为定义指向对象数组的指针。
point *p[3];point是类名,p为对象指针数组 。
指针和函数的结合
值传递
函数形参会发生改变,但是实参并没有发生改变
void max(int a){
}
max(a);
地址传递
void max(int *p){
}
max(&a);
数组类型
- 数组大小
sizeof()
结构体类型
结构体变量的定义
- 只是一种数据类型,不占用内存空间;只有定义结构体变量时,才开辟内存空间。
- 将不同类型的数据有序地组合在一起,构成一个新的数据类型,称为结构体。
struct Student
{
int num;
char name[20];
char sex;
}s1,s2;
Student s3,s4; //可在之后声明添加.
--------------------
struct
{
int num;
char name[20];
char sex;
}s1,s2;//不可以在之后声明添加.
--------------------
struct Student
{
int num;
char name[20];
char sex;
Date birthday;
}s1;
struct Date
{
int month;
int day;
int year;
};
//赋值时
s1.birthday.day = 25;
*注意
**结构体成员名与程序变量名不冲突,如s1.name与局部变量name不冲突。
**不能对结构体变量整体输入和输出,只能分别使用各个成员。
***wrong cin>>s1; cout<<s1;
结构体变量的赋值
struct Student
{
int num;
char name[20];
char sex;
};
Student s1 = {123,"lihua",'M'}; //初始化
Student s2 = s1;
*注意
**s2 = s1;
***java
两者指向同一块地址,同时修改。
***c++
将s1复制给s2,两者之后的更改互不影响。
结构体数组
struct Student
{
int num;
char name[20];
char sex;
}stu[3] = {
{123,"lihua",'M'},
{123,"lihua",'M'},
{123,"lihua",'M'}
};
*每个数组元素都是一个结构体的值,在内存中连续存放。
结构体变量的指针
*指向运算符 ->
Student stu,*p;
p = &stu;
直接访问 | 间接访问 | 基于指向运算符的间接访问 |
---|---|---|
stu.name | p->name |
结构体变量传参给函数
*结构体变量名作为参数,将实参值传递给形参,一般较少使用这种方法
**时间和空间开销大,但要传入基本数据类型时,可以采用。
**结构体拷贝,效率不高。
void print (Student s){
cout<<s.name<<endl;
}
*指向结构体变量的指针作为实参,将结构体变量的地址传给形参。
**时间和空间开销小,效率高
//只有可读权限,同上。
void print (const Student *p){
cout<<p->name<<endl;
}
*用结构体变量的引用变量作为函数参数(推荐)
**高效
**安全
**可读性强
void print (const Student &s){
cout<<s.name<<endl;
}
自定义新类型
用typedef定义新类型
*typedef 已定义的类型 新的类型
typeof float real
real x,y;//等同于float x,y;
*作用:有利于程序的通用和移植。
//无论什么平台,real都表示最高精度小数。
#ifdef_win64
typedef long double real;
#else
typedef double real;
#endif
real r1,r2;
*typedef VS #define
**typedef float real:编译时处理,定义(复杂)数据类型。
**#define real float:预编译处理,所有real替换为float。
*复杂使用方法
typedef char STRING[81];
STRING s1;//char s1[81];
*应用
**图像,图形行业
double img1[1920][1080];
typedef double IMAGE[1920][1080];
IMAGE imag1;
进制
- Oct 八进制 写在数字左边cout<<oct<<25;
- Hex 十六进制
- 0+数字是八进制
- 0x+数字是十六进制
- 判断是否为十六进制,使用 isxdigit()
- 注意其返回的整数值,不同环境不一样,
奇怪!
常量
实型常量
C/C++中的实型常量必须符合一定的格式要求,包括小数点、指数符号等。如果不符合这些要求,就无法被编译器正确解析,因此是非法的实型常量。例如,以下几种实型常量都是非法的:
- “3…14”:有两个小数点,不符合实型常量的格式要求。
- “1.2E3.4”:有两个指数符号,不符合实型常量的格式要求。相当于12E-1E3.4。
- “0x1.2p3”:这是一个十六进制的实型常量,但是十六进制实型常量必须以小数点或指数符号开头,不符合格式要求。
因此,编程时应该注意实型常量的格式要求,避免出现非法的常量。
变量
局部变量
Main
True
String
string
printf
While
main
都可以用来命名
自增运算
++ ++x
自增两次++x++
会报错x++ ++
会报错(++x)++
自增两次
类型转换
整型转换为字符串
-
to_string(int)
-
static_cast < type-id > ( expression ) 强制类型转换
-
(type-id)( expression )
double(a) + b / 2 //注意运算顺序
*数字的字符串形式转化为二进制字符串形式输出
cpp
string strToBinary(string str) {
int num = stoi(str);//stoi将字符串转化为整数
string binary_str;//空字符串binary_str,用于存储最终的二进制结果
while (num > 0) {
int last_bit = num & 1;//num & 1 与运算得到num的最后一位
binary_str = to_string(last_bit) + binary_str;
num >>= 1;//将num右移一位
}
return binary_str;
}
int main() {
string binary = strToBinary("255");
cout << binary << endl; // 11111111
}
----------------------------------------------------------------
cpp
string hexToBinary(string hex) {
int num = stoi(hex, 0, 16);
int binary_len = 8; // 设置二进制字符串长度为8位
string binary;
while (num > 0 || binary.length() < binary_len) {
if (num > 0) {
int last_bit = num & 1;
binary = to_string(last_bit) + binary;
num >>= 1;
} else { // 若num已转化完,则给binary补零
binary = "0" + binary;
}
}
return binary;
}
int main() {
string binary = hexToBinary("FF");
cout << binary << endl; // 11111111
}
-----------------------------------------------------------------
cpp
cout << setfill('0') << setw(8) << hex << endl;
//另一种补零方式
语法正确
;;;//;;;//正确
{{{ }}}//正确
((()))//错误
for(;;);//正确
do;while(0)//错误
do while(0);//错误
do;while(0);//正确
int a = 1, *p = &a; cout << (a/*p);//错误
常识
- a -> 97 A -> 65
头文件
#include <bits/stdc++.h> 万能头文件
#include <iostream> 输入输出
#include <cstring>
-
memset(sum,0,sizeof(sum)); = int sum[10] = {0};
-
int arr[1005] = {0};
-
int arr[1005];//都可以
#include <string>
- S.at()获取单个字符
- s.length()获取字符串长度
- 判断字符串相等"=="
#include <algorithm>
- sort (起始地址, 末尾地址+1, cmp)
- swap 交换函数
- 可参考【C++】蓝桥杯必备 算法竞赛常用STL万字总结
#include <cmath>
- Sqrt()开平方根
- Pow( ,2)平方
- Abs()绝对值
#include <iomanip>
-
Setw() 指定显示字段的宽度(对其后面的一个起作用,每次都要设置)。默认右对齐setiosflags(ios:left)设置为左对齐
-
Setfill(‘字符’ )设置用于在右对齐显示中填充空格的字符。
-
cout<<fixed<<setprecision(2)<<输出保留两位小数
转义字符
\t
\t
对应空格次数并不是固定的,并不是我们认为的4个空格或者8个空格
令 num = |n-8|%8, 其中n表示\t前面的字符占的位置(前面的字符也可能是转换说明,如%d,%10d等)。
- 当\t前面为123456时,后面有两个空格
- 当\t前面为1234567时,后面有1个空格
- 而当前面正好为12345678时,后面跟8个空格
- 当前面为123456781234时,后面的空格数量为 |12-8|%8=4
错误总结
Dev C++
编译错误
- [[Error] ‘stoi’ was not declared in this scope]([(90条消息) [Error] ‘stoi’ was not declared in this scope_stoi函数用不了_疯狂理工~~的博客-CSDN博客](https://blog.csdn.net/android_mangren/article/details/84930764?ops_request_misc=%7B%22request%5Fid%22%3A%22168010198916800188571516%22%2C%22scm%22%3A%2220140713.130102334…%22%7D&request_id=168010198916800188571516&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduend~default-1-84930764-null-null.142v77insert_down38,201v4add_ask,239v2insert_chatgpt&utm_term=[Error] stoi was not declared in this scope&spm=1018.2226.3001.4187))
疑惑
算法知识汇总
各种排序总结
选择排序
#include<iostream>
using namespace std;
void SelectSort(int A[],int n)
{
for(int i = 0;i < n;i++){
int index =i;
for(int j = i+1;j < n;j++){ //查找最大元素所在位置与index索引比较即可
if (A[j] > A[index])
index =j;
}
int temp = A[index]; //交换无序后列中首元素与最大元素的位置
A[index] = A[i];
A[i] = temp;
}
}