数组、字符串和指针

数组

数组就是一组名为数组元素或简称元素的内存位置,各个内存位置可以存储相同数据类型的数据项,我们可以用相同的变量名引用所有的内存位置。

存储各个元素所需的内存量取决于元素的类型,数组的所有元素都存储在连续的内存区域中。

声明数组

type arrayName[size];

数组声明时,在紧随数组名的方括号内指出数组元素的数量。

初始化数组

type arrayName[size]{ value 1,value 2,...,value n};

指定的初始值不能比数组元素多,但可以比数组的元素少。

如果少,列表中的初始值被分配从第一个元素(对应索引值0)开始的连续元素。没有得到初始值的数组元素初始化为0。

旧语法

type arrayName[] = { value 1,value 2,...,value n};

基于范围的for循环

使用for循环可以迭代数组中的所有元素。

for(type item:array)        //可以使用auto关键字
{
    //user code
}

C++库提供了——countof()函数,可以获取数组中的元素个数。

	int a[]{1,2,3,4,5};
	std::cout << _countof(a) << std::endl;
	for (int item:a)
	{
		std::cout << item << std::endl;
	}

范例:

#include <iostream>
using namespace std;

int main()
{  
    //4.1 数组
    cout << "数组" << endl;
    int data1[3]{1, 2, 3};//初始化1
    int data2[3]{ };//初始化2,填充0
    int data3[]{ 1, 2, 3 };//初始化3
    for (int i : data1)
    {
        cout << i << endl;
    }
    cout << "sizeof(data1[0]):" << sizeof(data1[0]) << endl;//int 4字节
    cout << "sizeof(data1):" << sizeof(data1)<<endl;//12字节
    cout << "_countof(data1):" << _countof(data1) << endl;//3
    cout <<endl;
}


output:
数组
1
2
3
sizeof(data1[0]):4
sizeof(data1):12
_countof(data1):3

多维数组

声明

type arrayName[size1][size2];

初始化

type arrayName[size1][size2]= {
                                { value 1,value 2,...,value n},
                                { value 1,value 2,...,value n}
                               };
int data1[2][4]  {  { 1,2,3,4},{ 5,6,7,8}  };

//可以省略某些初始值
int data2[2][4]  {  { 1,2,3}, { 5,6}  };


//用0初始化数组
int data2[2][4]  { };

范例:

#include <iostream>
using namespace std;

int main()
{  
    cout << "多维数组" << endl;
    int data4[2][4]{ {1,2,3,4},{5,6,7,8} };//初始化1
    int data5[2][4]{ };//初始化2,填充0
    int data6[][4]{ {1,2,3,4},{5,6,7,8} };//初始化3
    cout << "sizeof(data6[0][0]):" << sizeof(data6[0][0]) << endl;//int 4字节
    cout << "sizeof(data6[0]):" << sizeof(data6[0]) << endl;//16字节
    cout << "sizeof(data6):" << sizeof(data6) << endl;//32字节
    cout << "_countof(data6[0]):" << _countof(data6[0]) << endl;//4
    cout << "_countof(data6):" << _countof(data6) << endl;//2
    cout << "---------------------------------------------" << endl << endl;
}


output:
多维数组
sizeof(data6[0][0]):4
sizeof(data6[0]):16
sizeof(data6):32
_countof(data6[0]):4
_countof(data6):2


字符串

字符数组:char类型的数组。

字符串是附加有特殊字符(字符串结尾标志)的字符序列。这个特殊字符是‘\0’,有时候称为空字符,占1个字节,8位全为0。

非Unicode字符串中的每个字符占用一个字节,算上最后的空字符,字符串需要的字节数要比包含的字符串多1个字节。

#include "pch.h"
#include <iostream>

int main()
{    
	char a[] {"123456789"};
	std::cout << a << std::endl << sizeof(a) << std::endl;

	wchar_t b[]{ L"ABC" };
	std::wcout << b << std::endl << sizeof(b) << std::endl;

}

前缀L表示字符串字面值是一个宽字符串(Unicode字符串)。

wcout标准输出流(宽)。

输入

输入流成员函数 | Microsoft Docs

cin.get()和cin.geline(),从键盘输入的字符串序列,并将其以字符串的形式(以‘\0‘字符串终止)存入字符数组中。

函数的 get 变体指定缓冲区地址和要读取的最大字符数。

#include "pch.h"
#include <iostream>

int main()
{    
	char a[20] {};
	std::cin.get(a,20);
	std::cout << a << std::endl << sizeof(a) << std::endl;
}

输入:123456789
输出:123456789
输出: 20

getline成员函数类似于函数get。 这两个函数均允许用于指定输入终止字符的第三个参数。

#include "pch.h"
#include <iostream>

int main()
{    
	char a[20] {};
	std::cin.getline(a,20,'5');
	std::cout << a << std::endl << sizeof(a) << std::endl;
}

输入:123456789
输出:1234
输出: 20

字符串的字面量

前缀L表示字符串字面值是一个宽字符串(Unicode字符串)。

R表示原字符串字面量的开头,字符串用"(和)"界定。

#include "pch.h"
#include <iostream>

int main()
{    
	char a[] { "123\0\n" };
	std::cout << a << std::endl << sizeof(a) << std::endl;

	char b[]{ R"(123\0\n)" };
	std::cout << b << std::endl << sizeof(b) << std::endl;

	char c[]{ R"*+(123\0\n)*+" };
	std::cout << c << std::endl << sizeof(c) << std::endl;
}

输出:

123
6
123\0\n
8
123\0\n
8

字符串的for循环

#include "pch.h"
#include <iostream>

int main()
{    
	char a[] { "123" };
	for (auto item:a)
	{
		std::cout << item  << std::endl;
	}
	
}

输出:

1
2
3

范例:

#include <iostream>
using namespace std;

int main()
{  
    cout << "字符串" << endl;
    char sentences[2][20]{ {"(It is \n a pig)"},{R"(It is \n a pig)"} };
    for (auto a : sentences)
    {
        cout << a << endl;
    }
    cout << "---------------------------------------------" << endl << endl;
}


output:
字符串
(It is
 a pig)
It is \n a pig
---------------------------------------------

间接数据访问

指针

指针变量存储特定类型的另一个变量的地址。指针变量有名称,还有类型,以指出其内容引用的是什么类型的变量。

声明指针

在名称前面用*号表示指针变量。使用以字母p开始的变量名表示指针是通用惯例。

int* pb;
int *pc;

取值运算符

&,一元运算符,用于获取变量的地址,也称为引用运算符。

 使用指针

间接寻址运算符* 和 指针变量一起使用,访问指针指向的内容。

#include "pch.h"
#include <iostream>

int main()
{    
	int b {123456};
	int* pb;
	pb = &b;
	std::cout << "b: " << b << std::endl;
	std::cout << "&b: " << &b << std::endl;
	std::cout << "pb: " << pb << std::endl;
	std::cout << "&pb: " << &pb << std::endl;
	std::cout << "*pb: " << *pb << std::endl;
}

输出:

b: 123456
&b: 000000DBCF9BFB84
pb: 000000DBCF9BFB84
&pb: 000000DBCF9BFBA8
*pb: 123456

初始化指针

指针字面值nullptr不指向任何对象。

	int b {123456};
	int* pb{& b};
	int* pb{ nullptr };
	int* pb{ 0 };		//旧方法
	int* pb{ NULL };	//旧方法

nullptr可以隐式转换成任何指针类型,但不能隐式转换为除bool类型以外的其他任何整数类型。


	int* pb {nullptr};
    if(!pb)
        //user code

指向char类型的指针

const char* 类型的指针可以用字符串字面值初始化。

const char* pb{"123"};

该字面值的地址将是第一个字符的地址。

可以在非const的指针中存储字符串字面值的地址,但是C++11标准移除了这个功能,VC++仍然允许。

指针数组

sizeof操作符

sizeof操作符产生size_t类型的整数值,给出其操作数占用的字节数量,size_t是由标准库定义的类型。

_countof()可以得到数组元素的个数。

#include "pch.h"
#include <iostream>

int main()
{   
	int b[] {123,456,789};
	std::cout << "sizeof b: " << sizeof b << std::endl;
	std::cout << "_countof b: " << _countof(b) << std::endl;
}

sizeof b: 12
_countof b: 3

常量指针和指向常量的指针

const的指针中存储const数组的地址,这将阻止修改用作初始化器的字面值,此时const指针的地址可以修改。

#include "pch.h"
#include <iostream>

int main()
{  
	const int a { 1 };
	const int b { 2 };
	const int* ptr{ &a };
	ptr = { &b };
}

const type* const指针将阻止修改字面值和指针地址。

#include "pch.h"
#include <iostream>

int main()
{  
	const int a { 1 };
	const int b { 2 };
	const int* const ptr{ &a };
	ptr = { &b };	//报错
}
指针对象(的值)指针指向
指向常量对象的指针不能修改可以修改
指向某个对象的常量指针可以修改不能修改
指向常量对象的常量指针不能修改不能修改

指针和数组

数组可以直接给指针赋值。

或者用数组中某个元素的地址给指针赋值。

#include "pch.h"
#include <iostream>

int main()
{  
	int a[5];
	int* b { nullptr};
	b = a;
	std::cout << b << std::endl;
	b = &a[0];	
	std::cout << b << std::endl;
}

指针可以加、减运算,也可以比较指针值。

#include "pch.h"
#include <iostream>

int main()
{  
	int data[5]{ 2,4,6,8,10 };
	int* pdata{ nullptr };
	pdata = &data[2];
	std::cout << *(pdata + 1) << std::endl;
	pdata = &data[2];
	std::cout << *(pdata - 1) << std::endl;
}

指针与多维数组

#include "pch.h"
#include <iostream>

int main()
{  
	int data[2][3]{ {2,4,6},{1,2,3} };
	int* pdata{ nullptr };
	pdata = data[0]; //将1维数组的地址赋予指针
	std::cout << *pdata << std::endl;
	pdata = &data[0][0];
	std::cout << *pdata << std::endl;
	int (*pdata2)[3];//指针类型是int*[3],圆括号是必须得,否则声明的是一个指针数组。该指针只能用来存储规定维度的数组的地址。
	pdata2 = data;
	std::cout << *pdata2 << std::endl;
}
多维数组的指针形式

可以使用数组名的指针形式来引用数组的元素:

  • 使用带2个索引值得数组名。
  • 使用指针形式的数组名。
#include "pch.h"
#include <iostream>

int main()
{  
	int data[2][3]{ {2,4,6},{1,2,3} };
	int* pdata{ nullptr };
	pdata = data[0]; //将1维数组的地址赋予指针
	std::cout << data[1][1] << std::endl;
	std::cout << *(*(data+1)+1) << std::endl;
	std::cout << *(data[1] + 1) << std::endl;
}

范例:

#include <iostream>
using namespace std;

int main()
{  
    //4.3 间接访问
    cout << "间接访问" << endl;
    int num{ 8888 };
    int* pnum1{ &num };//初始化
    cout << "num: " << num << endl;//8888
    cout << "&num: " << &num << endl;//地址
    cout << "pnum1: " << pnum1 << endl;//地址
    cout << "*pnum1: " << *pnum1 << endl;//8888
    cout << "pnum1 + 1: " << pnum1 + 1 << endl;//地址 + 1单位类型
    cout << "*(pnum1 + 1): " << *(pnum1 + 1) << "(超出界限的指针)" << endl;
    pnum1 = nullptr;
    cout << "pnum1 = nullptr: " << pnum1 << endl; //0
    cout << endl;

    const char* pstr1{ "AbCdEfG" };
    cout << "pstr1: " << pstr1 << endl;//AbCdEfG
    cout << "*pstr1: " << *pstr1 << endl;//A
    cout << "*(pstr1 + 1): " << *(pstr1 + 1) << endl;//b
    cout << "*pstr1 + 1: " << *pstr1 + 1 << endl;//66,也就是B
    cout << "(sizeof pstr1) / (sizeof pstr1[0]): " << (sizeof pstr1) / (sizeof pstr1[0]) << R"( (包含末尾的'\0'))" << endl;//8,包含末尾的 '\0'
    int count{ 0 };
    while (*pstr1++)
    {
        count++;
    }
    cout << "count: " << count << R"( (不包含末尾的'\0'))" << endl;//7
    cout << endl;

    const char* pstr2[3];
    pstr2[0] = { "AbCdEfG" };
    pstr2[1] = { "HiJkLmN" };
    pstr2[2] = { "OpQrSt" };

    //数组首地址和数组元素地址
    cout << "&pstr2: " << &pstr2 << endl;  //数组首地址
    cout << "pstr2: " << pstr2 << endl;//数组首地址
    cout << "&pstr2[1]: " << &pstr2[1] << endl;//数组元素1的地址    

    //数组元素
    cout << "pstr2[0]: " << pstr2[0] << endl;//AbCdEfG    
    cout << "*pstr2: " << *pstr2 << endl;//AbCdEfG
    cout << "pstr2[1]: " << pstr2[1] << endl;//HiJkLmN
    cout << "*(pstr2 + 1): " << *(pstr2 + 1) << endl;//HiJkLmN

    //二位数组元素中的元素
    cout << "pstr2[1][0]: " << pstr2[1][0] << endl;//H
    cout << "*pstr2[1]: " << *pstr2[1] << endl;//H
    cout << "pstr2[1][1]: " << pstr2[1][1] << endl;//i
    cout << "*(pstr2[1] + 1): " << *(pstr2[1] + 1) << endl;//i
    cout << "(*pstr2[1] + 1): " << (*pstr2[1] + 1) << endl;//bCdEfG
    cout << "(*pstr2 + 1)[1]: " << (*pstr2 + 1)[1] << endl;//C

    cout << "*pstr2 + 1: " << *pstr2 + 1 << endl;//bCdEfG
    cout << "*pstr2[0] + 1: " << *pstr2[0] + 1 << endl;//66,也就是B
    cout << endl;

    int arr_int1[]{ 1,3,5,7,9 };
    int* parr_int{ &arr_int1[1] };
    cout << "*arr_int1: " << *parr_int << endl;//3
    cout << "*++arr_int1: " << *++parr_int << endl;//5
    cout << endl;

    //多维数组的指针
    //Array[i][j]
    //*(*(Array + i) +j)
    int  arr_int2[2][3]{ {1,2,3},{7,8,9} };
    int* parr_int2_1{ &arr_int2[1][1] };
    int* parr_int2_2{ arr_int2[1] };
    auto parr_int2_3{ arr_int2 };
    int(*parr_int2_4)[3]{ arr_int2 };
    cout << "arr_int2[2][3]:{ {1,2,3},{7,8,9} }" << endl;
    cout << "int* parr_int2_1{ &arr_int2 [1][1]}: " << *parr_int2_1 << endl;//8
    cout << "*(*(arr_int2 + 1) +1): " << *(*(arr_int2 + 1) + 1) << endl;//8
    cout << "int* parr_int2_2{ arr_int2[1]}: " << *parr_int2_2  << endl;//7
    cout << "*arr_int2: " << arr_int2 << endl;//地址
    cout << "auto parr_int2_3{ arr_int2 }: " << *parr_int2_3 << endl;//地址
    cout << "(*parr_int2_4)[3]{ arr_int2 }: " << *parr_int2_4 << endl;//地址
    cout << "---------------------------------------------" << endl << endl;
}


output:
间接访问
num: 8888
&num: 006FFBF0
pnum1: 006FFBF0
*pnum1: 8888
pnum1 + 1: 006FFBF4
*(pnum1 + 1): -858993460(超出界限的指针)
pnum1 = nullptr: 00000000

pstr1: AbCdEfG
*pstr1: A
*(pstr1 + 1): b
*pstr1 + 1: 66
(sizeof pstr1) / (sizeof pstr1[0]): 4 (包含末尾的'\0')
count: 7 (不包含末尾的'\0')

&pstr2: 006FFBB8
pstr2: 006FFBB8
&pstr2[1]: 006FFBBC
pstr2[0]: AbCdEfG
*pstr2: AbCdEfG
pstr2[1]: HiJkLmN
*(pstr2 + 1): HiJkLmN
pstr2[1][0]: H
*pstr2[1]: H
pstr2[1][1]: i
*(pstr2[1] + 1): i
(*pstr2[1] + 1): 73
(*pstr2 + 1)[1]: C
*pstr2 + 1: bCdEfG
*pstr2[0] + 1: 66

*arr_int1: 3
*++arr_int1: 5

arr_int2[2][3]:{ {1,2,3},{7,8,9} }
int* parr_int2_1{ &arr_int2 [1][1]}: 8
*(*(arr_int2 + 1) +1): 8
int* parr_int2_2{ arr_int2[1]}: 7
*arr_int2: 006FFB70
auto parr_int2_3{ arr_int2 }: 006FFB70
(*parr_int2_4)[3]{ arr_int2 }: 006FFB70
---------------------------------------------


动态分配内存

new操作符:动态分配内存。

delete操作符:释放new分配的内存。

#include "pch.h"
#include <iostream>

int main()
{  
	
	int* pdata = new int{ 123 };
	std::cout << *pdata << std::endl;
	delete pdata;
	std::cout << *pdata << std::endl;	//引发异常
}

释放指针指向的内存时,还应把该指针的值设置为nullptr,否则就会出现悬空指针,可以通过这种悬空指针访问已释放的内存,这会导致意外。

动态分配内存时,尤其是给数组或复杂的对象动态分配内存时,最好使用智能指针,不需要时,会自动释放内存。

为数组动态分配内存

#include "pch.h"
#include <iostream>

int main()
{  
	
	int* pdata{ new int[]{1,2,3,4,5,6,7,8,9} };
	std::cout << *pdata << std::endl;
	delete [] pdata;
	//std::cout << *pdata << std::endl;	//引发异常
	pdata = nullptr;
	
}

delete后的方括号指出要删除的是一个数组。还应该将指针设置为nullptr。

多维数组的动态分配内存

#include "pch.h"
#include <iostream>

int main()
{  
	
	int(*pdata)[3]{ new int[][3]{{1,2,3},{4,5,6}} };
	auto pdata2 { new int[][3]{{1,2,3},{4,5,6}} };
	std::cout << **pdata << std::endl;
	std::cout << **pdata2 << std::endl;
	delete [] pdata;
	//std::cout << *pdata << std::endl;	//引发异常
	pdata = nullptr;	
}

范例:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  
    //4.4 动态分配内存
    //int* parr{};
    //parr = new int{ 888 };
    cout << "动态分配" << endl;
    int* parr{ new int{ 888 } };
    cout << "*parr: " << *parr << endl;
    delete parr;
    parr = nullptr;

    int* parr2{ new int[] {333, 444} };
    cout << "*parr2: " << *parr2 << endl;//333
    cout << "*(parr2 + 1): " << *(parr2 + 1) << endl;//444
    unsigned long long address = (unsigned long long)parr2;
    cout << "parr2: " << parr2 << endl;
    cout << "address: " << hex << setfill('0') << setw(16) << uppercase << address << endl;

    int result1 = *(int*)address;
    cout << "result1: " << dec << result1 << endl;
    delete[] parr2;
    parr2 = nullptr;
    int result2 = *(int*)address;
    cout << "After delete[] parr2, result2: " << dec << result2 << endl;
    cout << "---------------------------------------------" << endl << endl;
}


output:
动态分配
*parr: 888
*parr2: 333
*(parr2 + 1): 444
parr2: 011BF370
address: 00000000011BF370
result1: 333
After delete[] parr2, result2: -572662307
---------------------------------------------



使用引用

引用是可用作其他对象的别名的一个名称。

引用分类:lvaluervalve

lvalue是另一个变量的别名。

rvalve引用也可以用作变量的别名,但它与lvalue引用的区别在于,它也能引用rvalve,这实质上是一个暂存的临时值。

声明初始化lvalue

类型名称后面,变量名称前面的&表示声明一个lvalue引用。

#include "pch.h"
#include <iostream>

int main()
{
	int a{ 1 };
	int& lvalue{ a };	//声明变量的引用
	const int& lvalue2 {2};	//声明变量的引用
	std::cout << lvalue << std::endl;
	std::cout << lvalue2 << std::endl;
}

基于范围的for循环中使用引用

#include "pch.h"
#include <iostream>

int main()
{
	int a[]{ 1,2,3 };
	for(int item:a)
		std::cout << item << std::endl;

	for (int& item : a)
	{
		item = item + 3;
		std::cout << item << std::endl;
	}
		
	for (const int& item : a)	//不修改,提高性能用const
	{
		std::cout << item << std::endl;
	}
}

创建rvalve引用

C++表达式,要么是lvalve,要么是rvalve

在类型名后用&来指定一个rvalve引用。

#include "pch.h"
#include <iostream>

int main()
{
	int && a{2*3 };	//rvalve,仅演示用,不是使用rvalve的方式
	std::cout << a;
}

范例:

#include <iostream>
#include <iomanip>
using namespace std;

int main()
{  
    //4.5 引用
    cout << "引用" << endl;
    int alvalue{ 99 };//lvalue
    int& re_alvalue1{ alvalue };//可以用引用代替原来的变量名
    const int& re_alvalue2{ 88 };//
    int* p_re_alvalue1{ &re_alvalue1 };

    cout << "alvalue: " << alvalue << endl;
    cout << "re_alvalue1: " << re_alvalue1 << endl;
    cout << "*p_re_alvalue1: " << *p_re_alvalue1 << endl;
    *p_re_alvalue1 += 1;
    cout << "*p_re_alvalue1 += 1" << endl;
    cout << "alvalue: " << alvalue << endl;
    cout << "re_alvalue1: " << re_alvalue1 << endl;
    cout << "*p_re_alvalue1: " << *p_re_alvalue1 << endl;

    cout << endl;
    //在基于范围的for循环中
    int aArr[]{ 333, 444 };
    cout << "int t:" << endl;
    for (int t : aArr)
    {
        t++;
    }
    for (int t : aArr)
    {
        cout << "aArr: " << t << endl;
    }
    cout << endl;
    cout << "int& t:" << endl;
    for (int& t : aArr)
    {
        t++;
    }
    for (int& t : aArr)
    {
        cout << "aArr: " << t << endl;
    }
    cout << endl;
    int&& re_rvalue3{ alvalue + 1 };//rvalue的引用
    cout << "re_rvalue3: " << re_rvalue3 << endl;
}


output:
引用
alvalue: 99
re_alvalue1: 99
*p_re_alvalue1: 99
*p_re_alvalue1 += 1
alvalue: 100
re_alvalue1: 100
*p_re_alvalue1: 100

int t:
aArr: 333
aArr: 444

int& t:
aArr: 334
aArr: 445

re_rvalue3: 101


字符串库函数

string标准头文件定义了string和wstring类。

一般来说,安全函数以_s结尾。

#include "pch.h"
#include <atlstr.h>

int main() {
    CString aCString = CString(_T("A string"));
    _tprintf(_T("%s"), (LPCTSTR)aCString);
}

通过使用当前区域设置或指定区域设置获取字符串的长度

strnlen、strnlen_s、wcsnlen、wcsnlen_s、_mbsnlen、_mbsnlen_l、_mbstrnlen、_mbstrnlen_l | Microsoft Docsicon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strnlen-strnlen-s?view=msvc-170

追加字符串

strcat_s、wcscat_s、_mbscat_s、_mbscat_s_l | Microsoft Docs详细了解:strcat_s、wcscat_s、_mbscat_s、_mbscat_s_licon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcat-s-wcscat-s-mbscat-s?view=msvc-170

复制字符串

strcpy_s、wcscpy_s、_mbscpy_s、_mbscpy_s_l | Microsoft Docs了解详细信息: strcpy_s、wcscpy_s、_mbscpy_s、_mbscpy_s_licon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcpy-s-wcscpy-s-mbscpy-s?view=msvc-170

比较字符串

strcmp、wcscmp、_mbscmp、_mbscmp_l | Microsoft Docs了解:strcmp、wcscmp、_mbscmp、_mbscmp_licon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strcmp-wcscmp-mbscmp?view=msvc-170

返回不属于某个字符集的字符串中第一个字符的索引

strspn、wcsspn、_mbsspn、_mbsspn_l | Microsoft Docs了解详细信息: strspn、wcsspn、_mbsspn、_mbsspn_licon-default.png?t=N7T8https://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strspn-wcsspn-mbsspn-mbsspn-l?view=msvc-170

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值