数组
一维数组
一维数组定义
数组的概述
所谓数组,就是一个集合,里面存放了相同类型的数据元素
特点:
1. 数组中的每个数据元素都是相同的数据类型
2. 数组是由连续的内存位置组成的
一维数组定义方式
一维数组定义的方式有三种:
- 数据类型 数组名 [ 数组长度 ];
如:int array[10];
- 数据类型 数组名 [ 数组长度 ] = { 值1,值2,… };
如:int array[5] = { 1,2,3,4,5 };
注意:如果初始值的元素不够数组长度就会用0代替
int array[ 5 ] = { 1,2 }; // 1 2 0 0 0
**给数组所有元素初始化为 0 **
int array [ 5 ] = { 0 };
指定下标位置的部分初始化
int array [ 5 ] = { [ 1 ] = 1, [ 3 ] = 3 };
- 数据类型 数组名 [ ] = { 值1,值2,… };
如:```int array[ ] = { 1,2,3,4,5 };`` (最大元素个数由初始化时决定)
数组元素访问方式
访问方式:
数组名 + [ 索引位置 ] 访问数组中对应的元素
0 号下标对应第一个数组元素
如:
int array[ 5 ] = { 1,2,3,4,5 };
array[ 0 ] 对应的元素就是1
array[ 1 ] 对应的元素就是2
…
array[ 4 ] 对应的元素就是5
注意:元素下标的有效范围是从 0 开始 到数组元素个数 -1
一维数组数组名
统计数组占用内存大小
假设有数组:int arr[ 5 ] = {1,2,3,4,5};
数组占用内存空间大小:sizeof(arr);
每个数据占用空间大小:sizeof(arr[0]);
数组中元素的个数:sizeof(数组名) / sizeof(int(数据类型));
获取到数组元素地址
假如有数组:int arr[5] = {1,2,3,4,5};
数组的首地址:arr(%p可以用十六进制显示 %d用十进制显示地址)
数组中第一个元素的地址:&arr[0];
数组中第三个元素的地址:```&arr[2];
数组名注意事项
- 数组名是常量,不可以赋值
数组逆置
#include <stdio.h>
#include <stdlib.h>
// 数组逆置
void welcome()
{
int a[5] = { 2,3,6,4,1 };
printf("逆置前的数组是:\n");
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d", a[i]);
}
printf("\n");
int we1 = 0; // 首下标
int we2 = sizeof(a) / sizeof(int) - 1; //未下标
while (we1 < we2) // 首下标 < 尾下标
{
int c = a[we1]; //存放首下标
a[we1] = a[we2]; // 首标和尾标交换
a[we2] = c; // 尾标和首标交换
we1++; // 首标++
we2--; // 尾标--
}
printf("逆置后的数组是:\n");
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d",a[i]);
}
printf("\n");
}
int main()
{
welcome();
system("pause");
return EXIT_SUCCESS;
}
冒泡排序
最常用的排序算法,对数组内元素进行排序(从大到小或者从小到大)
小到大排序
#include <stdio.h>
#include <stdlib.h>
// 冒泡排序 从小到大
void max1()
{
int a[8] = { 2,1,6,3,4,9,8,7 };
printf("排序前是:\n");
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d ", a[i]);
}
printf("\n");
//外层循环
for (int i = 0; i < sizeof(a) / sizeof(int) - 1; i++)
{
//内层循环 每次循环内存循环就总数组元素 - 外存循环次数 - 末尾最大所有不用在比较
for (int j = 0; j < (sizeof(a) / sizeof(int) - i - 1); j++)
{
// 当前下标元素 > 相邻下标 就进行交换
if (a[j] > a[j + 1])
{
int c = a[j]; // 临时存放最大值
a[j] = a[j+1]; // 小值在前
a[j+1] = c; // 大值在后
}
}
}
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
int main()
{
max1();
system("pause");
return EXIT_SUCCESS;
}
二维数组
二维数组定义
二维数组概念
概述:二维数组就是在一维数组基础上,多加了一个维度
特点:
- 数组中的每个数据元素都是相同的数据类型
- 二维数组本质也是由连续的内存位置组成的,人为划分成两个维度
二维数组定义方式
二维数组有四种定义方式:
- 数据类型 数组名[ 行数 ][ 列数 ];
- (推荐使用)数据类型 数组名[ 行数 ][ 列数 ] = {{ 数据1,数据2 },{ 数据3,数据4 }};
- 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
- 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4 };
数组元素访问方式
语法:数组名 + [ 行索引 ][ 列索引 ] 访问数组中对应的元素
[ 0,0 ]号下标对应第一个数组元素
如:int arr[2][3] = {1,2,3,4,5,6};
arr[0][0]:对应的元素就是 1
arr[0][1]:对应的元素就是 2
arr[0]][2]:对应的元素就是 3
arr[1][0]:对应的元素就是 4
arr[2][0[:对应的元素就是 5
arr[3][0]:对应的元素就是 6
遍历:
for(int i = 0; i < 行;i++)
{
for(int j = 0;j < 列; j++)
{
printf("%d",a[行][列]);
}
printf("\n");
}
二维数组数组名
统计数组占用内存大小
如:int a[2][3] = {1,2,3,4,5,6};
数组占用内存空间大小:sizeof(a);
每行占用空间大小:sizeof(arr[0]);
每个元素占用空间:sizeof(a[0][0]);
获取数组行数列数
如:int a[2][3] = {1,2,3,4,5,6};
行数 = 总大小 / 每行的大小:sizeof(a) / sizeof(a[0]);
列数 = 每行的大小 / 每个元素的大小:sizeof(a[0]) / sizeof(a[0][0]);
获取到数组元素地址
如:int a[2][3] = {1,2,3,4,5,6};
二维数组的首地址:a(%p可以用十六进制显示 %d用十进制显示地址)
二维数组第一行地址:a[0];
二维数组第二行地址:a[1];
数组中第一个元素的地址:&a[0][0];
数组中第二个元素的地址:&a[0][1];
数组名注意事项
二维数组名也是常量,不可以赋值
分数统计
#include <stdio.h>
#include <stdlib.h>
// 求总值和平均值
void scores()
{
// 创建二维数组
int scor[3][3] =
{
{100,100,100},
{90,80,20},
{30,10,70}
};
// 行数
int row = sizeof(scor) / sizeof(scor[0]);
// 列数
int col = sizeof(scor[0]) / sizeof(scor[0][0]);
for (int i = 0; i < row; i++)
{
// 存放总值
int sum = 0;
for (int j = 0; j < col; j++)
{
sum += scor[i][j];
}
printf("第 %d 总值是:%d\n", i+1, sum);
// 保留小数点后两位 1.0*转为小数类型
printf("第 %d 平均值是: %.2lf\n",i+1, 1.0*sum / col);
}
}
int main()
{
scores();
system("pause");
return EXIT_SUCCESS;
}
字符数组
字符数组初始化
字符数组定义方式
定义语法:char 数组名 [ 数组长度 ];
如:char a[5];
:声明字符数组,每个元素都是 char 类型,共有 5 个元素
字符数组的基本操作
- 逐个初始化字符数组
char a[3] = { 'w','q','l' };
- 错误因为没有 \0(零) 输出乱码
-
- 正确
- 注意 \0 本质就是 0 代表结束,占一个元素位置,也可以留一个位置系统会自动在空位补0,
-
整体初始化字符数组
语法:char a[] = "hello"; //自带 \0
-
遍历字符数组
遍历字符数组时,可以利用循环逐个字符遍历,也可以利用 %s 进行遍历
printf( "%s\n",a ); // %s从开始 a 到 \0 结束
字符串长度统计
字符串统计方式
- sizeof 统计
统计字符串占用内存空间大小 - strlen 统计
统计字符串长度,遇到 ‘\0’ 结束统计且不计入 ‘\0’,头文件#include <string.h>
注意:转义字符只占一个位置
字符串统计sizeof()和strlen()区别
sizeof();会先判断初始化有没有,有就输出初始化值,没有就统计元素,会加上‘\0’结束符,遇到中间有‘\0’符不会停止统计,会把整数数组的元素全部统计完
strlen();只统计数组里面的元素,遇到‘\0’结束,如果数组中有一个’\0’就会退出
如:
char a[32] = "hello";
// sizeof() = 32
// strlen() = 5;
char b[] = "h";
// sizeof() = 2; 加上尾部‘\0’
// strlen() = 1; 不会统计 '\0'
char c[] = "hello\0a";
// sizeof() = 8;
// strlen() = 5; 遇到‘\0’结束
字符串输入输出
字符串的输入
- scanf()函数
语法:scanf( “%s”,数组首地址 );
特点:遇到空格结束输入,不检测溢出 - gets()函数
语法:gets(数组首地址);
特点:可以输入空格,不检测溢出 - fgets()函数
语法:fgets(数组首地址,最大输入字符个数,stdin); // stdin 代表标准输入设备键盘
特点:可以输入空格,检测溢出,只保留最大输入字符数 -1
如:fgets(a,sizeof(a),stdin);
注意:需要把多出的 \n 去掉a[strlen(a) -1] = '\0';
因为可以输入空格也会输入换行 把\n改为\0
字符串的输出
- printf()函数
语法:printf(“%s”,数组首地址); - puts()函数
语法:puts(数组首地址);
特点:自带换行 - fputs()函数
语法:fputs(数组首地址,stdout); // stdout 代表标准输出设备屏幕
特点:不带换行