一、数组
在C语言中,数组是存储一个固定大小的相同类型元素的顺序集合。
因此,我们不妨将其理解为:一系列相同类型的变量,比如:n1,n2,n3......。其存储方式如下图所示:

1.1、数组的声明
在 C 语言中要声明一个数组,需要指定元素的类型和元素的数量,如下所示:
数据类型 表示数组名称的标识符 [元素个数]
type tag_name[element_num]
示例:
// 声明存储10个整型数据的数组
int array[10];
// 声明存储10个字符数据的数组
char array1[10];
1.2、数组的初始化
在 C 语言中,数组可以利用循环逐个初始化,也可以利用 { } 直接初始化。示例如下:
int main() {
int arr[5];
// for 循环初始化
for (int i = 0; i < 5; i++) {
arr[i] = i + 1;
}
// 直接初始化
int arr1[6] = {1,2,3,4,5,6};
// 一个一个的初始化,效率低下
int arr2[2];
arr2[0] = 0;
arr2[1] = 1;
arr2[2] = 2;
return 0;
}
1.3、数组元素的访问
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:
arr[0] // 访问第一个元素
示例代码:
int main (){
int n[10]; // n 是一个包含 10 个整数的数组
/* 初始化数组元素 */
for (int i = 0; i < 10; i++) {
/* 设置元素 i 为 i + 10 */
n[i] = i + 10;
}
/* 输出数组中每个元素的值 */
for (int j = 0; j < 10; j++) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
1.4、多维数组
声明方式:type tag_name[size1][size2]....[sizen]
以二维数组为例:
type tag_name[a][b] // 相当于 a 行 b 列的表格数据
示意图如下:

其初始化及其访问方式与一维数组类似,示例如下:
int main () {
// 一个带有 5 行 2 列的数组
int a[5][2] = {{0,0}, {1,2}, {2,4}, {3,6},{4,8}};
// 由于数组在内存中是连续的, 所以内部的大括号也可以去掉
// 内部加上大括号,可以使结构一目了然,可读性更高
// 输出数组中每个元素的值
for (int i = 0; i < 5; i++) {
for ( int j = 0; j < 2; j++) {
printf("a[%d][%d] = %d\n", i,j, a[i][j]);
}
}
return 0;
}
1.5、字符数组
字符数组与其他类型的数组声明与初始化方式相似,但也有着独特的初始化方式,下面是一个一般字符串的声明与初始化示例:
// 一般字符数组
char str[5] = {'a', 'b', 'c', 'd', 'e'}
特殊字符数组:字符串
在 C 语言中,字符串是使用 null (\0) 字符 '' 终止的一维字符数组,下面是它的声明和初始化示例:
// 字符串的声明和初始化
// 以普通字符数组的方式声明,需要手动添加 \0
char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
// 通过双引号声明,无需手动添加 \0
char str[] = "hello";
二、指针
在 C 语言中,指针 是最好理解的,它并不复杂。如果你不相信,请看他的定义:
指针:用来存放变量内存地址的变量
怎么样?是不是非常简单。下面我们来看下指针变量的定义与初始化
2.1、指针变量的声明
type * tag_name
这里的type表示指针类型,tag_name指针变量名称,* 表示声明的变量是一个指针变量如:
int *ip; // 一个整型的指针
double *dp; // 一个 double 型的指针
float *fp; // 一个浮点型的指针
char *chp // 一个字符型的指针
2.2、指针变量的使用
指针的使用示例:定义一个指针变量、把变量地址赋值给指针、访问指针变量中可用地址的值。
int a = 10; // 定义一个整型指针
// 使用 取地址操作符 & 取变量a的内存地址
int * ptr = &a; // 定义一个整型指针变量,并存放变量a的地址
printf("%p\n", ptr); // 打印内存地址,输出一个16进制数
// 通过指针获取变量a的值
printf("%d\n", *ptr); // 使用 * 操作符对指针变量解引用,输出10
// 通过指针修改变量a的值
*ptr = 50;
printf("%d\n", a); // 输出50
2.3、空指针与泛型指针
空指针:在变量声明的时候,如果没有确切的地址可以赋值,就可以给指针变量赋值位NULL,这样的指针就是空指针。这样的指针指向内存地址为 0,在大多数系统上,内存地址为0处的位置具有特殊意义,所以不能对空指针解引用,否则会触发操作系统的一种内存保护机制。导致程序崩溃。因为空指针,它不指向任何有效的地址。
泛型指针:是指指针类型为 void 的指针。如果要对这样的指针进行解引用操作,必须将其强制转换成其他确切类型的指针。例如:*((int * )(void * p))
三、小结
相信通过上面的学习,你已经完全掌握了C语言中的数组和指针的使用。对于指针这种容易上手便于理解的操作应信手拈来了。不信你可以尝试解读下面代码:
1、((void (*)()) 0)();
2、int (*f (void *, int))(int *, void*);
相信现在你的表情可能是 😱 这样的,也可能是 😳 这样的。不知道有没有 😁 这样的。
下一节:深入理解指针
5122

被折叠的 条评论
为什么被折叠?



