
C语言5,数组
数组
5.1 定义
数组是一种数据结构,用于存储多个相同数据类型的值
格式是:数据类型 数据名 [长度]
特点:
- 连续的空间
- 一旦定义后长度不可变
5.2 数组的初始化
定义数组的时候,第一次给数组赋值
若省略长度,则编译器根据初始化列表的元素个数自动确定数组长度
若不省略长度,则初始化时不得超过该长度
没有定义的部分默认为 0/ 0.0/ '\0'/ NULL(整数,浮点数,字符,字符串)
int arr [5] = {4,6,1,9,4};
5.3 元素访问
5.3.1 索引
从0开始,连续+1,不间断
5.3.2 获取
变量 = 数组名[索引]
int arr [5] = {4,6,1,9,4};
int num1 = arr[2]; //获取第三个数,即1
5.3.3 修改
数据名[索引] = 数据值
int arr [5] = {4,6,1,9,4};
arr[3] = 8; //修改第四个元素为8
5.4 遍历
依次获取数组中的每一个元素
for(int i=0; i<5; i++){
printf("%d\n", arr[i]);
}
5.5 内存中的数组
printf("%d\n",arr[2]);
printf(*(arr + 2));
5.6 数组的长度
int len = sizeof(arr) / sizeof(arr[0]);
len即为数据的个数
5.7 数组的算法题
一定要自己动手写!!!
5.7.1 求最值
已知一个整数数组,找出数组中的最大值并打印在控制台
例:已知数组元素为 {33, 5, 22, 44, 55}
#include<stdio.h>
int main(){
int arr[] = {33,5,22,44,55};
int max = arr[0];
int len = sizeof(arr) /sizeof(arr[0]);
for(int i = 1; i < len; i++){
if(arr[i] > max){
max = arr[i];
}
}
printf("%d\n",max);
return 0;
}
思路:利用第三方变量储存数组里面的第一个值,再依次进行比较,将较大的数储存在变量里面,最后打印
5.7.2 数组求和(基础)
生成10个1~100之间的随机数存入数组
- 求出所有数据的和
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){
//定义数组
int arr[10];
int len = sizeof(arr) / sizeof(arr[0]);
//生成随机数
srand(time(NULL));
for(int i = 0; i < len; i++){
int num = rand() % 100 + 1;
//把随机数存入数组
arr[i] = num;
}
/* 验证是否成功生成随机数的代码
for(int i = 0; i < len; i++){
printf("%d\n",arr[i]);
}
*/
//求和数据
int sum = 0;
for(int i = 0; i < len; i++){
sum += arr[i];
}
//输出求和
printf("%d\n",sum);
return 0;
}
5.7.3 数组求和,求平均数,统计
生成10个1~100之间的随机数存入数组,且不能重复
- 求出所有数据的和;
- 求所有数据的平均数;
- 统计有多少个数据比平均数少;
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int if_same(int arr[], int len, int num);
int main(){
//定义数组
int arr[10];
int len = sizeof(arr) / sizeof(arr[0]);
//生成随机数
srand(time(NULL));
for(int i = 0; i < len;){
int num = rand() % 100 + 1;
//存入之前,先做判断
int flag = if_same(arr, len, num);
if(!flag){
arr[i] = num;//赋值
i++;
}
}
// 打印所有随机数的代码
printf("numbers:");
for(int i = 0; i < len; i++){
printf("%d ",arr[i]);
}
printf("\n");
//求和数据
int sum = 0;
for(int i = 0; i < len; i++){
sum += arr[i];
}
//输出求和
printf("sum:%d\n",sum);
//求平均数
int avg = sum / len;
//打印平均数
printf("average:%d\n",avg);
//统计有几个数字比平均数小
int num1 = 0;
for(int i = 0; i < len; i++){
if(arr[i] < avg){
num1++;
}
}
//输出小于平均数的个数
printf("The number of numbers smaller than the average:%d\n",num1);
}
//判断num是否在数组中存在
//若存在,返回1
//若不存在,返回0
int if_same(int arr[], int len, int num){
for(int i = 0; i < len; i++){
if(arr[i] == num){
return 1;
}
}
return 0;
}
这个程序以时间生成随机数,所以你在一秒钟之内运行多次程序后会发现随机的数是一样的
5.7.4 反转数组
键盘录入5个数据并存入数组
- 遍历数组
- 反转数组
- 再次遍历
#include<stdio.h>
void printArr(int arr[5], int len);
int main(){
//定义数组
int arr[5];
int len = sizeof(arr) / sizeof(int);
//键盘录入
for(int i = 0; i < len; i++){
printf("Please write the number %d:", i+1);
scanf("%d", &arr[i]);
}
//打印数组
printf("The numbers:\n");
printArr(arr, len);
//反转数组
int i = 0;
int j = len - 1;
while(i < j){
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
i++;
j--;
}
//打印数组
printf("The numbers:\n");
printArr(arr, len);
return 0;
}
//打印程序函数
void printArr(int arr[5], int len){
for(int i = 0; i < len; i++){
printf("%d\n", arr[i]);
}
}
在Microsoft Visual Studio 2022中,scanf()可能被视为不安全的写法,可将其替换为scanf_s()
5.7.5 打乱数组
定义一个数组,存入1~5
打乱数组中所有数据的顺序
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main(){
//定义数组
int arr[5] = {1,2,3,4,5};
int len = sizeof(arr) / sizeof(arr[0]);
//打印数组
printf("numbers:");
for(int i = 0; i < len; i++){
printf("%d ",arr[i]);
}
//生成随机数
srand(time(NULL));
//随机交换
for (int i = 0; i < len; i++){
int index = rand() % len;
//交换
int temp = arr[i];
arr[i] = arr[index];
arr[index] = temp;
}
//打印数组
printf("\n");
printf("numbers:");
for(int i = 0; i < len; i++){
printf("%d ",arr[i]);
}
return 0;
}
5.8 内存分配方式
-
静态数组:
内存在编译时分配(即在栈上分配内存)
数组的大小必须在编译时确定,定义后大小不能更改例如:
int arr[10]; // 静态数组,大小为10,编译时确定
-
动态数组:
内存在运行时通过堆(heap)动态分配
可以根据需求在运行时确定数组的大小,并且可以随时重新调整大小-
例如:
int* arr = (int*)malloc(10 * sizeof(int)); // 动态数组,使用malloc分配10个元素的空间
-
5.8.1 内存管理
-
静态数组:
内存由编译器自动管理,当数组超出其作用范围时(如函数结束后),内存自动释放。
内存管理比较简单,不需要手动释放。 -
动态数组:
需要手动管理内存,分配的内存必须在使用完后手动释放,否则会造成内存泄漏。
释放内存时使用free()
函数,例如:free(arr); // 手动释放内存
5.8.2 大小调整
-
静态数组:
大小固定,不能在运行时调整。
例如:
int arr[10]; // 无法在运行时调整大小
-
动态数组:
可以在运行时调整大小,常通过
realloc()
函数重新分配内存空间。例如:
arr = (int*)realloc(arr, 20 * sizeof(int)); // 调整动态数组大小为20
5.8.3 性能与效率
- 静态数组:由于在栈上分配内存,栈的访问速度较快,性能较高。
适合较小的数组(因为栈的空间有限),如函数局部数组。 - 动态数组:在堆上分配内存,内存管理更灵活,但分配和释放内存的开销较大。
适合需要存储大量数据的情况。
5.8.4 使用场景
-
静态数组:
适用于数组大小已知且不需要在运行时调整的场景,常用于局部变量或程序生命周期固定的场景。
-
动态数组:
适用于数组大小不确定或需要根据用户输入、文件数据等动态改变的场景。
5.8.5 代码示例
5.8.5.1 静态数组:
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5}; // 静态数组
for (int i = 0; i < 5; i++) {
printf("%d ", arr[i]);
}
return 0;
}
5.8.5.2 动态数组:
#include <stdio.h>
#include <stdlib.h>
int main() {
int* arr = (int*)malloc(5 * sizeof(int)); // 动态数组
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
printf("%d ", arr[i]);
}
free(arr); // 释放内存
return 0;
}
5.8.6 总结
- 静态数组:固定大小、在栈上分配、内存管理简单。
- 动态数组:灵活调整大小、在堆上分配、需要手动管理内存。