小白初识嵌入式day7

C语言数组学习笔记

一、数组定义

在C语言中,为统计一类数据,引出数组!

数组的定义形式为:类型说明符 数组名[常量表达式] ,其中:

• (1) 类型说明符:用于明确数组中存储的数据类型,例如int表示存储整型数据,float表示存储浮点型数据 。

• (2) 数组名:类似变量名,用于标识整个数组。它具有以下特性:

◦ 数据类型:数组名代表整个数组这种数据类型,通过sizeof(数组名)可以获取整个数组所占的内存字节数。

◦ 值:数组名代表数组首元素的地址,也是整个数组的起始地址,由于数组在内存中是连续存储的,通过该地址可以访问数组的所有元素。

• (3) 常量表达式:用[]括起来,用于指定数组的长度,即相同类型数据的个数。在定义数组时,[]明确表示定义的是一个数组。判断数据类型的通用方法是去掉变量名(标识符),剩下的部分即为数据类型。

数组大小的计算方式为:数组大小 = sizeof(数据类型) * 数组长度 ,由此可推导出 数组长度 = sizeof(数组名) / sizeof(单个数据类型) 。

二、数组特点

1. 单一性:数组中所有元素的类型必须一致,例如int类型的数组只能存储整型数据。

2. 连续性:数组在内存中开辟的是一块连续的内存空间,这使得数组元素的访问效率较高。

3. 有序性:数组元素按照顺序依次存储,每个元素都有唯一的下标,通过下标可以快速访问对应元素。

三、数组的初始化和赋值

(一)初始化

1. 全部初始化:int a[10] = {1,2,3,4,5,6,7,8,9,10}; ,使用花括号{}将所有初始值列出,依次赋给数组元素。

2. 部分初始化:int a[10] = {1,2,3,4,5}; ,只对前面部分元素赋值,未初始化的元素默认初始化为0。

3. 未初始化:int a[10]; ,此时数组中的元素值为随机值(垃圾值)。

4. 初始化全0数组:

◦ int a[]={}; ,定义时省略数组长度,根据初始化列表为空,编译器会创建一个长度为0的数组。

◦ int a[]={0}; ,定义一个长度为1且元素值为0的数组。

(二)赋值

1. 计算赋值:通过循环计算出一些值并赋值到数组中,示例代码如下:
for (int i = 0; i < len; ++i) {
    a[i] = 表达式;
}
2. 键盘输入赋值(动态定义):从键盘读取数据赋值给数组元素,示例代码如下:
for (int i = 0; i < len; ++i) {
    scanf("%d", &a[i]);
}
特别注意:在动态定义数组长度时,如int i; scanf("%d", &i); int a[i]; ,i的定义与scanf语句必须在定义数组a之前,否则编译器无法分配空间,会导致报错。

四、数组元素引用

通过 数组名[下标] 的方式引用数组元素,需要注意:

1. 数组下标可能越界,且编译时不会报错(因为没有语法错误),需要程序员在编程过程中仔细检查,避免出现逻辑错误。

2. 下标取值范围是[0,数组长度 - 1] 。

3. 数组长度必须是整型。

4. 定义数组时,数组长度可以省略,但前提是必须进行初始化,实际长度取决于初始化元素的个数,如int[]={1,2} ,若不初始化直接省略长度,编译器无法分配空间,会报错。

5. 数组不能整体赋值,只能对具体元素进行单个操作。

五、经典算法:排序与逆序

 

(一)选择排序

 

• 思想:每轮从剩余元素中选最小值,与当前位置交换。

 

• 步骤:

 

1. 外层循环控制当前位置i。

 

2. 内层循环从i+1到末尾找最小值下标j。

 

3. 交换a[i]与a[j]。

 

• 代码示例:

for (i=0; i

    min = i;

    for (j=i+1; j

        if (a[j] < a[min]) min = j;

    }

    swap(&a[i], &a[min]);

}

(二)冒泡排序

 

• 思想:相邻元素两两比较,大的后移(类似气泡上浮)。

 

• 步骤:

 

1. 外层循环控制轮数(n-1轮)。

 

2. 内层循环从0到n-1-i,比较a[j]与a[j+1],逆序则交换。

 

• 代码示例:

for (i=0; i

    for (j=0; j

        if (a[j] > a[j+1]) swap(&a[j], &a[j+1]);

    }

}

(三)数组逆序

 

• 思路:首尾元素交换,逐步向中间逼近。

 

• 代码示例:

for (i=0; i

    temp = a[i];

    a[i] = a[n-1-i];

    a[n-1-i] = temp;

}

七、常见问题与练习

 

1. 动态定义数组(C99):

int n; scanf("%d", &n);  // 需在定义前赋值

int a[n];                // 可变长数组

2. 练习场景:

 

◦ 找出数组中能被3整除的元素。

 

◦ 求最大值(“打擂台”法,初始值设为a[0])。

 

◦ 数组循环移动(如输入n,将末尾n个元素移到开头)。

3、关键注意事项

 

• 数组名本质是地址,但sizeof(数组名)返回整个数组大小(非指针长度)。

 

• 初始化时省略长度需确保有初始值,否则编译报错。

 

• 排序算法需熟练掌握逻辑与代码实现,可结合流程图辅助理解。

 

大算法程序:

(一)选择排序

选择排序的基本思想是将每个元素与它后面全部元素比较,如果后面存在元素小于它,则换位,每轮小循环都会找出当前轮次最小元素,可实现从低到高排序。示例代码如下:
#include

int main(void) {
    int n;
    printf("Input a num:");
    scanf("%d", &n);
    int a[n];

    int i = 0;
    for (i = 0; i < n; ++i) {
        scanf("%d", &a[i]);
    }

    for (i = 0; i < n; ++i) {
        printf("%d ", a[i]);
    }
    putchar('\n');

    int j = 0;
    for (i = 0; i < n - 1; ++i) {  // 控制位置
        for (j = i + 1; j < n; ++j) {  // 控制选择合适的数
            if (a[i] > a[j]) {
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
            }
        }
    }

    for (i = 0; i < n; ++i) {
        printf("%d ", a[i]);
    }
    putchar('\n');

    return 0;
}
(二)冒泡排序

冒泡排序的核心是当后一元素大于前一元素时进行交换,这样每轮循环的开始元素都是那一轮循环的最小值,从而实现将数组从小到大排序。示例代码如下:
#include
int main() {
    int a[5] = {2, 3, 5, 8, 4};
    int i, j, tmp;
    int len = sizeof(a) / sizeof(a[0]);
    for (i = 0; i < len - 1; i++) {
        for (j = 0; j < len - 1 - i; j++) {
            if (a[j] > a[j + 1]) {
                tmp = a[j];
                a[j] = a[j + 1];
                a[j + 1] = tmp;
            }
        }
    }
    for (i = 0; i < len; i++) {
        printf("%d ", a[i]);
    }
}

 

你可能感兴趣的:(嵌入式硬件,嵌入式实时数据库)