目录
4、用 strlen 与 sizeof 计算字符数组长度(元素个数)的区别
一、一维数组
(一)概念
数组是一组相同类型元素的集合
注:
数组中存放的是 1 个或多个数据,但数组元素个数不能为0(即什么都不写);
数组存放的多个数据,类型是相同的
(二)创建和初始化
1、创建
基本语法如下:
注:
若创建了如下数组:
int arr[10];
① 数组中每个元素的类型是 int,数组的类型是 int [10] ;
② 数组元素类型、元素个数 的改变都会改变数组的类型,如 char [5],double [12];
③ 数组只创建不赋值,数组元素的值是随机的
2、初始化
使用【大括号 { }】来初始化
完全初始化:
int arr1[5] = {1,2,3,4,5};
不完全初始化:
int arr2[6] = {1};
第⼀个元素初始化为1,剩余的元素默认初始化为0
不指定长度初始化:
int arr3[] = {1,2,3,4,5}
会根据初始化的元素个数,自动计算数组的长度
注:
① 若【被定义的数组长度】与【数组初始化时提供的初值个数】不相同,则【代表数组长度的数字】不能省略;
② 【大括号 { }】中不能有空值
int arr[3] = { };
int arr[3] = {1,,3};
初始化写法均为错误
(三)使用
C语言规定,只能引用数组中的元素,不能引用整个数组;
单个元素的引用形式为:
1、下标
C语言规定数组是有下标的,下标是从0开始的,假设数组有n个元素,最后⼀个元素的下标是n-1,下标就相当于数组元素的编号
注:下标最大值 == 数组的【总长度 or 总的元素个数】 - 1
2、下标引用操作符
中括号 [ ] 为下标引用操作符;
① 数组初始化时 [ ] 中的数字是指定数组元素个数(数组长度);
② 数组使用时 [ ] 中的数字是数组的下标
注:
#include<stdio.h>
int main()
{
int i, arr[10];
for(i = 0;i<10;i++)
{
scanf("%d", &arr[i]);
}
return 0;
}
① arr 是数组名,表示的是数组首元素的地址;
② arr [ i ] 看作是普通变量来进行使用,当使用 scanf 时需要取地址&arr [ i ];
③ 取地址操作符 & —— 取出【变量在内存中的地址】;
④ 注意数组的合法引用范围 arr[0]~arr[9]
(四)在内存中的存储
①数组在内存中是连续存放的;
②随着数组下标的增长,地址也是由小到大(低到高)变化【万丈高楼平地起】
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
二、二维数组
(一)概念
把【一维数组】做为【数组的元素】,这时候就是【二维数组】
(二)创建和初始化
1、创建
基本语法如下:
理解为:
①
类型说明 数组名 [ 多少个一维数组 ] [ 每个一维数组中有多少元素 ] ;
或者
类型说明 数组名 [ 行 ] [ 列 ] ;
②
int a[3][4];
相当于定义了12个元素
2、初始化
(1)不完全初始化
int arr1[3][5] = {1,2};
int arr2[3][5] = {0};
(2)完全初始化
int arr3[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
(3)按照行初始化
int arr4[3][5] = {{1,2},{3,4},{5,6}};
(4)初始化时省略行,但不能省略列
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}};
(三)使用
引用下标使用:
int arr[3][5] = {1,2,3,4,5, 2,3,4,5,6, 3,4,5,6,7};
注:
① 注意数组的合法引用范围
② 按列打印:把按行打印的参数调换就行
(四)在内存中的存储
①数组在内存中是连续存放的;
②随着数组下标的增长,地址也是由小到大(低到高)变化
int arr[3][5] = { 0 };
三、有意思的点
(一)字符数组
字符数组不仅能保存字符,还能保存字符串
1、概念
存放字符数据的数组就是字符数组,字符数组中的一个元素存放一个字符
char arr[11];
arr[0] = 'I';
arr[1] = ' ';
arr[2] = 'l';
arr[3] = 'i';
arr[4] = 'k';
arr[5] = 'e';
arr[6] = ' ';
arr[7] = 'p';
arr[8] = 'i';
arr[9] = 'z';
arr[10] = 'z';
arr[11] = 'a';
2、创建与初始化
(1)完全初始化,最好理解
char arr[11] = {'I',' ','l','i','k','e',' ','p','i','z','z','a'};
(2)省略长度初始化
char arr[] = {'I',' ','l','i','k','e',' ','p','i','z','z','a'};
3、保存字符与字符串的区别
区别:字符数组保存字符串会被系统自动填充进去一个 ' \0 ' 字符
char arr1[] = {'I',' ','l','i','k','e',' ','p','i','z','z','a'};
数组arr1长度为11,除非手动加入
arr[12] = 0; 或 arr[12] = '\0'; ('\0'的ASCII码值是0,可互通使用)
否则输出字符串时带有垃圾信息:
printf("%s", arr1);
输出:直到找到\0为止的信息
char arr2[] = "I like pizza";
等价于
char arr3[] = {'I',' ','l','i','k','e',' ','p','i','z','z','a','\0'};
数组arr2的长度为12,系统自动填入字符'\0'
按字符串输出数组arr2, 数组arr3无垃圾信息
printf("%s", arr2);
printf("%s", arr3);
输出均为:I like pizza
4、用 strlen 与 sizeof 计算字符数组长度(元素个数)的区别
strlen 是求字符串长度,只能针对字符串或字符数组;
sizeof 求内存大小
(1)字符数组中保存字符串
strlen(字符数组):得到字符串长度,本函数执行的结果值为字符串的实际长度,但不包括字符串结束标记 ' \0 ' ;(知识篇(一),十二,(五),中介绍部分)
sizeof(类型):返回的是所占用的内存大小,在字符数组中长度计算包括字符串结束标记 ' \0 ' ;(知识篇(二),一,(一),5,中介绍)
所以字符数组中保存字符串时:
① strlen(数组名)== ' \0 ' 的下标;
② sizeof(数组名)/ sizeof(数组首元素)- 1 == ' \0 ' 的下标
③ sizeof 的一般使用:sizeof(数组名)/ sizeof(数组首元素)- 1 == 数组最后一个元素的下标
(2)字符数组中保存字符
char arr1[] = "I like zaizai!";
char arr2[] = {'I',' ','l','i','k','e',' ','z','a','i','z','a','i','!'};
printf("arr1的strlen计算数组元素个数的结果为:%zd\n", strlen(arr1)); printf("arr2的strlen计算数组元素个数的结果为:%zd\n", strlen(arr2));
① strlen() 的结果与【字符数组中保存的内容】有关,strlen() 会计算 ' \0 ' 之前的字符内容,若字符数组中储存的是字符且不手动添加 ' \0 ' ,strlen()则会在数组后面继续找,直到找到 ' \0 '为止,然后返回计算' \0 ' 之前的内容有多少个:
arr1的strlen计算数组元素个数的结果为:14 arr2数组'\0'之前有14个字符 arr2的strlen计算数组元素个数的结果为:45 arr2数组继续向后找32个字符才找到'\0'
printf("arr1的sizeof计算数组元素个数结果为:%zd\n", sizeof(arr1) / sizeof(arr1[0])); printf("arr2的sizeof计算数组元素个数结果为:%zd\n", sizeof(arr2) / sizeof(arr2[0]));
② sizeof() 的结果与【变量或数据类型中保存的的数值内容】无关,直接返回所占内存大小:
arr1的sizeof计算数组元素个数结果为:15 arr2的sizeof计算数组元素个数结果为:14 arr1数组比arr2数组多一个隐藏的'\0'
(二)sizeof 计算数组的元素个数
为了增加代码的灵活性,使用 sizeof 函数来计算数组元素个数;
理解为:总大小 / 每个元素的大小 = 元素个数
int main()
{
int a[10] = { 0 };
int sz = sizeof(a) / sizeof(a[0]);
printf("数组a的元素个数为:%d\0", sz);
return 0;
}
输出:数组a的元素个数为:10
(三)C99中的变长数组
C99中给一个变长数组(variable-length array,简称 VLA)的新特性,允许我们可以使用变量指定数组大小;
变长数组的根本特征,就是数组长度只有运行时才能确定,所以变长数组不能初始化;
【变长数组大小】要在【创建】之前确定
int n = 0;
scanf("%d", &n);
int arr[n];
遗憾的是在VS2022上,虽然支持大部分C99的语法,没有支持C99中的变长数组,没法测试,但在牛客刷题时可以使用
#include <stdio.h>
int main()
{
int n = 0;
scanf("%d", &n);//根据输⼊数值确定数组的⼤⼩
int arr[n];
int i = 0;
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
(四)计算平均数溢出的解决方法
平均数 = 小 + (大 - 小)/2
以上博客仅供分享