C++知识点

数据类型

整型

int(整型)

  1. Int8, 等于Byte, 占1个字节.
  2. Int16, 等于short, 占2个字节. -32768 32767
  3. Int32, 等于int, 占4个字节. -2147483648 2147483647
  4. Int64, 等于long, 占8个字节. -9223372036854775808 9223372036854775807

浮点型

浮点数

大小比较
  1. 小数比较大小要确定精度来进行(一般精确最少要到小数点后六位,更精确更好)

字符型

布尔型

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的区别:

  1. 复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
  2. 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
  3. 用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

指针类型

引用

引用的定义
*对变量起另外一个名字(别名),这个名字就成为该变量的引用。
    int a;
    int &ref_a = a;
    **ref_a并没有在内存中开辟单元,只是引用a的单元。
    **地址相同,但有两个名字。
*引用在被定义时,必须要初始化
*引用只能被定义一次,不可改成其他变量的引用。(唯一)
*常数值对应的引用必须是常引用
        const double &rPI = 3.14;
引用和指针的区别
  1. 指针通过地址间接访问变量;引用通过别名直接访问变量。
  2. 存储指针需要额外的内存空间。
  3. 引用一旦被初始化,不会再作为其他变量的别名。
引用用作函数实参
//具有读写权限,而不是副本/拷贝,只可读。
//实参是变量而不是地址
void swap(int &x, int &y){
    
}
*常量引用
    const int &x;//防止通过引用修改数值。
引用用作函数返回值
****warning****
int& m4(int x){
    int &y = x;
    return y;
}

指针的作用/用途

  1. 指针可以保存一个地址

指针的定义

  1. 数据类型 * 指针变量名

    int * p;

  2. 让指针记录变量的地址

    p = &a;

  3. 解引用

    *p = 123213; //修改指向地址的数值

指针的内存空间

  1. 在32位操作系统下,占4个字节
  2. 在64位操作系统下,占8个字节

指针类型的分类

空指针
  1. 定义:指针变量指向内存中编号为0的空间
  2. 用途:初始化指针变量
  3. 注意:空指针指向的内存不可以访问(0~255之间的内存编号是系统占用的,不可以访问)
野指针
  1. 定义:指针变量指向非法的内存空间

空指针和野指针都不是我们申请的空间,不要轻易访问

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);

数组类型

  1. 数组大小 sizeof()

结构体类型

结构体变量的定义

  1. 只是一种数据类型,不占用内存空间;只有定义结构体变量时,才开辟内存空间。
  2. 将不同类型的数据有序地组合在一起,构成一个新的数据类型,称为结构体。
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).namep->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;

进制

  1. Oct 八进制 写在数字左边cout<<oct<<25;
  2. Hex 十六进制
  3. 0+数字是八进制
  4. 0x+数字是十六进制
    • 判断是否为十六进制,使用 isxdigit()
    • 注意其返回的整数值,不同环境不一样,奇怪!

常量

实型常量

C/C++中的实型常量必须符合一定的格式要求,包括小数点、指数符号等。如果不符合这些要求,就无法被编译器正确解析,因此是非法的实型常量。例如,以下几种实型常量都是非法的:

  • “3…14”:有两个小数点,不符合实型常量的格式要求。
  • “1.2E3.4”:有两个指数符号,不符合实型常量的格式要求。相当于12E-1E3.4。
  • “0x1.2p3”:这是一个十六进制的实型常量,但是十六进制实型常量必须以小数点或指数符号开头,不符合格式要求。

因此,编程时应该注意实型常量的格式要求,避免出现非法的常量。

变量

局部变量

Main True String string printf While main 都可以用来命名

自增运算

  1. ++ ++x自增两次
  2. ++x++会报错
  3. x++ ++会报错
  4. (++x)++自增两次

类型转换

整型转换为字符串

  1. to_string(int)

  2. static_cast < type-id > ( expression ) 强制类型转换

  3. (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);//错误

常识

  1. 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>

cstring和string的区别

  • S.at()获取单个字符
  • s.length()获取字符串长度
  • 判断字符串相等"=="

#include <algorithm>

#include <cmath>

#include <iomanip>

  • Setw() 指定显示字段的宽度(对其后面的一个起作用,每次都要设置)。默认右对齐setiosflags(ios:left)设置为左对齐

  • Setfill(‘字符’ )设置用于在右对齐显示中填充空格的字符。

  • cout<<fixed<<setprecision(2)<<输出保留两位小数

转义字符

\t

\t 对应空格次数并不是固定的,并不是我们认为的4个空格或者8个空格

令 num = |n-8|%8, 其中n表示\t前面的字符占的位置(前面的字符也可能是转换说明,如%d,%10d等)。

  1. 当\t前面为123456时,后面有两个空格
  2. 当\t前面为1234567时,后面有1个空格
  3. 而当前面正好为12345678时,后面跟8个空格
  4. 当前面为123456781234时,后面的空格数量为 |12-8|%8=4

错误总结

Dev C++

编译错误

  1. [[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))

疑惑

  1. 函数中传入数组后,运用sizeof(arr)/sizeof(arr[0])得到的数值与main函数内的不相等.
  2. union

算法知识汇总

各种排序总结

选择排序

#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(整型)

  1. Int8, 等于Byte, 占1个字节.
  2. Int16, 等于short, 占2个字节. -32768 32767
  3. Int32, 等于int, 占4个字节. -2147483648 2147483647
  4. Int64, 等于long, 占8个字节. -9223372036854775808 9223372036854775807

浮点型

浮点数

大小比较
  1. 小数比较大小要确定精度来进行(一般精确最少要到小数点后六位,更精确更好)

字符型

布尔型

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的区别:

  1. 复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
  2. 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
  3. 用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy

指针类型

引用

引用的定义
*对变量起另外一个名字(别名),这个名字就成为该变量的引用。
    int a;
    int &ref_a = a;
    **ref_a并没有在内存中开辟单元,只是引用a的单元。
    **地址相同,但有两个名字。
*引用在被定义时,必须要初始化
*引用只能被定义一次,不可改成其他变量的引用。(唯一)
*常数值对应的引用必须是常引用
        const double &rPI = 3.14;
引用和指针的区别
  1. 指针通过地址间接访问变量;引用通过别名直接访问变量。
  2. 存储指针需要额外的内存空间。
  3. 引用一旦被初始化,不会再作为其他变量的别名。
引用用作函数实参
//具有读写权限,而不是副本/拷贝,只可读。
//实参是变量而不是地址
void swap(int &x, int &y){
    
}
*常量引用
    const int &x;//防止通过引用修改数值。
引用用作函数返回值
****warning****
int& m4(int x){
    int &y = x;
    return y;
}

指针的作用/用途

  1. 指针可以保存一个地址

指针的定义

  1. 数据类型 * 指针变量名

    int * p;

  2. 让指针记录变量的地址

    p = &a;

  3. 解引用

    *p = 123213; //修改指向地址的数值

指针的内存空间

  1. 在32位操作系统下,占4个字节
  2. 在64位操作系统下,占8个字节

指针类型的分类

空指针
  1. 定义:指针变量指向内存中编号为0的空间
  2. 用途:初始化指针变量
  3. 注意:空指针指向的内存不可以访问(0~255之间的内存编号是系统占用的,不可以访问)
野指针
  1. 定义:指针变量指向非法的内存空间

空指针和野指针都不是我们申请的空间,不要轻易访问

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);

数组类型

  1. 数组大小 sizeof()

结构体类型

结构体变量的定义

  1. 只是一种数据类型,不占用内存空间;只有定义结构体变量时,才开辟内存空间。
  2. 将不同类型的数据有序地组合在一起,构成一个新的数据类型,称为结构体。
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).namep->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;

进制

  1. Oct 八进制 写在数字左边cout<<oct<<25;
  2. Hex 十六进制
  3. 0+数字是八进制
  4. 0x+数字是十六进制
    • 判断是否为十六进制,使用 isxdigit()
    • 注意其返回的整数值,不同环境不一样,奇怪!

常量

实型常量

C/C++中的实型常量必须符合一定的格式要求,包括小数点、指数符号等。如果不符合这些要求,就无法被编译器正确解析,因此是非法的实型常量。例如,以下几种实型常量都是非法的:

  • “3…14”:有两个小数点,不符合实型常量的格式要求。
  • “1.2E3.4”:有两个指数符号,不符合实型常量的格式要求。相当于12E-1E3.4。
  • “0x1.2p3”:这是一个十六进制的实型常量,但是十六进制实型常量必须以小数点或指数符号开头,不符合格式要求。

因此,编程时应该注意实型常量的格式要求,避免出现非法的常量。

变量

局部变量

Main True String string printf While main 都可以用来命名

自增运算

  1. ++ ++x自增两次
  2. ++x++会报错
  3. x++ ++会报错
  4. (++x)++自增两次

类型转换

整型转换为字符串

  1. to_string(int)

  2. static_cast < type-id > ( expression ) 强制类型转换

  3. (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);//错误

常识

  1. 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>

cstring和string的区别

  • S.at()获取单个字符
  • s.length()获取字符串长度
  • 判断字符串相等"=="

#include <algorithm>

#include <cmath>

#include <iomanip>

  • Setw() 指定显示字段的宽度(对其后面的一个起作用,每次都要设置)。默认右对齐setiosflags(ios:left)设置为左对齐

  • Setfill(‘字符’ )设置用于在右对齐显示中填充空格的字符。

  • cout<<fixed<<setprecision(2)<<输出保留两位小数

转义字符

\t

\t 对应空格次数并不是固定的,并不是我们认为的4个空格或者8个空格

令 num = |n-8|%8, 其中n表示\t前面的字符占的位置(前面的字符也可能是转换说明,如%d,%10d等)。

  1. 当\t前面为123456时,后面有两个空格
  2. 当\t前面为1234567时,后面有1个空格
  3. 而当前面正好为12345678时,后面跟8个空格
  4. 当前面为123456781234时,后面的空格数量为 |12-8|%8=4

错误总结

Dev C++

编译错误

  1. [[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))

疑惑

  1. 函数中传入数组后,运用sizeof(arr)/sizeof(arr[0])得到的数值与main函数内的不相等.
  2. union

算法知识汇总

各种排序总结

选择排序

#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;
	}
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值