You will learn:
- keyword
static - Operators:
& * (unary) - How to create and initialize arrays
- Pointers
- Writing Functions that process arrays
- Two-dimensional arrays
Arrays
An array is composed of a series of elements of one data type.
记住数组最大的特点:在内存中连续存放,有顺序。
Declare arrays
Float candy[365];
char code[12];
int states[50]
- 数组从0开始计数,用 candy[0] 表示第 1 个元素, candy[364] 表示第 365 个元素。
Initialization
int powers[8] = {1, 2, 3, 4, 5, 6, 7, 8};
...
Listing 10.1 presents a short program that prints the number of days per month
#include <stdio.h>
#define MONTHS 12
int main()
{
int days[MONTHS] = {31, 28, 31, 30, 31,30, 31,31, 30, 31, 30, 31 };
int index;
for (index = 0; index < MONTHS; index++)
printf("Month %d has %2d days.\n", index + 1, days[index]);
return 0;
}
Output
➜ C10_ArraysAndPointers ./a.out
Month 1 has 31 days.
Month 2 has 28 days.
Month 3 has 31 days.
Month 4 has 30 days.
Month 5 has 31 days.
Month 6 has 30 days.
Month 7 has 31 days.
Month 8 has 31 days.
Month 9 has 30 days.
Month 10 has 31 days.
Month 11 has 30 days.
Month 12 has 31 days.
Using const with Arrays
const int days[MONTHS] = {31, 28, 31, 30, 31,30, 31,31, 30, 31, 30, 31 };
Now it is a read-only array.
定义数组的时候要初始化,否则数组可能为任何值,及原本处于对应数组内存位置的值。
定义数组时可以不指定元素个数,由编译器自动计算
const int days[] = {31, 28, 31, 30, 31,30, 31,31, 30, 31, 30, 31 };
在这种情况下,可以在 for 循环中用 sizeof <数组名> / sizeof <数组名[0]> 计算数组元素个数:
for (index = 0; index < sizeof days / sizeof days[0]; index++)
...
Designated Initializers (C99)
C99 added a new capability: designated initializers. This feature allows you to pick and choose which elements are initialized.
简单来说,就是你可以挑选数组中的任意值进行初始化。并且其它没有初始化的元素将被自动设为默认值(如 0,空字符等)
下面两条语句等价:
int arr[6] = {0, 0, 0, 0, 0, 212};
int arr[6] = {[5] = 212};
Listing 10.5
#include <stdio.h>
#define MONTHS 12
int main()
{
int days[MONTHS] = {31, 28, [4] = 31,30,31,[1] = 29 };
int index;
for (index = 0; index < MONTHS; index++)
printf("Month %d has %2d days.\n", index + 1, days[index]);
return 0;
}
Output
➜ C10_ArraysAndPointers ./a.out
Month 1 has 31 days.
Month 2 has 29 days.
Month 3 has 0 days.
Month 4 has 0 days.
Month 5 has 31 days.
Month 6 has 30 days.
Month 7 has 31 days.
Month 8 has 0 days.
Month 9 has 0 days.
Month 10 has 0 days.
Month 11 has 0 days.
Month 12 has 0 days.
以上程序看出
- 当初始化第五个元素后,后面默认初始化后面的元素,除非指定第几个元素。
- 如果某个元素初始化了多次,则最后一次的初始化生效(编译器会提警告)。
Assigning Array values
After an array has been declared, you can assign values to array members by using an array index.
数组可以通过使用索引赋值。
...
a[2] = 3;
...
数组名的值即为数组第一个元素的地址。
#include <stdio.h>
#define SIZE 5
int main()
{
int envs[SIZE] = {1, 2,3, 4, 5};
int i;
printf("The value of envs is %p\n", envs);
for (i = 0; i < SIZE; i++){
printf("%p >>> %d\n", &envs[i], envs[i]);
}
return 0;
}
Output
➜ C10_ArraysAndPointers ./a.out
The value of envs is 0x16bc73610
0x16bc73610 >>> 1
0x16bc73614 >>> 2
0x16bc73618 >>> 3
0x16bc7361c >>> 4
0x16bc73620 >>> 5
数组只有在初始化时候可以整体赋值。初始化以后,只能对各个元素单独操作
下面的程序展示了几种数组的错误操作方式:
#include <stdio.h>
#define SIZE 5
int main(void)
{
int oxen[SIZE] = {5, 3, 2, 8};
int yaks[SIZE];
yaks = oxen; // not allowed
yaks[SIZE] = oxen[SIZE]; // out of range
yaks[SIZE] = {5, 3, 2, 8}; // doesn't work
return 0;
}
Array Bounds
C语言编译器不检查数组越界!!!
#include <stdio.h>
#define SIZE 5
int main(void)
{
int oxen[SIZE] = {5, 3, 2, 8};
for(int i = 0; i < SIZE + 2; i++)
{
printf("%d >>> %d\n", i, oxen[i]);
}
return 0;
}
Output
➜ C10_ArraysAndPointers ./a.out
0 >>> 5
1 >>> 3
2 >>> 2
3 >>> 8
4 >>> 0
5 >>> 1 // out of range
6 >>> -374800268 // out of range
C trusts the programmer to do the coding correctly and rewards the programmer with a faster program.
下面的程序逆向输出斐波那契数列
#include <stdio.h>
#define SIZE 10
int main(void)
{
int feibo[SIZE] = {1, 1};
for(int i = 2; i < SIZE; i++)
{
feibo[i] = feibo[i-1] + feibo[i-2];
}
for(int i = 0; i < SIZE; i++)
{
printf("feibo %d >>>>> %d\n", i+1, feibo[i]);
}
int i = 0;
int j = sizeof feibo / sizeof feibo[0] - 1;
int tmp;
while (i < j)
{
tmp = feibo[i];
feibo[i] = feibo[j];
feibo[j] = tmp;
i++;
j--;
}
printf("inverse the feibo sequence...\n");
for(int i = 0; i < SIZE; i++)
{
printf("feibo %d >>>>> %d\n", i+1, feibo[i]);
}
return 0;
}
Output
➜ C10_ArraysAndPointers ./a.out
feibo 1 >>>>> 1
feibo 2 >>>>> 1
feibo 3 >>>>> 2
feibo 4 >>>>> 3
feibo 5 >>>>> 5
feibo 6 >>>>> 8
feibo 7 >>>>> 13
feibo 8 >>>>> 21
feibo 9 >>>>> 34
feibo 10 >>>>> 55
inverse the feibo sequence...
feibo 1 >>>>> 55
feibo 2 >>>>> 34
feibo 3 >>>>> 21
feibo 4 >>>>> 13
feibo 5 >>>>> 8
feibo 6 >>>>> 5
feibo 7 >>>>> 3
feibo 8 >>>>> 2
feibo 9 >>>>> 1
feibo 10 >>>>> 1
C99 中不允许使用变长数组。
C11可以使用变长数组。
如
int n = 10;
float arr[n]; // not allowed before C99.