c++相关知识点(持续更新中~)

文章介绍了如何生成随机数并防止重复,水仙花数的概念及其判断算法,冒泡排序的实现,以及C++中分文件编写程序的方法,包括头文件、主文件和源文件的使用。此外,还提到了指针常量的三种形式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

添加随机数种子:

//通过利用当前时间生成随机数,防止每次随机数一样
srand((unsigned int)time(0));
int num=rand()%100+1;//生成1-100的值
//例如:如果需要生成30-200的值 那么% 171之后是0-170 之后再+1 为1-171范围 再+29 为30-200   
//以此往前推即可
cout << num <<endl;

水仙花数:

简述:一个三位数,将其个位数、十位数、百位数拆解后各自立方之和等于这个三位数。

例如:2x2x2+7x7x7+0x0x0=270

程序逻辑:

1、输入三位数

int data;
cout<<"输入三位数: "<<endl;
cin>data;//输入的三位数值

2、使用do{}while()循环

循环解释:先执行一遍程序段之后进入循环判断

程序段:

do {
    	//拆解出个位数、十位数、百位数
		unit = num % 10;   //个位数
		decade = num / 10 % 10; //十位数
		hundreds = num / 100; // 百位数
		 cout << "hundreds: " << hundreds << "\tdecade: " << decade << "\tunit: " << unit << endl;
    //各自立方和
		data = unit * unit * unit + decade * decade * decade + hundreds * hundreds * hundreds;
	//判断是否等于本身,如果是本身则输入该值时水仙花数。	
    if (data == num) {
			cout << "水仙花数为:" << num << endl;
		}
		num++;
	} while (num < 1000);

冒泡排序:

**注释:**第一个遍历,按顺序指定数据,将第一个遍历的数据和后面的数据依次比较,从小到大(前一个数据如果大于后面的数据进行替换),从大到小反之。

int arr[9] = { 4,2,8,0,5,7,1,3,9 };
int temp;

for (int i = 0; i < 9 - 1; i++) {
    for (int j = i + 1; j < 9; j++) {
        if (arr[i] > arr[j]) {
            temp = arr[j];
            arr[j] = arr[i];
            arr[i] = temp;
        }
        else {
            continue;
        }
    }
}
for (int i = 0; i < 9; i++) {
    cout << arr[i] << endl;
}

分文件写法:

主文件:

导入

#include "子文件.h" 

swap(1,2);

子文件.cpp:

cpp文件内部写函数的内容

#include "子文件.h"

void swap(int a,int b){
    return a + b;
}

子文件.h:

定义函数

#pragma once
#include <iostream>
using namespace std;

void swap(int a,int b);

注意:.h文件头部的#pragm once必须要写,用来区分

扩展:

引用的区别

<文件>:内部的库使用

“文件”:自己写的库

空指针和野指针:

**空指针:**对指针一开始赋值为NULL

**野指针:**并未对指针赋初始值

这两指针最好不要出现在程序内部

const修饰对象区别:

指针常量:

修饰常量

指针的指向不可以修改,指针指向的值可以修改

int * const p = &a;

常量指针:

修饰指针

指针的指向可以修改,指针指向的值不可以修改

const int * p = &a;

第三种:

既修饰指针又修饰常量

const int * const p = &a;

浮点精度设置

std::setprecision(n) //n:打印长度

布尔类型0/1->true/false

std::cout << std::boolalpha; // 以  true , false 格式打印bool
std::cin >> std::boolalpha;// 允许用户输入 'true' or 'false' 作为bool变量的值

转义字符

名称符号含义
告警(Alert)\a发出告警,例如响铃
退格(Backspace)\b将光标往后移一格
换页(Formfeed)\f将光标移动到下一页
换行(Newline)\n将光标移动到下一行
回车(Carriage return)\r将光标移动到行的开头
水平制表(Horizontal tab)\t水平制表符
垂直制表(Vertical tab)\v垂直制表符
单引号(Single quote)\’单引号
双引号(Double quote)"双引号
反斜杠(Backslash)\反斜杠
问号(Question mark)?问号
八进制数字(Octal number)(number)按八进制解释为数字
十六进制数字(Hex number)\x(number)按十六进制解释为数字

static_cast操作符

static_cast<新类型>(表达式)

例子:

#include <iostream>

void print(int x)
{
	std::cout << x << '\n';
}

int main()
{
	print( static_cast<int>(5.5) ); // 显示的将 double 值 5.5 转换为 int

	return 0;
}

常量-优化程序

const修饰常量之后数据不可修改。

如何区分时编译时常量还是运行时常量?

constexpr关键词进行修饰,且是能修饰编译时常量,如果修饰的是运行时常量则会报错。但constexpr修饰的函数可以传入 1、没被constexpr修饰的常量。不过会成为运行时求值。2、数值(例如1、2、3…),则有可能是编译时求值,也可能是运行时求值。

关键字consteval,用于指示函数必须在编译时求值,否则将导致编译错误。这种函数称为即时函数(immediate functions)

#include <iostream>

consteval int greater(int x, int y) // function 现在是 consteval
{
    return (x > y ? x : y);
}

int main()
{
    constexpr int g { greater(5, 6) };              // ok: 在编译时求值
    std::cout << g << '\n';

    std::cout << greater(5, 6) << " is greater!\n"; // ok: 在编译时求值

    int x{ 5 }; // not constexpr
    std::cout << greater(x, 6) << " is greater!\n"; // error: consteval 函数必须在编译时求值

    return 0;
}

字面值常量

类别后缀类型
integralu or Uunsigned int
integrall or Llong
integralul, uL, Ul, UL, lu, lU, Lu, LUunsigned long
integralll or LLlong long
integralull, uLL, Ull, ULL, llu, llU, LLu, LLUunsigned long long
integralz or ZThe signed version of std::size_t (C++23)
integraluz, uZ, Uz, UZ, zu, zU, Zu, ZUstd::size_t (C++23)
floating pointf or Ffloat
floating pointl or Llong double
stringsstd::string
stringsvstd::string_view
float f { 4.1 }; // warning: 4.1 is a double literal, not a float literal
//默认带小数的数值是double类型,需要后缀4.1f

以十进制、八进制或十六进制输出值

#include <iostream>

int main()
{
    int x { 12 };
    std::cout << x << '\n'; // 十进制 (默认)
    std::cout << std::hex << x << '\n'; // 16进制
    std::cout << x << '\n'; // 现在是16进制
    std::cout << std::oct << x << '\n'; // 八进制
    std::cout << std::dec << x << '\n'; // 重新设置回十进制
    std::cout << x << '\n'; // 十进制

    return 0;
}
//输出
12
c
c
14
12
12

输出二进制值

#include <bitset> // 引入 std::bitset
#include <iostream>

int main()
{
	// std::bitset<8> 意味着要存储 8 个 bit
	std::bitset<8> bin1{ 0b1100'0101 }; // 二进制的 1100 0101
	std::bitset<8> bin2{ 0xC5 }; // 十六进制的 1100 0101

	std::cout << bin1 << '\n' << bin2 << '\n';
	std::cout << std::bitset<4>{ 0b1010 } << '\n'; // 创建一个临时的bitset并打印

	return 0;
}
//输出
11000101
11000101
1010

在C++20和C++23中,通过新的格式库(C++20)和打印库(C++23),我们有更好的选项:

#include <format> // C++20
#include <iostream>
#include <print> // C++23

int main()
{
    std::cout << std::format("{:b}\n", 0b1010); // C++20
    std::cout << std::format("{:#b}\n", 0b1010); // C++20

    std::print("{:b} {:#b}\n", 0b1010, 0b1010); // C++23

    return 0;
}
//输出
1010
0b1010
1010 0b1010

string库简介

序号函数名称
1std::string
2std::getline()

std::string

#include <iostream>
#include <string>

int main()
{
    std::cout << "Enter your full name: ";
    std::string name{};
    std::cin >> name; // 可能不一定按预期工作,因为std::cin读取到 空白字符,就会停止

    std::cout << "Enter your favorite color: ";
    std::string color{};
    std::cin >> color;

    std::cout << "Your name is " << name << " and your favorite color is " << color << '\n';

    return 0;
}

std::getline() 另一种方式输入字符串

#include <iostream>
#include <string> // 引入 std::string 和 std::getline

int main()
{
    std::cout << "Enter your full name: ";
    std::string name{};
    std::getline(std::cin >> std::ws, name); // 将一整行输入读取到 name

    std::cout << "Enter your favorite color: ";
    std::string color{};
    std::getline(std::cin >> std::ws, color); // 将一整行输入读取到 color

    std::cout << "Your name is " << name << " and your favorite color is " << color << '\n';

    return 0;
}

那么为什么会使用std::ws呢?

如果我们先cin然后再getline,那么会导致cin之后直接跳出,从而不会接受到getline的字符串。因此使用std::ws输入操纵器,告诉std::getline()忽略任何前导空格字符。

针对如何得到有多少个字符串

#include <iostream>
#include <string>

int main()
{
    std::string name{ "Alex" };
    std::cout << name << " has " << name.length() << " characters\n";

    return 0;
}
#include <iostream>
#include <string>

int main()
{
    std::string name{ "Alex" };
    std::cout << name << " has " << std::ssize(name) << " characters\n";

    return 0;
}

如果说你要将得到的字符串数量值传给int值,最好使用static_cast转化为int类型数值

int length { static_cast<int>(name.length()) };

为了节省运行时的资源,当把string初始化的值传到函数内部,会导致大量的资源消耗,因此可以利用std::string_view进行初始化数据,这样可以让数据变成只读数据,无法更改,因此只能用于不需要更改数据的场合。

#include <iostream>
#include <string_view>

// str 提供了传入参数的只读访问能力
void printSV(std::string_view str) // str现在是 std::string_view
{
    std::cout << str << '\n';
}

int main()
{
    std::string_view s{ "Hello, world!" }; // s现在是 std::string_view
    printSV(s);

    return 0;
}

注意:

1、string可以转换为string_view,但string_view不可以隐式转换为string

2、使用static_cast做显式转换

std::string_view更像是一个视图,我们可以通过限制查看的范围去左侧、右侧进行遮挡,从而删除字符

  1. remove_prefix() 成员函数从视图的左侧删除字符。
  2. remove_suffix() 成员函数从视图的右侧删除字符。
#include <iostream>
#include <string_view>

int main()
{
	std::string_view str{ "Peach" };
	std::cout << str << '\n';

	// 从视图左侧移除一个字符
	str.remove_prefix(1);
	std::cout << str << '\n';

	// 从视图右侧移除一个字符
	str.remove_suffix(2);
	std::cout << str << '\n';

	str = "Peach"; // 重置视图
	std::cout << str << '\n';

	return 0;
}
//输出
Peach
each
ea
Peach

运算符优先级和结合性表

优先级/结合性运算符描述模式
1 L->R::全局命名空间(一元)::name
::命名空间(二元)class_name::member_name
2 L->R()括号(expression)
()函数调用function_name(parameters)
()初始化type name(expression)
{}列表初始化type name{expression}
type()类型转换new_type(expression)
type{}类型转换new_type{expression}
[]数组下标取值pointer[expression]
.取对象成员object.member_name
->取对象指针的成员object_pointer->member_name
++后自增lvalue++
––后自减lvalue––
typeid运行时类型信息typeid(type) or typeid(expression)
const_cast去掉类型的const限定const_cast(expression)
dynamic_cast运行时类型转换dynamic_cast(expression)
reinterpret_cast强制类型转换reinterpret_cast(expression)
static_cast编译时类型转换static_cast(expression)
sizeof…获取模板打包的参数个数sizeof…(expression)
noexcept编译时异常检查noexcept(expression)
alignof获取类型对齐方式alignof(type)
3 R->L+一元加+expression
-一元减-expression
++前自增++lvalue
前自减––lvalue
!逻辑非!expression
not逻辑非not expression
~按位取反~expression
(type)c样式类型转换(new_type)expression
sizeof求字节大小sizeof(type) or sizeof(expression)
co_await异步Await调用co_await expression (C++20)
&取对象地址&lvalue
*解引用*expression
new动态内存分配new type
new[]动态数组内存分配new type[expression]
delete动态内存回收delete pointer
delete[]动态数组内存回收delete[] pointer
4 L->R->*成员指针访问object_pointer->*pointer_to_member
.*成员对象访问object.*pointer_to_member
5 L->R*expression * expression
/expression / expression
%余数expression % expression
6 L->R+expression + expression
-expression - expression
7 L->R«按位左移/插入expression « expression
»按位右移/提取expression » expression
8 L->R<=>三向比较expression <=> expression
9 L->R<小于比较expression < expression
<=小于等于比较expression <= expression
>大于比较expression > expression
>=大于等于比较expression >= expression
10 L->R==相等比较expression == expression
!=不相等比较expression != expression
11 L->R&按位 Andexpression & expression
12 L->R^按位 XORexpression ^ expression
13 L->R|按位 ORexpression | expression
14 L->R&&逻辑 ANDexpression && expression
and逻辑 ANDexpression and expression
15 L->R||逻辑 ORexpression || expression
or逻辑 ORexpression or expression
16 R->Lthrow抛出异常throw expression
co_yieldYield 表达式 (C++20)co_yield expression
?:条件表达式expression ? expression : expression
=赋值lvalue = expression
*=乘赋值lvalue *= expression
/=除赋值lvalue /= expression
%=余数赋值lvalue %= expression
+=加赋值lvalue += expression
-=减赋值lvalue -= expression
«=按位左移赋值lvalue «= expression
»=按位右移赋值lvalue »= expression
&=按位And赋值lvalue &= expression
|=按位Or赋值lvalue |= expression
^=按位Xor赋值lvalue ^= expression
17 L->R,逗号运算符expression, expression
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跨界科技汇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值