目录
一. 数组
1.1 概念
数组是用来保存一组相同数据类型的数据的集合
数组是一个构造类型
数组中每隔相同的数据类型的数据称之为数组的元素,也叫数组的成员
定义数组会在内存上分配一块连续的空间来存储数据,不管几维数组,都是连续的
1.2 一维数组
1.2.1 概念
简单来说,一维数组就是下标只有一个的数组
1.2.2 定义一维数组的格式
存储类型:默认为 auto
数据类型:既可以是基本类型,也可以是构造类型
数组名:是一个标识符,符合标识符的命名规范
下标:在定义数组时,下标一般是一个常量,用来表示要定义的数组的长度
下标在其他场景下,既可以是常量,也可以是变量,也可以是表达式,表示的是数组中第几个表达式的意思
举例:
int s[3]
表达的意思是:定义了一个叫做 s 的一维数组,数组中一共有五个元素,每个元素都是 int
1.2.3 一维数组的性质
#include <stdio.h>
int main(int argc, const char *argv[])
{
//定义了一个一维数组,数组名是s,数组中有5个元素,每个元素都是一个int类型的变量
int s[5];
//数组访问元素的方式 数组名[下标]
//注意:下标是从0开始的 长度为5的数组下标的范围应该是 [0,4]
//当数组通过下标取出某个元素时
//对数组元素的操作,和对普通变量的操作 是一样的
s[0] = 520;
s[1] = 10;
s[2] = 20;
s[3] = 30;
s[4] = 40;
printf("s[0] = %d\n", s[0]);
printf("s[1] = %d\n", s[1]);
printf("s[2] = %d\n", s[2]);
printf("s[3] = %d\n", s[3]);
printf("s[4] = %d\n", s[4]);
//数组的成员是一个变量,可以被重新赋值
s[0] = 1314;
printf("s[0] = %d\n", s[0]);
//一维数组的长度指的是元素的个数
//一维数组的大小指的是占用的字节数
//一维数组的大小 = 一个元素的大小 * 元素的个数
printf("sizeof(s) = %ld\n", sizeof(s));// 4 * 5 = 20
//注意 !!!!
//数组名是一个常量 不能被赋值
//s = 1314;//错误的
//s++;//错误的
//数组一旦定义好,就不能整体赋值了
//只能一个一个的赋值
s[0] = 111;
s[1] = 222;
//一维数组的元素在内存上是连续的
// & :取地址符 可以获取变量的地址(编号最小的 首地址)
// %p :打印地址的占位符
printf("&s[0] = %p\n", &s[0]);//依次相差4
printf("&s[1] = %p\n", &s[1]);
printf("&s[2] = %p\n", &s[2]);
printf("&s[3] = %p\n", &s[3]);
printf("&s[4] = %p\n", &s[4]);
printf("-----------------------------\n");
//遍历一维数组
int i = 0;
//for(i = 0; i < 5; i++){
for(i = 0; i < sizeof(s)/sizeof(s[0]); i++){
printf("%d ", s[i]);
}
printf("\n");
//注意:数组越界的问题编译器不会检查 需要程序员自己检查并处理
//数组越界的问题是不可预知的 ----所以一定要严格检查数组的边界
//s[5678] = 1234;
//printf("%d\n", s[5678]);
return 0;
}
1.2.4 一维数组的初始化
#include <stdio.h>
int main(int argc, const char *argv[])
{
//一维数组如果没有初始化,里面所有的元素都是随机值c
//int s[5];
//一维数组的初始化:
//方式1:完全初始化
//int s[5] = {10, 20, 30, 40, 50};
//方式2:不完全初始化
//int s[5] = {10, 20};//是从小到大依次初始化,不够的位用 0 初始化
//方式3:全部初始化成 0 ----最常用的用法
//int s[5] = {0};
//方式4:不指定下标的初始化
//这种写法 编译器会根据后面初始化的元素个数 自动计算长度
int s[] = {10, 20, 30, 40, 50, 60};
printf("sizeof(s) = %ld\n", sizeof(s));//24
//遍历一维数组
int i = 0;
for(i = 0; i<sizeof(s)/sizeof(s[0]); i++){
printf("%d ", s[i]);
}
printf("\n");
return 0;
}
二. 练习——冒泡排序
2.1 基本思想
相邻两个数进行比较,按照要求进行交换。 (升序或者降序)
2.2 实现思路
第一趟排序:
第一个元素和第二个元素进行比较,将较大的元素放在第二个位置上
然后第二个元素和第三个元素进行比较,将较大的元素放在第三个位置上
依此类推,直到第一趟排序完成,最大值就在最后一个位置上了。
第二趟排序:
第一个元素和第二个元素进行比较,将较大的元素放在第二个位置上
然后第二个元素和第三个元素进行比较,将较大的元素放在第三个位置上
依此类推,直到第二趟排序完成,第二大的值就在倒数第二个位置上了。
依此类推,直到整个排序完成。
2.3 代码实现
#include <stdio.h>
int main(int argc, const char *argv[])
{
int temp = 0;
int s[10] = {10, 20, 34, 5, 67, 8, 96, 40, 55, 21};
int len = sizeof(s)/sizeof(s[0]);
//排序前
int i = 0;
int j = 0;
for(i = 0; i < 10; i++){
printf("%d ", s[i]);
}
printf("\n");
//排序
#if 0
//一趟排序
for(i = 0; i < len-1; i++){
if(s[i] > s[i+1]){//如果是降序排列,只需将此处的 > 改成 < 就可以了
//三杯水交换
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
}
}
#endif
//完整的排序
//外层循环控制排序的趟数
for(j = 0; j < len-1; j++){//此处的-1 是因为最后一趟只有一个元素 无需排序了
//内层循环控制每趟排序
for(i = 0; i < len-j-1; i++){//此处的-1 是为了防止越界访问的
//-j 是因为每趟都可以少比一个
if(s[i] > s[i+1]){
//三杯水交换
temp = s[i];
s[i] = s[i+1];
s[i+1] = temp;
}
}
}
//排序后
for(i = 0; i < 10; i++){
printf("%d ", s[i]);
}
printf("\n");
return 0;
}