C语言中的指针和数组



在C语言编程中,数组和指针的概念非常重要,两者之间也密切相关。本章将详细解释C语言中数组和指针之间的关系。

C语言中的数组

C语言中的数组是同构元素的集合,这些元素都是单一数据类型,存储在连续的内存块中。数组的大小是一个整数,放在方括号内,放在数组名称的前面。

声明数组

要声明一个数组,使用以下语法

data_type arr_name[size];

数组中的每个元素都由一个唯一的递增索引标识,从“0”开始。数组可以以不同的方式声明和初始化。

可以先声明一个数组,然后在代码中需要时再初始化它。例如

int arr[5];
... 
... 
a[0] = 1;
a[1] = 2;
... 
... 

也可以同时声明和初始化数组。要存储的值以逗号分隔的列表形式放在花括号内。

int a[5] = {1, 2, 3, 4, 5};

注意:当在声明时初始化数组时,提及其大小是可选的,因为编译器会自动计算大小。因此,以下语句也是有效的:

int a[] = {1, 2, 3, 4, 5};

示例:数组的下界和上界

数组中的所有元素都有一个位置索引,从“0”开始。数组的下界始终为“0”,而上界为“大小 - 1”。可以使用此属性使用循环遍历、赋值或读取数组下标中的输入。

请看下面的例子:

#include <stdio.h>

int main(){

   int a[5], i;
   
   for(i = 0; i <= 4; i++){
      scanf("%d", &a[i]);
   }

   for(i = 0; i <= 4; i++){
      printf("a[%d] = %d\n",i,  a[i]);
   }
   
   return 0;
}

输出

运行代码并检查其输出:

a[0] = 712952649
a[1] = 32765
a[2] = 100
a[3] = 0
a[4] = 4096

C语言中的指针

指针是一个存储另一个变量地址的变量。在C语言中,符号(&)用作取地址运算符。此运算符返回的值被赋值给一个指针。

要将变量声明为指针,需要在名称前加上星号 (*)。此外,指针变量的类型必须与它存储的变量的类型相同。

在此代码片段中,“b”是一个整数指针,它存储整数变量“a”的地址:

int a = 5;
int *b = &a;

对于数组,可以将它的第0个元素的地址赋给指针。

int arr[] = {1, 2, 3, 4, 5};
int *b = &arr[0];

在C语言中,数组的名称本身解析为其第0个元素的地址。这意味着,在上述情况下,可以使用“arr”作为“&arr[0]”的等价物:

int *b = arr;

示例:使用指针的自增运算符

与普通的数值变量(其中自增运算符“++”将其值增加1)不同,用于指针的自增运算符会将其值增加其数据类型的sizeof大小。

因此,当int指针递增时,会增加4。

#include <stdio.h>

int main(){

   int a = 5;
   int *b = &a;
   
   printf("Address of a: %d\n", b);
   b++;
   printf("After increment, Address of a: %d\n", b);
   
   return 0;
}

输出

运行代码并检查其输出:

Address of a: 6422036
After increment, Address of a: 6422040

C语言中的解引用运算符

在C语言中,"*"符号用作解引用运算符。它返回指针指向的地址中存储的值。

因此,以下语句返回“5”,这是变量“a”中存储的值,变量“b”指向“a”

int a = 5;
int *b = &a;
printf("value of a: %d\n", *b);

注意:对于char指针,它将递增1;对于double指针,它将递增8;对于struct类型,它将递增该struct类型的sizeof值。

示例:使用指针遍历数组

可以使用指针的此属性使用指针遍历数组元素。

#include <stdio.h>

int main(){
    
   int arr[5] = {1, 2, 3, 4, 5};
   int *b = arr;

   printf("Address of a[0]: %d value at a[0] : %d\n",b, *b);
    
   b++;
   printf("Address of a[1]: %d value at a[1] : %d\n", b, *b);

   b++;
   printf("Address of a[2]: %d value at a[2] : %d\n", b, *b);

   b++;
   printf("Address of a[3]: %d value at a[3] : %d\n", b, *b);
    
   b++;
   printf("Address of a[4]: %d value at a[4] : %d\n", b, *b);

   return 0;
}

输出

运行代码并检查其输出:

address of a[0]: 6422016 value at a[0] : 1
address of a[1]: 6422020 value at a[1] : 2
address of a[2]: 6422024 value at a[2] : 3
address of a[3]: 6422028 value at a[3] : 4
address of a[4]: 6422032 value at a[4] : 5

需要注意的几点

需要注意的是:

  • “&arr[0]” 等价于 “b”“arr[0]” 等价于 “*b”
  • 同样,“&arr[1]” 等价于 “b + 1”“arr[1]” 等价于 “*(b + 1)”
  • 同样,“&arr[2]” 等价于 “b + 2”“arr[2]” 等价于 “*(b + 2)”
  • 一般来说,“&arr[i]” 等价于 “b + i”“arr[i]” 等价于 “*(b + i)”

示例:使用解引用运算符遍历数组

可以使用此属性和循环使用解引用运算符遍历数组。

#include <stdio.h>

int main(){

   int arr[5] = {1, 2, 3, 4, 5};
   int *b = arr;
   int i;

   for(i = 0; i <= 4; i++){
      printf("a[%d] = %d\n",i,  *(b+i));
   }
   
   return 0;
}

输出

运行代码并检查其输出:

a[0] = 1
a[1] = 2
a[2] = 3
a[3] = 4
a[4] = 5

也可以在每次迭代中递增指针并获得相同的结果:

for(i = 0; i <= 4; i++){
   printf("a[%d] = %d\n", i, *b);
   b++;
}

C语言中数组和指针的概念密切相关。可以使用指针来提高程序的效率,因为指针直接处理内存地址。指针也可以用来处理多维数组。

广告