当前位置: 首页 > news >正文

C++微基础备战蓝桥杯之数组篇10.1

#前言

uu们,我开始有点懒散了,今天开始写才发现已经9天没有学习了,~||~,言归正传,接下来高强度一点,看能不能补回来,这一篇大概写c++数组

一. ⼀维数组

数组是⼀组相同类型元素的集合;

从这个概念中我们就可以发现2个有价值的信息:

1.数组中存放的是1个或者多个数据,但是数组元素个数不能为0。

2• 数组中存放的多个数据,类型是相同的。

数组分为⼀维数组和多维数组,多维数组⼀般⽐较多⻅的是⼆维数组。

 1. ⼀维数组的创建和初始化

⼀维数组是最常⻅的,通常⽤来存放⼀组数据,⼀维数组是⼀块连续的空间。

1.1 数组创建

⼀维数组创建的基本语法如下:

type arr_name[常量值] 

存放在数组的值被称为数组的元素,数组在创建的时候需要指定数组的⼤⼩和数组的元素类型。 

type 指定的是数组中存放数据的类型,可以是: 定义的类型  char 、 short 、 int 、 float 等,也可以⾃ arr_name 是数组的名字,这个名字可以⾃定义,根据实际情况,起的有意义就⾏。

•[] 中的常量值是⽤来指定数组的⼤⼩的,数组的⼤⼩是根据实际的需求指定就⾏。在算法竞赛中 为了为了保证不越界访问,往往会多开辟⼀些空间,后期题⽬中会讲到。 

可以使⽤ const int N = 100 的⽅式定义常量,来指定数组的⼤⼩。

例如: int arr[N] ;

⽐如:我们现在想存储某个班级的20⼈的数学成绩,那我们就可以创建⼀个数组,如下:

#include <iostream>
using namespace std;const int N = 20;
int main()
{int math[N];return 0;} 

1.12.数组的初始化

有时候,数组在创建的时候,我们需要给定⼀些初始值,这种就称为初始化的。

那数组如何初始化呢?数组的初始化⼀般使⽤⼤括号,将数据放在⼤括号中。

#include <iostream>
using namespace std;int main()
{int arr[5] =  {1,2,3,4,5};//完全初始化、int arr2[6] = {1};//不完全初始化 //错误示范
//  int arr3[3] = {1,2,3,4,5}return 0;} 

1.2. ⼀维数组元素的访问

数组是有下标的,从0开始 ,可以使用下标引用操作符来实现访问 

#include <iostream>
using namespace std;int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};//数组是有下标的,从0开始 ,可以使用下标引用操作符来实现访问 arr[3] = 4;// 其中的arr[3]就是下标引用操作符 return 0;} 

求数组元素个数

#include <iostream>
using namespace std;int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};cout << sizeof(arr) << endl;//--40//这里使用的是字节,这里的是整型,一个整型占4个字节//则cout << sizeof(arr) / sizeof(arr[0]) << endl;//所有元素字节长度 / 一个元素字节长度//得出元素个数 return 0;} 

3. ⼀维数组元素的打印

接下来,如果想要访问整个数组的内容,那怎么办呢?

只要我们产⽣数组所有元素的下标就可以了,那我们使⽤for 循环产⽣所有的下标,接下来使⽤下标访问就⾏了。

#include <iostream>
using namespace std;int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int i = 0;for(i = 0; i < 10; i++){cout << arr[i] << " ";}cout << endl;return 0;} 

由打印元素个数方式可将其优化为

#include <iostream>
using namespace std;int main()
{int arr[5] = {0};int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for(i = 0;i < sz;i++){cin >> arr[i]; }for(i = 0; i < sz; i++){cout << arr[i] << " ";}cout << endl;return 0;} 

4. 范围for 

打印数组元素除了可以使⽤之前讲过的三种循环外,还有⼀个更⽅便的⽅式,使⽤范围for

范围for语法:

for(类型 变量名 : 数组名 )

但是范围for只能c++11支持使用

比如devC++就不能使用,那如何配置环境呢?

在devC++中,菜单中,点击:工具->编译选项,打开

勾选【编译时加入一下命令】,然后在下方的编译框中加入:

-std=c++11

其他代码块

-std=c++14 
-std=c++17 
-std=c++20 

eg

#include <iostream>
using namespace std;int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10};for(int e : arr){e = 1;}for(int e : arr){cout << e << " ";}//输出1 2 3 4 5 6 7 8 9 10 return 0;} 

范围for只能打印数组,不能更改数组

5. auto 关键字

auto 的主要⽤途是让编译器⾃动推导出变量的类型的

⽐如:

#include <iostream>
using namespace std;int main()
{auto a = 3.14;auto b = 100;auto c = 'x';cout << a << endl;cout << b << endl;cout << c << endl;return 0;} 

调试时能看到a,b ,c ,类型

不想给其明确指定类型,或者不确定其字符类型就可以使用auto

范围for也经常使用auto类型

	for(auto e : arr){e = 1;}

6. memset设置数组内容

函数原型介绍

void * memset ( void * ptr, int value, size_t num );参数解释:
ptr -- 指针:指向了要设置的内存块的起始位置
value -- 要设置的值
num -- 设置的字节个数
#include <iostream>
#include <cstring>
using namespace std;int main()
{char arr[] = "hello world";cout << arr << endl;//对于整型数组不能直接这样打印 memset(arr,'x',5);//使用需要头文件   #include <cstring> cout << arr << endl;//打印出 xxxxx world return 0;
}

memset 是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容,需要头⽂件

#include <cstring>

一般使用memset来设置整型数组时都设置为0,其他数字容易出错

#include <iostream>
#include <cstring>
using namespace std;int main()
{int arr[5] = {1,2,3,4,5};memset(arr,0,20);for(int e : arr){cout << e << " ";}cout << endl;//输出 0 0 0 0 0 return 0;
}

比如


#include <iostream>
#include <cstring>
using namespace std;int main()
{int arr[5] = {1,2,3,4,5};memset(arr,1,20);for(int e : arr){cout << e << " ";}cout << endl;//输出 16843009 16843009 16843009 16843009 16843009return 0;
}

7. memcpy拷⻉数组内容

在使⽤数组的时候,有时候我们需要将数组a的内容给数组b,⽐如:

	int a[10] = {1,2,3,4,5,6,7,8,9,10};int b[10] = {0};

怎么做呢?直接赋值是错误的

数组名是地址,地址是一个常量的值,常量不可被修改 
其实C++中有⼀个库函数 memcpy 可以做数组内容的拷⻉,当然 memcpy 其实是⽤来做内存块的拷⻉ 的,当然⽤来做数组内容的拷⻉也是没问题的。

函数原型如下:

#include <cstring>void * memcpy ( void * destination, const void * source, size_t num );//destination -- 目标空间的起始地址//source    --  源数据空间的起始地址  
//num    --    拷贝的数据的字节个数 

eg

#include <iostream>
#include <cstring>
using namespace std;int main()
{int a[10] = {1,2,3,4,5,6,7,8,9,10};int b[10] = {0};memcpy(b, a, 10 * sizeof(int));for(int e: b){cout << e << " ";}//打印出1,2,3,4,5,6,7,8,9,10 return 0;} 

二. ⼆维数组 

1. ⼆维数组的概念

前⾯学习的数组被称为⼀维数组,数组的元素都是内置类型的,如果我们把⼀维数组做为数组的元 素,这时候就是⼆维数组,⼆维数组作为数组元素的数组被称为三维数组,⼆维数组以上的数组统称 为多维数组。

2. ⼆维数组的创建和初始化

2.1.创建

那我们如何定义⼆维数组呢?语法如下:

type arr_name[常量值1][常量值2]; 
例如:int arr[3][5];double data[2][8];
#include <iostream>
using namespace std;int main()
{int arr1[3][5] = {1,2};int arr2[3][50] = {1, 2, 3, 4, 5, 6};return 0;
}

下⾯解释⼀下上述代码中的⼀些关键信息:

• 3 表⽰数组有 3 ⾏

• 5 表⽰每⼀⾏有 5 个元素

• int 表⽰数组的每个元素是整型类型

• arr 是数组名,可以根据⾃⼰的需要指定名字

data 数组意思基本⼀致。

2.2.初始化

在创建变量或者数组的时候,给定⼀些初始值,被称为初始化。 那⼆维数组如何初始化呢?像⼀维数组⼀样,也是使⽤⼤括号初始化的。

#include <iostream>
using namespace std;int main()
{//不完全初始化int arr1[3][5] = {1,2};int arr2[3][5] = {0};//完全初始化int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};//按行初始化 int arr4[3][5] = {{1,2},{3,4},{5,6}};//如果数组初始化了,数组在指定??的时候可以省略?,?不能省略列int arr5[][5] = {1,2,3};int arr6[][5] = {1,2,3,4,5,6,7};int arr7[][5] = {{1,2}, {3,4}, {5,6}};return 0;
}

2.3.二维数组下标

当我们掌握了⼆维数组的创建和初始化,那我们怎么使⽤⼆维数组呢? 比特就业课 其实⼆维数组访问也是使⽤下标的形式的,⼆维数组是有⾏和列的,只要锁定了⾏和列就能唯⼀锁定 数组中的⼀个元素。

C/C++规定,⼆维数组的⾏是从 0 开始的,列也是从 0 开始的,如下所⽰:

int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};

eg

#include <iostream>
using namespace std;int main()
{int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};cout << arr[2][4] << endl;//输出7 return 0;} 

3. ⼆维数组的元素的访问

#include <iostream>
using namespace std;int main()
{int arr[3][5] = { 1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7 };for (int i = 0; i < 3; i++){for (int j = 0; j < 5; j++) {cout << arr[i][j] << " ";}cout << endl;}//输出//1 2 3 4 5//2 3 4 5 6 //3 4 5 6 7 return 0;
}

4. memset设置⼆维数组

memset 是⽤来设置内存的,将内存中的值以字节为单位设置成想要的内容。 下⾯演⽰两个例⼦,使⽤ memset 来设置⼆维数组的内容

#include<iostream>
#include <cstring>
using namespace std;
int main()
{char arr[10][10];  memset(arr, 'x', sizeof(arr));      
//将二维整型数组中每个字节都设置为xfor(int i = 0; i < 10; i++){for(int j = 0; j < 10; j++){cout << arr[i][j] << " ";}cout << endl;}return 0;
}

memset 在⼆维数组中的⽤法同⼀维数组,同样也需要注意避免给整型赋⾮ 0 值

三. 字符数组

数组的元素如果是字符类型,这种数组就是字符数组,字符数组可以是⼀维数组,可以是⼆维数组 (多维数组)。 接下来主要讨论⼀维的字符数组。

	char arr1[5];   //二维数组char arr2[3][5];//二维数组

C语⾔中使⽤双引号括起来⼀串字符表⽰字符串,这种⽅式虽然在C++中也是⽀持的,但是⼀般我们 会将这种字符串称为C语⾔⻛格的字符串。如果需要将⼀个C语⾔⻛格的字符串存储起来,就可以是 字符数组。

1. 字符数组的初始化

char a[10]; //字符数组的创建

字符数组的创建同⼀维数组的创建就不再赘述,但是字符串数的初始化有2种⽅式,如下:

//式1 char ch1[10] = "abcdef";char ch2[] = "abcdef";//如果数组初始化的时候,数组的大小可以省略不写,//数组大小会根据初始化内容来确定//式2 char ch3[10] = {'a', 'b', 'c', 'd', 'e', 'f'};char ch4[] = {'a', 'b', 'c', 'd', 'e', 'f'};

2. strlen求字符串⻓度

字符数组中存放的着字符串,这个字符数组有⾃⼰的⻓度,也就是数组的元素个数,这个可以使⽤sizeof 计算,那数组中存放的字符串的⻓度是多少?怎么来计算呢?其实C/C++中有⼀个库函数 叫: strlen ,可以求字符串的⻓度,其实统计的就是字符串中 \0 之前的字符个数。 strlen 需要 的头⽂件是<cstring> 。

   size_t strlen ( const char * str );//str - 指针,存放的是字符串的起始地址,//从这个地址开始计算字符串的长度

eg


#include <iostream>
#include <cstring>using namespace std;int main()
{char arr[10] = "abcdef";//a b c d e f \ 0 0 0 0int n = strlen(arr);cout << n << endl;int sz = sizeof(arr) / sizeof(arr[0]);//     10               1cout << sz << endl;//输出 6   10 
}

3. 字符数组的输⼊

3.1.输⼊没有空格字符串

3.11使⽤scanf函数和字符数组来实现:

其头文件#include <cstdio>

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[10];//输入 --abcdefscanf("%s", arr);//输出printf("%s\n", arr);//---输出abcdef return 0;
}
3.12也可以使用cin和cout


但是他们只能使用于不带空格的字符串 

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[10];cin >> arr;cout << arr;//输入abcdef//输出abcdef return 0;
}

那如果输出带空格的字符串应该用什么呢?

scanf
#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[20];scanf("%s",arr);printf("%s\n",arr);//输入  abc def//输出  abc return 0;} 

当输⼊"abcdef"的时候,实际上scanf只读取了abc就结束了,也就是相当于遇到空格就结束了。

这⾥特别说⼀下占位符 %s ,它其实不能简单地等同于字符串。它的规则是,从当前第⼀个 ⾮空⽩字符开始读起,直到遇到空⽩字符(即空格、换⾏符、制表符等)为⽌。 因为 %s 的读取不会包含空⽩字符,所以⽆法⽤来读取多个单词,除⾮多个 这也意味着, %s ⼀起使⽤。 scanf() 不适合读取可能包含空格的字符串,⽐如书名或歌曲名。另外有⼀ 个细节注意⼀下, scanf() 遇到 %s 占位符,会在字符串变量末尾存储⼀个 \0 字符。

同时 scanf() 将字符串读⼊字符数组时,不会检测字符串是否超过了数组⻓度。所以,储存字符串 时,很可能会超过数组的边界,导致预想不到的结果。为了防⽌这种情况,使⽤ %s 占位符时,可以 指定读⼊字符串的最⻓⻓度,即写成%[m]s,其中的 [m] 是⼀个整数,表⽰读取字符串的最⼤⻓度,后⾯的字符将被丢弃。

cin cout
#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[20];cin >> arr;cout << arr << endl;//输入abc def//输出abc return 0;} 

结果也是⼀样,没有任何区别。

其实cin在读取⼀个字符串的时候,在遇到空⽩字符的时候,就认为字符串结束了,不再继续 往后读取剩余的字符,同时将已经读取到的字符串末尾加上\0,直接存储起来。

1.13.解决办法
1.14gets和fgets
char * gets ( char * str );char * fgets ( char * str, int num, FILE * stream );

eg

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[20];gets(arr);cout << arr;//输入abc edf//输出abc edfreturn 0;} 

gets是怎么运行工作的呢

gets 是从第⼀个字符开始读取,⼀直读取到 \n 停⽌,但是不会读取 \n ,也就是读取到的内容 中没有包含 \n ,但是会在读取到的内容后⾃动加上 \0 。

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[10] = {0};fgets(arr, sizeof(arr), stdin);printf("%s\n", arr);return 0;
}

注:即使这里标的是20个数,但fgets最多读取19个数

fgets 也是从第⼀个字符开始读取,最多读取 num-1 个字符,最后⼀个位置留给 \0 ,如果num 的⻓度是远⼤于输⼊的字符串⻓度,就会⼀直读取到 \n 停⽌,并且会读取 \n ,将 \n 作 为读取到内容的⼀部分,同时在读取到的内容后⾃动加上 \0 。

注:

在DevC++中使⽤gets函数,确实没有报错,但是在其他的IDE上,⽐如:VS2022上直接报 错,不允许使⽤gets函数。 所以在代码中还是慎⽤gets函数。

当然C语⾔中使⽤ scanf 函数其实也能做到读取带有空格的字符串,只是不常⻅⽽已。⽅式就是 将 "%s" 改成 "%[^\n]s" ,其中在 % 和 s 之间加上了 [^\n] ,意思是⼀直读取,直到遇到\n ,这样即使遇到空格也就不会结束了。

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[10] = "xxxxxxxx";scanf("%[^\n]s", arr);printf("%s\n", arr);//输入abc def//输出abc def return 0;} 
getchar

使⽤ getchar 逐个字符的读取,也是可以读取⼀个字符串的。

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[20];int ch = 0;int i = 0;while((ch = getchar()) != '\n'){arr[i] = ch;i++;}arr[i] = '\0';//必须有一个'\0',不然程序会崩 cout <<arr;//输入abc def//输出abc def return 0;} 

如果不想在结尾输入'\0',也可以在开始时初始化数组

#include <iostream>
#include <cstdio>using namespace std;int main()
{char arr[20] ={0};int ch = 0;int i = 0;while((ch = getchar()) != '\n'){arr[i] = ch;i++;}cout <<arr;//输入abc def//输出abc def return 0;} 

4. 字符数组的输出

其实前面已经使用得差不多了,总结以下

1. C语⾔中可以在 printf 函数中使⽤ %s 占位符的⽅式,打印字符数组中的字符串。

 
#include <iostream>
#include <cstdio>
using namespace std;
int main()
{char a[] = "hello world";cout << a << endl;printf("%s\n", a);//    输出 hello world 
//         hello worldreturn 0;
}

2. C++中使⽤ cout ,可以直接打印字符数组中的字符串内容。

#include <iostream>
using namespace std;
int main()
{char a[] = "hello world";int i = 0;while (a[i] != '\0'){cout << a[i];i++;}cout << endl;//输出 hello world return 0;
}

3.也可以采⽤循环的⽅式逐个字符打印字符串的内容。

#include <iostream>
#include <cstring>
using namespace std;
int main()
{char a[] = "hello world";int i = 0;for (i = 0; i < strlen(a); i++){cout << a[i];}cout << endl;//输出 hello world return 0;
} 

如果字符数组里没有'\0',不能构成字符串,又该如何打印呢?

#include <iostream>
#include <cstring>
using namespace std;
int main()
{char arr[] = {'a','b','c','d','e','f'};int sz = sizeof(arr)/sizeof(arr[0]);int i = 0;for(i = 0;i < sz; i++){cout << arr[i];}return 0;
}  

5. strcpy和strcat 

5.1.strcpy

使⽤字符数组可以存放字符串,但是字符数组能否直接赋值呢?

比如

char arr1[] = "abcdef";
char arr2[20] = {0};
arr2 = arr1;//这样这节赋值可以吗? 

就⾏整型数组中,我们说的过⼀样,这⾥也是不⾏的。那么如何将arr1中的字符串,拷⻉到arr2中呢? 其实C/C++中有⼀个库函数叫strcpy,可以完成。

char * strcpy ( char * destination, const char * source );//destination - 是目标空间的地址//source      - 是源头空间的地址//需要的头文件 <cstring> 

eg

#include <cstdio>
#include <cstring> using namespace std; int main()
{char arr1[] = "abcdef";char arr2[20] = {0};strcpy(arr2, arr1);printf("%s\n", arr2); //输出abcdef return 0;
} 

5.2.strcat 

有时候我们需要在⼀个字符的末尾再追加⼀个字符串,那字符数组能直接追加吗?

⽐如:

char arr1[20] = "hello ";
char arr2[] = "world";
arr1 += arr2;//这样也是不行的

那怎么办呢?C/C++中有⼀个库函数叫 strcat,可以完成

char * strcat ( char * destination, const char * source );//destination - 是目标空间的地址//source      - 是源头空间的地址//需要的头文件<cstring>  

eg

#include <cstdio>
#include <cstring> int main()
{char arr1[20] = "hello ";char arr2[] = "world";strcat(arr1, arr2);printf("%s\n", arr1);//输出hello world return 0;} 

除了上⾯的两个字符串相关函数外,其实C/C++中还提供了⼀些其他的函数,有兴趣的同学可以拓展学 习:https://legacy.cplusplus.com/reference/cstring/

http://www.dtcms.com/a/446004.html

相关文章:

  • 美发店会员管理系统更新
  • HTB Attacking GraphQL Skills Assessment
  • 从化区城郊街道网站麻二村生态建设共青城市建设局网站
  • C# 调用 onnx格式的YOLOv11n模型
  • 使用PyTorch构建你的第一个神经网络
  • 数据结构哈希表--c
  • 腾云公司做网站赣州创可通科技有限公司
  • 大模型预训练深度解析:从基座构建到目标设计
  • 记一次网络io学习流水账
  • 网站建设与推广的实训报告天门网站网站建设
  • vue可以做pc的网站asp网站如何建设
  • YOLO11框架训练高光谱数据归一化问题
  • 宿迁网站定制有什么手机网站
  • 温州服务网站建设毕设用别人网站做原型
  • 八股文:计算机网络
  • MOVS 和MOVZ
  • llama.cpp RMSNorm CUDA 优化分析报告
  • 24ICPC成都站补题
  • DAY 41 简单CNN-2025.10.5
  • 网站建设的图片怎么加水印剪辑软件
  • 【c++】面 向 对 象 与 抽 象 数 据 类 型
  • 国内网站设计制作泰安招聘信息最新招聘2022
  • 第十二章:代理模式 - 访问控制的守护大师
  • 用wordpress建立学校网站网络营销软文案例
  • C++11线程相关
  • 住房和城乡建设统计网站网站开发公司需要招聘哪些人
  • 小土堆pytorch
  • 环保网站 中企动力建设专业的网站建设网络
  • 触摸未来2025.10.05:悟神经网络符号之伤,拥抱声音的宇宙
  • 大连鼎信网站建设wordpress简历模板