数组
本篇主要介绍:一维二维数组
、字符数组
、数组名和初始化注意点
以及字节序
。
一维数组
初始化
有以下几种方式对数组初始化:
// 定义一个有5个元素的数组,未初始化
int a[5];
// 定义一个有5个元素的数组,将第一个初始化0,后面几个元素默认初始化为0
int a[5] = {0};
// 定义一个有5个元素的数组,5个元素都初始化为:2,3,4,5,6
int a[5] = {2, 3, 4, 5, 6};
// 【推荐】
// 和上一种在功能上是相同的。编译器会根据初始化列表中的元素个数(5个)自动确定数组a的大小为5
int a[] = {2,3,4,5,6};
Tip:以上写法创建的数组都是不可变大小的
。
练习1
题目
:int a[5] = {1}
,请问 a 的每个值是多少?
#include <stdio.h>
int main() {
// 将第一个初始化1,后面几个元素默认初始化为0
int a[5] = {1};
int i;
for (i = 0; i < 5; i++) {
printf("%d ", a[i]);
}
return 0;
}
输出:1 0 0 0 0
。
在C和C++中,当我们创建数组时,如果没有为数组的所有元素提供初始值,那么剩下未被初始化指定初始值的元素会被默认初始化。对于基本数据类型(如int、float、double等),默认情况下,未初始化的元素将被设置为0
练习2
题目
:如果不对 a[5]
进行初始化,将输出什么?
#include <stdio.h>
int main() {
- int a[5] = {1};
+ int a[5];
int i;
for (i = 0; i < 5; i++) {
printf("%d\n", a[i]);
}
return 0;
}
输出随机数:
开始运行...
4198784
0
4198464
0
-2014700240
运行结束。
练习3
题目
:如果将int a[5];
提到全局作用于中,输出什么?
#include <stdio.h>
int a[5];
int main() {
int i;
for(i = 0; i < 5; i++){
printf("%d ", a[i]);
}
return 0;
}
输出: 0 0 0 0 0
练习4
题目
:这段代码有什么错误?
#include <stdio.h>
int main() {
int i = 10;
int a[i] = {0};
return 0;
}
运行:
开始运行...
# 不允许初始化可变大小的对象。即 i 是可变的。
/workspace/CProject-test/main.c:5:11: error: variable-sized object may not be initialized
int a[i] = {0};
^
1 error generated.
运行结束。
结论
:数组长度不能是变量。
如果换成 #define 常量
还有问题吗?
#include <stdio.h>
#define i 10
int main() {
// int i = 10;
int a[i] = {0};
return 0;
}
如果换成 #define 常量
就正常,前面我们知道 #define 是文本替换
。
数组名
题目
:定义一个数组a,请问 a
、&a[0]
、&a
的含义是什么?
#include <stdio.h>
int main() {
int a[5] ={1};
printf("%p\n", a);
printf("%p\n", &a[0]);
printf("%p\n", &a);
printf("-----\n");
printf("%p\n", a + 1);
printf("%p\n", &a[0] + 1);
printf("%p\n", &a + 1);
return 0;
}
运行:
开始运行...
0x7ffdfb131f00
0x7ffdfb131f00
0x7ffdfb131f00
-----
0x7ffdfb131f04
0x7ffdfb131f04
0x7ffdfb131f14
运行结束。
Tip: printf 中的 %p 打印的就是内存地址
。内存地址通常以十六进制
形式表示。
上半部分都是输出的都是 0x7ffdfb131f00
。
但下半部分加1后,结果明显不同。其中:
0x7ffdfb131f04 - 0x7ffdfb131f00 = 0x4
,转为十进制是4,一个 int 就是4个字节0x7ffdfb131f14 - 0x7ffdfb131f00 = 0x14
,转为十进制数是20,刚好是数组 a 的字节数(5*4)
结论:
a
- 数组名。表示首元素的地址,加 1 是加一个元素(比如这里4个字节)&a[0]
- 表示首元素地址,加 1 是加一个元素(比如这里4个字节)&a
- 表示整个数组。加1相当于跨越了整个数组
冒泡排序
之前我们写过冒泡排序的例子,我们将该示例用 C 语言重写如下(函数部分后文会讲):
#include <stdio.h>
void bubbleSort(int arr[], int n) {
// 比较轮数,每轮都会将一个值冒泡到正确的位置
for (int i = 0; i < n; i++) { // 第i轮冒泡
for (int j = 0; j < n - i - 1; j++) { // 第i轮冒泡需要比较n-i-1次
// 出界则为 false,不会交换
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
int main() {
int arr[] = {4, 3, 2, 1};
// 计算数组