数组、指针与字符串
数组
数组是具有一定顺序关系的若干对象的集合体,组成数组的对象被称为该数组的元素。
每个元素有 n 个下标的数组被称为 n 维数组。
声明一个数组类型,应该包括以下几个方面:
- 确定数组的名称
- 确定数组元素的类型
- 确定数组的结构(包括数组维数,每一维的大小等)
声明语法:数据类型 标识符[常量表达式1][常量表达式2]...
例如:
int b[5];
int b[] = {1,2,3};
int a[5][5];
int a[][] = {{1,2,3},{1,2,3},{1,2,3}};
数组的使用:数组名[常量表达式1][常量表达式2]...
数组的存储:数组元素在内存中是顺序的、连续存储的。
数组的初始化:在声明数组时给部分或全部元素赋初始值。
注意:
- 如果数组后面没赋值的,则默认为0
- 在多维数组中,
[][]的顺序时先行后列的 - 在定义方法的形参中,二维数组中的列大小不能省略
void rowSum(int a[][3])
{
//...
}
void main()
{
int table[4][3]={...};
rowSum(table);
}
对象数组
数组的元素不仅可以是基本数据类型,也可以是自定义类型。
声明语法:类名 数组名[常量表达式]
使用:数组名[下标表达式].成员名
指针
指针变量是用于存放内存单元地址的。
声明语法:数据类型 *标识符
与地址相关的运算:
- *:称为指针运算符
- &:称为取地址运算符
int *p;
cout << *p << endl;//输出指定所指向的内容
int a,b;
int *pa, *pb = &b;
pa = &a;
指针的赋值:
- 定义语法:
存储类型 数据类型 *指针名 = 初始地址; - 赋值语法:
指针名 = 地址;
注意:
- 一个数组,可以用它的名称来直接表示他的初始地址。数组名实际上就是一个不能被赋值的指针,即指针常量。
void main()
{
int i;
int *p = &i;
i = 10;
cout << i << endl; //输出int类型的数的值
cout << *p << endl; //输出int类型指针所指地址的内容
}
- 可以声明指向常量的指针,此时不能通过指针来改变所指对象的值,但指针本身可以改变,可以指向另外的对象。
- 可以声明指针类型的常量,这时指针本身的值不能被改变。
- 一般情况下,指针的值只能赋给相同类型的指针。,但是有一种特殊的 void 类型指针,可以存储任何类型的对象地址。
指针的运算:
- *p1+n1(*(p1+n1)/p1[n1]):表示p1当前所指位置后方第n1个数的地址
- *p1-n1(*(p1-n1)/p1[-n1]):表示p1当前所指位置前方第n1个数的地址
- *p++/*p–:表示指针当前所指位置下一个或前一个数据的地址
- 空指针:可以用
NULL或nullptr来表示
指针数组
如果一个数组的每一个元素都是指针变量,这个数组就是指针数组。
注意:指针数组存储的是变量的地址!
void main()
{
int arr1 = {1,2,3}
int arr2 = {1,2,3}
int arr3 = {1,2,3}
int *pArr[3] = {arr1,arr2,arr3};
for(int i = 0;i<3;i++)
{
for(int k = 0;k<3;k++)
{
//pArr存储的是指针地址
cout << pArr[i][j] << endl;
}
}
}
指针型函数:
除了 void 类型函数外,函数在调用结束之后都要有返回值,指针也可以是函数的返回值。
指针函数的语法:
返回值的数据类型 *函数名(参数列表)
{
函数体;
}
函数返回数组指针:由于数组不能被复制,因此函数不能返回数组,但是可以返回数组的指针。
语法:
类型说明符 (*函数名(参数列表))[数组维度]
//(*函数名(参数列表)):意味着对函数返回的结果执行解析操作
例如:
typedef int arr[10];
//foo 返回一个指向含有10个整数的数组的指针
arr* foo(int i);
//或
int (*foo(int i))[10]
C++ 11标准中提供了一种可以简化上述 foo 声明的方法,即使用尾置返回类型。任何函数的定义都可以使用尾置返回类型,但是这种形式对于返回类型复杂的函数更有效。
语法:auto 函数名(参数列表) -> 类型说明符(*)[数组维度]
例如:
auto foo(int i) -> int(*)[10];
如果知道函数返回的指针将只想哪一个数组,就只可以使用 decltype 关键字声明返回类型。
例如:
int a[] = {0,1,2,3,4};
int b[] = {5,6,7,8,9};
decltype(a) *func(int i)
{
return (i%2)? &a :&b;
}
![图片[1]-【学习笔记 Day04】C++基础:独一份的指针,探索其中的奥秘!-资源刺客](http://images.kodo.cdn.itdka.cn/wp-content/uploads/2025/10/20251031190041879.png)
指向函数的指针
语法:
数据类型 (*函数指针名)(形参表)
//说明类型:说明函数指针所指函数的返回值类型
例如:
int (*foo)(int i);
函数指针在使用之前也要进行赋值,使指针指向一个已经存在的函数代码的地址。
语法:
函数指针名 = 函数名;
例如:
void float printStuff(float data)
{
cout << "printStuff" << endl;
}
void printMessage(float data)
{
cout << "printMessage" << endl;
}
void printFloat(float data)
{
cout << "printFloat" << endl;
}
const float PI = 3.1415926f;
const float Two_PI = 3.1415927f;
void main()
{
void (*func)(float);
printStuff(PI);
func = printStuff; //函数指针指向 printStuff
func(PI); //通过函数指针进行调用
func = printMessage; //函数指针指向 printMessage
func(Two_PI);
func(13.0);
func = printFloat;
fun(PI);
}
对象指针
对象指针用于存放对象地址的变量。
语法:
类名 *对象指针名
//使用
对象指针名 -> 成员名
//或
(*对象指针名).成员名
例如:
Point *p;
Point p1;
p = p1;
this 指针
this 指针是一个隐含于每一个类的非静态成员函数中的特殊指针(包括构造函数和析构函数),它用于指向正在被成员函数操作的对象。
指向类的非静态成员的指针
指向对象成员的指针使用前也需要先声明,再赋值,然后在引用。
语法:
类型说明符 类名::*指针名; //声明指向数据成员的指针
类型说明符 (类名::*指针名)(参数列表); //声明指向函数成员的指针
声明了指向成员的指针之后,需要对其进行赋值,语法:
指针名 = &类名::数据成员名;
访问数据成员时,可以使用以下语法:
对象名.*类成员指针
//或
对象指针名 -> *类成员指针名
访问函数成员时,可以使用以下语法:
(对象名.*类成员指针名)(参数列表);
//或
(对象名 -> *类成员指针名)(参数列表);
指向类的静态成员的指针
对类的静态成员的访问是不依赖于对象的。
动态内存分配
运算符 new 的功能是动态分配内存或称为动态创建堆对象。
创建对象的语法:
数据类型 变量名 = new 数据类型(初始化参数列表);
建立和删除堆对象使用两个运算符: new 和 delete(两两配合使用,不然会内存泄漏)。
删除对象的语法:
delete 指针名;
例如:
int *point = new int(2);
delete *point;
使用 vector 创建数组对象
vector 不是一个类,而是一个类模板。
语法:
vector<元素类型> 数组对象名(数组长度,元素初值);
//访问数组:
数组对象名[下标索引位置];
例如:
vector<int> arr(10);
arr[5];
字符串
string 类提供了对字符串进行处理所需要的操作。
- 构造函数的原型:
//默认构造函数,建立一个长度为0的字符串
string();
//复制构造函数
string(const string &rhs);
//用指针s所指向的字符串常量初始化string类的对象
string(const char *s);
//将对象 rhs 中的串从位置pos开始取n个字符,用来初始化string类的对象。
string(const string &rhs,unsigned int pos,unsigned int n);
//注:串中的第一个字符的位置为0
//用指针s所指向的字符串中的前n个字符初始化string类的对象
string(const char *s,unsigned int n);
//将参数c中的字符重复n次,用来初始化string类的对象
string(unsigned int n,char c);
- string类的操作符
| 操作符 | 示例 | 注释 | 操作符 | 示例 | 注释 |
| + | s+t | 将串s和t连接成一个新串 | < | s<t | 判断s是否小于t |
| = | s=t | 用t更新s | <= | s<=t | 判断s是否小于或等于t |
| += | s+=t | 等价于s=s+t | >= | s>=t | 判断s是否大于等于t |
| == | s==t | 判断s与t是否相等 | > | s>t | 判断s是否大于t |
| != | s!=t | 判断s与t是否不相等 | [] | s[i] | 访问串中下标为i的字符 |
- 常用成员函数功能简介
//将字符串s添加到本字符串的末尾
string append(const char *s);
/赋值:将s所指向的字符串赋值给本对象
string assign(const char *s);
//比较本串与str串的大小,当本串小于str串时,返回复数,反之返回正数,两串相等时返回0
int compare(const string &str) const;
//将s所指向的字符串插入在本串中的位置p0之前
string &insert(unsigned int p0,const char *s);
//取子串,取本串中的位置pos开始n个字符,构成新的string类对象作为返回值
string substr(unsigned int pos,unsigned int n) const;
//查找并返回str在本串中第一次出现的位置
unsigned int find(const basic_string &str) const;
//返回串的长度(字符个数)
unsigned int length() const;
//将本串与str中的字符串进行交换
void swap(string &str);


![[学习笔记 Day02]Vue基础:前端造梦,继续干!-资源刺客](http://images.kodo.cdn.itdka.cn/wp-content/uploads/2025/09/20250919193418264.jpeg)

![[学习笔记 Day01]C#基础:从入门到精通,开启新世纪的编程大门到精通,开启新世纪的编程大门-资源刺客](http://images.kodo.cdn.itdka.cn/wp-content/uploads/2025/08/20250827185617438.jpeg)





![[自动化 + 手残党专属]宝塔安装AllinSSL证书管理教程-资源刺客](http://images.kodo.cdn.itdka.cn/wp-content/uploads/2025/11/20251112122722716.png)




暂无评论内容