C 语言中指针数组的初始化
指针是一个存储另一个变量地址的变量。指针变量的名称必须以"*"符号作为前缀。与普通变量一样,我们也可以声明一个"指针数组",其中数组的每个下标都保存着一个数组类型的地址。
如何在 C 语言中初始化指针数组?
指针变量可以在声明时初始化,方法是将其赋给现有变量的地址。以下代码片段展示了如何初始化指针 -
int x = 10; int *y = &x;
默认情况下,所有变量(包括指针变量)都属于"自动存储类"。这意味着指针变量将存储不可预测的、垃圾的、随机的内存地址,这可能导致未定义的行为和程序的潜在风险,例如段错误。因此,如果在声明时没有指定要存储的特定值,则应将其初始化为 NULL。
int *ptr = NULL;
"指针数组"将地址存储在每个元素中。数组的类型必须与目标变量的类型匹配。
使用 static 关键字初始化指针数组
您还可以使用 static 关键字 初始化 指针数组,在每个下标中存储"0"。
示例
#include <stdio.h> int main(){ static int *ptr[5]; for (int i = 0; i < 5; i++){ printf("ptr[%d] = %d ", i, ptr[i]); } return 0; }
输出
运行代码并检查其输出 −
ptr[0]= 0 ptr[1]= 0 ptr[2]= 0 ptr[3]= 0 ptr[4]= 0
初始化整数指针数组
这里,我们声明一个整数指针数组,并存储三个整数变量的地址。
示例
#include <stdio.h> int main(){ int a = 10, b = 20, c = 30; int *ptr[3] = {&a, &b, &c}; for (int i = 0; i < 3; i++){ printf("ptr[%d]: address: %d value: %d ", i, ptr[i], *ptr[i]); } return 0; }
输出
运行代码并检查其输出 −
ptr[0]: address: 6422040 value: 10 ptr[1]: address: 6422036 value: 20 ptr[2]: address: 6422032 value: 30
通过直接地址初始化指针数组
我们可以将普通数组中每个元素的地址存储在指针数组的相应元素中。
示例
#include <stdio.h> int main(){ int arr[] = {10, 20, 30}; int *ptr[3] = {&arr[0], &arr[1], &arr[2]}; for (int i = 0; i < 3; i++){ printf("ptr[%d]: address: %d value: %d ", i, ptr[i], *ptr[i]); } return 0; }
输出
运行代码并检查其输出 −
ptr[0]: address: 6422032 value: 10 ptr[1]: address: 6422036 value: 20 ptr[2]: address: 6422040 value: 30
通过基址遍历数组
当我们获取数组的基址(在本例中为" &arr[0]" )时,我们可以获取其后续元素的地址,因为指针会根据数据类型的大小递增。
因此,仅凭基址(数组名称与第 0 个元素的地址相同),我们就可以遍历数组。
示例 1
请看以下示例 -
#include <stdio.h> int main(){ int arr[] = {10, 20, 30}; int *ptr=arr; for (int i = 0; i < 3; i++){ printf("ptr[%d]: address: %d value: %d ", i,ptr+i, *(ptr+i)); } return 0; }
输出
运行代码并检查其输出 −
ptr[0]: address: 6422020 value: 10 ptr[1]: address: 6422024 value: 20 ptr[2]: address: 6422028 value: 30
示例 2:使用指针数组遍历二维数组
本例中,我们有一个二维数组。每行第 0 个元素的地址存储在一个指针数组中。遍历时,指针数组中每个元素的地址(指向相应行的第 0 个元素)都会递增,以提取每行的值。
#include <stdio.h> int main(){ // 二维数组 int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, }; int ROWS = 2, COLS = 4; int i, j; // 指针 int (*ptr)[4] = arr; // 通过指针 ptr 打印数组元素 for (i = 0; i < ROWS; i++) { for (j = 0; j < COLS; j++) { printf("%d ", *(ptr[i]+j)); } printf(" "); } return 0; }
输出
运行此代码时,将产生以下输出 -
1 2 3 4 5 6 7 8
示例 3
这里我们实际上不需要指针数组,因为我们可以使用这个二维数组的名称作为其基指针,并按行和列递增它以获取给定二维数组中的元素 -
#include <stdio.h> int main(){ // 二维数组 int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, }; int ROWS = 2, COLS = 4; int i, j; // 指针 int *ptr = arr; // 通过指针 ptr 打印数组元素 for (i = 0; i < ROWS; i++){ for (j = 0; j < COLS; j++){ printf("%d ", *(ptr + i * COLS + j)); } printf(" "); } return 0; }
输出
输出类似于前面的代码 -
1 2 3 4 5 6 7 8
初始化字符指针数组(字符串)
在 C 语言编程中,字符串是 char 数据类型的数组。由于数组名称也代表其第 0 个元素的地址,因此字符串可以声明为 -
char arr[] = "Hello";
使用指针表示法,将字符串赋值给 char 指针,如下所示 -
char *arr = "Hello";
然后,我们可以声明一个字符指针数组来存储多个字符串,如下所示 -
char *arr[3] = {"string1", "string2", "string3", . . . };
示例
以下示例包含一个字符指针数组,用于存储计算机语言的名称 -
#include <stdio.h> int main(){ char *langs [10] = { "PYTHON", "JAVASCRIPT", "PHP", "NODE JS", "HTML", "KOTLIN", "C++", "REACT JS", "RUST", "VBSCRIPT" }; for(int i = 0; i < 10; i++) printf("%s ", langs[i]); return 0; }
输出
运行此代码时,将产生以下输出 -
PYTHON JAVASCRIPT PHP NODE JS HTML KOTLIN C++ REACT JS RUST VBSCRIPT
在此程序中,"langs"是一个指向一个包含 10 个字符串的数组的指针。因此,如果"langs[0]"指向地址 5000,那么"langs + 1"将指向地址 5004,该地址存储了指向第二个字符串的指针。
因此,我们也可以使用以下循环变体来打印字符串数组 -
for (int i = 0; i < 10; i++){ printf("%s ", *(langs + i)); }
动态指针数组的初始化
您可以使用 malloc() 函数 以动态方式声明和初始化指针数组。
示例
请看以下示例 -
#include <stdio.h> int main(){ int *arr = (int *)malloc (sizeof (int) * 5); for(int i = 0; i < 5; i++){ arr[i] = i; } for (int x = 0; x < 5; x++){ printf("%d %d ", x, arr[x]); } return 0; }
输出
运行此代码时,将产生以下输出 -
0 0 1 1 2 2 3 3 4 4
您甚至可以请求用户输入并将值分配给数组指针中的元素 -
for(i = 0; i < 5; i++){ scanf("%d", &x); arr[i] = x; }