栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

数组、字符串和指针

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

数组、字符串和指针

数组

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

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

声明数组
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;
	}
多维数组

声明

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]  { };

字符串

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

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

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

#include "pch.h"
#include 

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(),从键盘输入的字符串序列,并将其以字符串的形式(以‘‘字符串终止)存入字符数组中。

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

#include "pch.h"
#include 

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 

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 

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

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

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

输出:

123
6
123n
8
123n
8

字符串的for循环
#include "pch.h"
#include 

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

输出:

1
2
3


间接数据访问

指针

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

声明指针

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

int* pb;
int *pc;
取值运算符

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

 使用指针

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

#include "pch.h"
#include 

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 

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 

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

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

#include "pch.h"
#include 

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

指针和数组

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

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

#include "pch.h"
#include 

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 

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 

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 

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

动态分配内存

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

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

#include "pch.h"
#include 

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

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

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

为数组动态分配内存

#include "pch.h"
#include 

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 

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;	
}
使用引用

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

引用分类:lvalue和rvalve。

lvalue是另一个变量的别名。

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

声明初始化lvalue

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

#include "pch.h"
#include 

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 

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 

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

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

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

#include "pch.h"
#include 

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 Docshttps://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_lhttps://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_lhttps://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_lhttps://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_lhttps://docs.microsoft.com/zh-cn/cpp/c-runtime-library/reference/strspn-wcsspn-mbsspn-mbsspn-l?view=msvc-170

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/917006.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号