C PRIMER PLUS——第6节:数组

目录

1. 数组的定义

2. 数组的格式

3. 数组的初始化

4. 数组的索引

5. 元素访问

6.遍历

7.内存和内存地址

8.数组练习

①写出10个数,找出最大值

②生成10个1-100之间的随机数存入数组并且求和

③定义一个数组,存入1-10,要求打乱数组中的所有数据顺序

④遍历数组比较最大值

9.数组常见算法

①查找算法

(1)基本查找/顺序查找

(2)二分查找/折半查找

(3)插值查找

②排序算法

(1)冒泡排序

(2)选择排序


1. 数组的定义

数组是一组具有相同数据类型的元素的集合,这些元素在内存中是连续存储的。也是一种容器,可以用来存储同种数据类型的多个值。


2. 数组的格式

①定义数组的一般格式为:数据类型(int)    数组名(arr)    [数组大小/长度]  ;

  • 数据类型:指定数组中每个元素的数据类型,如 intfloatchar 等。

  • 数组名:是用户为数组取的名称,遵循标识符命名规则。

  • 数组大小/长度:表示数组中元素的个数,必须是一个常量表达式。

②特点:连续的空间;一旦定义,长度不可变。

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int arr[80];//定义数组存储全班80位同学年龄
	double arr2[50];//定义数组存储全班50位同学身高
	double arr3[3];//定义数组存储全身每件衣服价格
	return 0;
}

3. 数组的初始化

①完全初始化:在定义数组时,为数组的每个元素提供初始值。

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

② 部分初始化:只对数组的部分元素提供初始值,未初始化的元素会被自动初始化为 0。

int arr[5] = {1, 2}; // 等价于 {1, 2, 0, 0, 0}

③省略数组大小:如果在初始化时提供了所有元素的值,可以省略数组大小,编译器会根据初始化列表的元素个数来确定数组的大小。

int arr[ ] = {1, 2, 3, 4, 5}; // 数组大小为 5 

 ④注意:

        (1)长度省略:数据值的个数就是数组长度。如:int arr [ ]={1,2,3}

        (2)长度未省略:数据值的个数≤长度。如:int arr [ 5 ]={1,2,3}   ——还有2个空位没有数字,用默认值0表示!


4. 数组的索引

数组的一个编号,也叫作:角标,下标,编号。数组的索引是从 0 开始的整数,用于访问数组中的元素。例如,对于一个包含 n 个元素的数组,其索引范围是从 0 到 n - 1

特点:从0开始,连续+1,不间断。


5. 元素访问

(1)定义:通过数组名和索引来访问数组中的元素。

(2)获取:

        变量 = 数组名 [ 索引 ]        或        printf( “ 占位符 ” ,数组名 [ 索引 ]);

        int num = arr [ 5 ]               或        printf( “ 占位符 ” ,arr [ 5 ]);

(3)修改:

        数组名 [ 索引 ] = 数据值;

        arr [ 5 ] = 10; 

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个长度为5的数组,并进行初始化:1,2,3,4,5
//要求:①获取索引为0,2,4并求和
//	    ②把最后一个索引元素修改为10
int main()
{
	int arr[] = { 1,2,3,4,5 };
	int num1 = arr[0];
	int num2 = arr[2];
	int num3 = arr[4];
	int sum = num1 + num2 + num3;
	printf("%d\n", sum);//9
	printf("修改前:%d\n", arr[4]);//修改前:5
	arr[4] = 10;
	printf("修改后:%d\n", arr[4]);//修改后:10
	return 0;
}

6.遍历

依次获取数组中的每一个元素

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//定义一个长度为5的数组,并进行初始化:1,2,3,4,5
//要求:遍历数组,并且把每一个元素打印到控制台
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	//利用循环遍历数组
	for (int i = 0; i < 5; i++)
	{
		//i:依次表示数组里面的每一个索引
		printf("%d\n", arr[i]);//1  2  3  4  5
	}
	return 0;
}

7.内存和内存地址

(1)定义

        ①内存:软件在运行时,用来临时存储数据的

        ②内存地址:编号(1格子=1字节)。作用是快速管理内存空间

                规则:

                        Ⅰ:32位操作系统,内存地址以32位的二进制表示。地址范围共计429496.7296个=4GB

                        Ⅱ:64位操作系统,内存地址以64位的二进制表示。地址范围共计0~2^64=17179TB=17.592.186GB

(2)C语言中的内存地址

int类型→4个字节        1个索引4个格子,1个格子8个0

#define  _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
//获取变量的内存地址
int main()
{
	int a = 10;
	printf("%p\n", &a);//00000052AAB4F684
	return 0;
}

(3)通过变量的首地址,就可以确定变量中存储的数据

(4)数组长度=总长度 / 数据类型占用的字节个数

(5)数组作为函数的形参,实际上传送是数组的首地址,如果要在函数中对数组进行遍历的话,记得一定要把数组的长度一起传送过去

(6)数组的索引越界:最小索引:0;        最大索引:长度-1


8.数组练习

①写出10个数,找出最大值

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
    int numbers[10] = { 23, 45, 12, 67, 89, 34, 56, 78, 90, 11 };
    int max = numbers[0];

    for (int i = 1; i < 10; i++) {
        if (numbers[i] > max) {
            max = numbers[i];
        }
    }

    printf("这 10 个数中的最大值是: %d\n", max);//这 10 个数中的最大值是: 90

    return 0;
}

②生成10个1-100之间的随机数存入数组并且求和

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    int arr[10];
    int sum = 0;
    srand(time(NULL));
    for (int i = 0; i < 10; i++) {
        arr[i] = rand() % 100 + 1;
        sum += arr[i];
    }
    printf("生成的 10 个 1 - 100 之间的随机数为: ");//生成的 10 个 1 - 100 之间的随机数为: 10 87 61 14 70 80 40 82 44 31
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    printf("这 10 个随机数的和为: %d\n", sum);//这 10 个随机数的和为: 519
    return 0;
}
  • srand(time(NULL)); 利用当前时间初始化随机数种子,保证每次运行生成的随机数不同。

  • rand() % 100 + 1 生成 1 到 100 之间的随机数。

③定义一个数组,存入1-10,要求打乱数组中的所有数据顺序

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    int arr[10];
    srand(time(NULL));
    for (int i = 0; i < 10; i++) {
        arr[i] = i + 1;
    }
    for (int i = 9; i > 0; i--) {
        int j = rand() % (i + 1);
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    printf("打乱顺序后的数组为: ");//打乱顺序后的数组为: 9 1 6 2 10 8 7 4 5 3
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}
  •  先把数组初始化为 1 到 10。
  • 采用 Fisher - Yates 洗牌算法打乱数组顺序,从数组末尾开始,随机选取前面的元素与当前元素交换。

④遍历数组比较最大值

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ARRAY_SIZE 10
int main() {
    int arr[ARRAY_SIZE] = { 34, 7, 23, 32, 5, 62, 15, 54, 90, 8 };
    int max = arr[0];
    for (int i = 1; i < ARRAY_SIZE; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    printf("数组中的最大值是: %d\n", max);//数组中的最大值是: 90
    return 0;
}
  • 数组定义:借助 #define 宏定义数组的大小 ARRAY_SIZE,接着定义了一个包含 ARRAY_SIZE 个元素的整数数组 arr,并且对其进行了初始化。
  • 最大值初始化:把数组的首个元素 arr[0] 赋值给变量 max,将其当作当前的最大值。
  • 数组遍历:利用 for 循环从数组的第二个元素(索引为 1)开始遍历整个数组。
  • 比较更新:在循环中,运用 if 语句比较当前元素 arr[i] 和 max 的大小,若当前元素大于 max,就把当前元素的值赋给 max
  • 输出结果:循环结束后,max 中存储的就是数组中的最大值,使用 printf 函数输出该值。

9.数组常见算法

①查找算法

(1)基本查找/顺序查找
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 顺序查找函数
int sequentialSearch(int arr[], int n, int target) {
    for (int i = 0; i < n; i++) {
        if (arr[i] == target) {
            return i; // 找到目标元素,返回其索引
        }
    }
    return -1; // 未找到目标元素,返回 -1
}
int main() {
    int arr[] = { 12, 34, 56, 78, 90, 23, 45, 67 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 45;
    int result = sequentialSearch(arr, n, target);
    if (result != -1) {
        printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 45 在数组中的索引是 6
    }
    else {
        printf("元素 %d 未在数组中找到\n", target);
    }
    return 0;
}
  • int sequentialSearch(int arr[], int n, int target):这是一个自定义函数,用于在数组里进行顺序查找。

    • int arr[]:表示要查找的数组。

    • int n:代表数组的元素个数。

    • int target:指的是要查找的目标元素。

  • for (int i = 0; i < n; i++):运用for循环逐个遍历数组元素。

  • if (arr[i] == target):在遍历过程中,若当前元素和目标元素相等,就返回该元素的索引i

  • return -1:若遍历完整个数组都没找到目标元素,就返回 -1 以表明未找到。

  • int main():程序的入口函数,程序从这里开始执行。

  • int arr[] = { 12, 34, 56, 78, 90, 23, 45, 67 };:定义并初始化一个整数数组arr

  • int n = sizeof(arr) / sizeof(arr[0]);:计算数组arr的元素个数。sizeof(arr)得到数组的总字节数,sizeof(arr[0])得到数组单个元素的字节数,二者相除便得到元素个数。

  • int target = 45;:定义要查找的目标元素为 45。

  • int result = sequentialSearch(arr, n, target);:调用sequentialSearch函数在数组arr里查找目标元素target,并把查找结果存于变量result中。

  • if (result != -1):对查找结果进行判断。若result不等于 -1,就意味着找到了目标元素,输出目标元素及其索引;反之,则输出未找到目标元素的信息。

  • return 0;:表示程序正常结束。

(2)二分查找/折半查找
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 二分查找函数
int binarySearch(int arr[], int left, int right, int target) {
    while (left <= right) {
        int mid = left + (right - left) / 2;

        if (arr[mid] == target) {
            return mid; // 找到目标元素,返回其索引
        }
        else if (arr[mid] < target) {
            left = mid + 1; // 目标元素在右半部分
        }
        else {
            right = mid - 1; // 目标元素在左半部分
        }
    }
    return -1; // 未找到目标元素,返回 -1
}

int main() {
    int arr[] = { 10, 20, 30, 40, 50, 60, 70, 80 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 40;
    int result = binarySearch(arr, 0, n - 1, target);
    if (result != -1) {
        printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 40 在数组中的索引是 3
    }
    else {
        printf("元素 %d 未在数组中找到\n", target);
    }
    return 0;
}

(3)插值查找
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 插值查找函数
int interpolationSearch(int arr[], int n, int target) {
    int left = 0, right = n - 1;

    while (left <= right && target >= arr[left] && target <= arr[right]) {
        if (left == right) {
            if (arr[left] == target) return left;
            return -1;
        }
        // 计算插值位置
        int pos = left + (((double)(target - arr[left]) / (arr[right] - arr[left])) * (right - left));
        if (arr[pos] == target) {
            return pos; // 找到目标元素,返回其索引
        }
        else if (arr[pos] < target) {
            left = pos + 1; // 目标元素在右半部分
        }
        else {
            right = pos - 1; // 目标元素在左半部分
        }
    }
    return -1; // 未找到目标元素,返回 -1
}

int main() {
    int arr[] = { 10, 12, 13, 16, 18, 19, 20, 21, 22, 23, 24, 33, 35, 42, 47 };
    int n = sizeof(arr) / sizeof(arr[0]);
    int target = 18;
    int result = interpolationSearch(arr, n, target);
    if (result != -1) {
        printf("元素 %d 在数组中的索引是 %d\n", target, result);//元素 18 在数组中的索引是 4
    }
    else {
        printf("元素 %d 未在数组中找到\n", target);
    }
    return 0;
}

②排序算法

(1)冒泡排序
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

// 冒泡排序函数
void bubbleSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                // 交换 arr[j] 和 arr[j+1]
                int temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

int main() {
    int arr[] = { 64, 34, 25, 12, 22, 11, 90 };
    int n = sizeof(arr) / sizeof(arr[0]);
    bubbleSort(arr, n);
    printf("排序后的数组: ");//排序后的数组: 11 12 22 25 34 64 90
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

(2)选择排序
#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
// 选择排序函数
void selectionSort(int arr[], int n) {
    for (int i = 0; i < n - 1; i++) {
        int minIndex = i;
        for (int j = i + 1; j < n; j++) {
            if (arr[j] < arr[minIndex]) {
                minIndex = j;
            }
        } // 交换 arr[i] 和 arr[minIndex]
        int temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
}
int main() {
    int arr[] = { 64, 25, 12, 22, 11 };
    int n = sizeof(arr) / sizeof(arr[0]);
    selectionSort(arr, n);
    printf("排序后的数组: ");//排序后的数组: 11 12 22 25 64
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值