内容
1.数组知识点
2.数组置换
3.数组逆序
4.冒泡排序
*1.数组知识点
数组创建:
type_t arr_name [const_n];
//type_t 是指数组的元素类型
//const_n 必须是一个常量表达式,用来指定数组的大小
int arr1[] = {1,2,3,4};
int arr2[5] = {1,2,3,4,5};
int arr3[2]={1}; //不完全初始化
int len = sizeof(arr1) / sizeof(arr1[0]); //计算数组元素个数,4
一维数组数组名的使用:
- 计算一维数组元素个数: * sizeof(数组名) / sizeof(数组名[0])
- 获取数组中一个元素的地址: printf("%p\n", &arr1[3]); //%p 打印格式为指针型 ,指向该数组元素的地址.
- 可以统计整个数组在内存中所占的长度; // sizeof(数组名) 数组存储在内存中分配的是一段连续的内存空间
- printf(“一维数组arr1的首地址为:%p\n”, arr1);
- 数组名是常量,不能进行赋值操作(表达式是不可修改的左值);
注意:
(1) 如果创建数组时,不想直接指定元素个数,就得进行初始化.如果明确了数组元素个数,未进行初始化的元素默认为0; 数组元素下标从0~len-1;
(2) 使用printf()函数打印输出时, %d-格式为整型; %p-格式为指针型,用于打印变量地址; %s-表示打印为字符型;%f-表示打印为浮点型…
char str[]="hello";
char arr[]={'h','e','l','l','o'};
- sizeof(str)=6 ; 一个字符串数组,在内存中字符串后面隐式包含’ \0’,一个字符占一个字节;
- strlen(str)=5; arr数组表示含有字符型变量5个单字符的数组;
- strlen(arr);结果是一个随机数,strlen函数遍历字符串遇到’\0’才会停之;arr数组元素检测完还会继续向后检测,直到遇到’\0’是才终止,因此答案为不确定;
二维数组的创建同理,相当于两个一维数组,多了一维:
int arr1[][2]={0};
int arr2[2][2]={{1,2},{3,4}};
注意:二维数组在创建时不可省略第二维元素个数,也就是不可省略列向量的个数.
- 计算二维数组行数: sizeof(数组名) / sizeof(数组名[0])
- 计算二维数组列数: sizeof(数组名[0]) / sizeof(数组名[0][0])
- 计算二维数组所占内存大小: sizeof(数组名)
- 计算二维数组第2行所占内存大小: sizeof(数组名[2])
- 计算二维数组第一行第二列元素地址: &数组名[0][1]
#include<stdio.h>
#include<stdlib.h>
int main() {
int arr1[] = { 3,4,2,6 };
int arr2[] = { 9,8,0,1 };
printf("一维数组arr1的首地址为:%p\n", arr1);
printf("一维数组arr1[0]元素的地址:%p\n", &arr1[0]);
printf("一维数组arr1[1]元素的地址:%p\n", &arr1[1]);
int len1 = sizeof(arr1) / sizeof(arr1[0]);
int len2 = sizeof(arr2) / sizeof(arr2[0]);
printf("一维数组arr1的长度为:%d\n", len1);
printf("一维数组占内存大小:%d\n", sizeof(arr1));
int arr[][3] = { 1,2,3,4,5,6 };
int row = sizeof(arr) / sizeof(arr[0]);
int col = sizeof(arr[0]) / sizeof(arr[0][0]);
printf("二维数组行数%d\n", row);
printf("二维数组列数%d\n", col);
printf("二维数组占内存大小:%d\n", sizeof(arr));
printf("二维数组第一行大小:%d\n", sizeof(arr[0]));
printf("二维数组第一行地址:%p\n", &arr[0]);
printf("二维数组第二行第一个元素地址:%p\n", &arr[1][0]);
system("pause");
return 0;
}
测试结果为:
*2.数组置换
要求: 将两个相同长度的数组进行元素交换.
(1) 创建两个数组;
(2) 判断两个数组长度是否相等;
(3) 创建一个置换函数,进行数组元素交换.
注意: 数组作为函数参数时,只要传入的实参为数组,实际上传入时,数组名可以隐式转换为指向首元素的指针.所以不管形参是指针型还是数组型,给形参的都是一个指向数组首地址的指针.进行的都是地址传递.
代码实现:
#include<stdio.h>
#include<stdlib.h>
//打印数组序列函数
void printA(int Arr[], int len) {
for (int i = 0; i < len; i++) {
printf(" %d ", Arr[i]);
}
printf("\n");
}
//交换数组函数:实现两个等长的数组交换
void exchange(int* Arr1, int* Arr2,int len) {
for (int i = 0; i < len; i++) {
int temp = Arr1[i]; //老套路,设置中间变量进行交换
Arr1[i] = Arr2[i];
Arr2[i] = temp;
}
}
int main() {
int arr1[] = { 3,4,2,6 };
int arr2[] = { 9,8,0,1 };
int len1 = sizeof(arr1) / sizeof(arr1[0]);
int len2 = sizeof(arr2) / sizeof(arr2[0]);
printf("置换前数组arr1的序列为:");
printA(arr1, len1);
printf("置换前数组arr2的序列为:");
printA(arr2, len2);
if (len1 = len2) {
exchange(arr1,arr2,len1);
printf("数组已完成交换\n");
}
else {
printf("数组长度不相同,不能进行交换");
}
printf("置换后数组arr1的序列为:");
printA(arr1,len1);
printf("置换后数组arr2的序列为:");
printA(arr2, len2);
system("pause");
return 0;
}
结果显示:
*3.数组逆序
要求:
(1) 创建一个一维数组
(2)通过一个函数令数组改编为原数组的逆序数组
思路: 快速首尾交换,向中间操作
代码实现:
#include<stdio.h>
#include<stdlib.h>
//打印函数:实现对数组元素的打印输出
void print(int Arr[], int len) {
printf("数组的元素序列为: ");
for (int i = 0; i < len; i++) {
printf("%d ", Arr[i]);
}
printf("\n");
}
//数组逆序函数:实现对数组元素逆序操作
void reverse(int Arr[], int len) {
int left = 0;
int right = len - 1;
while (left < right) {
int temp = Arr[left];
Arr[left] = Arr[right];
Arr[right] = temp;
left++;
right--;
}
}
int main() {
int arr2[] = { 1,4,7,8,3,6 };
int len = sizeof(arr2) / sizeof(arr2[0]);
printf("逆序前的");
print(arr2, len);
reverse(arr2, len);
printf("逆序后的");
print(arr2, len);
system("pause");
return 0;
}
结果:
*4.冒泡排序
作用: 做常用的排序算法,对元素内数组进行排序
(1) 实现升序的第一种冒泡排序形式: 每次比较交换,每一轮总是把该轮比较的最大值放在比较的最右边
- 总是从数组第一位开始往后比较
- 冒泡排序轮数 i :len-1
- 冒泡排序每轮排序次数 j : len-第 i 轮-1
图解法:
注意 : 由于数组下标都是从0开始的 故轮数 i 和 比较字数 j 都是从0开始.
代码实现:
#include<stdio.h>
#include<stdlib.h>
//冒泡排序函数:实现对数组升序排列,总是把最大的数放在比较的最右边
void bubbleSort(int str[], int len) {
for (int i = 0; i < len - 1; i++) {
for (int j = 0; j < len - i - 1; j++) {
if (str[j] > str[j + 1]) {
int temp = str[j];
str[j] = str[j + 1];
str[j + 1] = temp;
}
}
}
}
//打印排序后数组的函数
void printS(int str[], int len) {
printf("数组序列为:");
for (int i = 0; i < len; i++) {
printf("%d ", str[i]);
}
printf("\n");
}
int main() {
int s[] = { 2,5,9,7,1,8,3,4 };
int len = sizeof(s) / sizeof(s[0]);
printf("升序冒泡排序前的");
printS(s, len);
bubbleSort(s,len);
printf("升序冒泡排序后的");
printS(s,len);
system("pause");
return 0;
}
结果:
(2) 实现升序的第二种冒泡排序形式: 每次比较交换,每一轮总是把该轮比较的最大值放在比较的最右边
算法描述:
- 总是从数组最后一位开始往前比较
- 1 .比较相邻两个数,前者大于后者,则两个数进行交换
- 2 .每相邻两个数做同样的工作, 执行结束后,找到第一个最小数
- 3 .重复以上步骤,每次比较范围boune+1(向后移一位),直到升序完成范围,不需要比较
设置初始的比较范围 bound 为[0,size-1], 当前值 数组[current] 初始总是为数组最后一个元素. 换言之就是:下标为current的数组元素两两相邻比较交换,比较的范围总是在数组下标为bound的范围内.
图解法:
代码实现:
#include<stdio.h>
#include<stdlib.h>
//冒泡排序函数:实现对数组升序排列
void bubbleSort(int str[], int len) {
int bound = 0;
for (; bound < len; bound++) {
for (int cur = len - 1; cur > bound; cur--) {
if (str[cur - 1] > str[cur]) {
int temp = str[cur - 1];
str[cur - 1] = str[cur];
str[cur] = temp;
}
}
}
}
//打印排序后数组的函数
void printS(int str[], int len) {
printf("数组序列为:");
for (int i = 0; i < len; i++) {
printf("%d ", str[i]);
}
printf("\n");
}
int main() {
int s[] = { 2,5,9,7,1,8,3,4 };
int len = sizeof(s) / sizeof(s[0]);
printf("升序冒泡排序前的");
printS(s, len);
bubbleSort(s,len);
printf("升序冒泡排序后的");
printS(s,len);
system("pause");
return 0;
}
结果:
不同: 两种方法都实现冒泡升序排序,第一种总先找到最大数,第二种总先找到最小数.