C语言数组

2022/01/02 14:27

数组与指针有许多相似之处,但也有不同。

1 数组名是一个指针

int a[10];
int *c;
c = &a[0];
c = a;

数组和指针再大多数时候可以等效,我们可以将数组名就看作是一个指向数组第一个元素的指针。上面的c=&a[0]c=a操作其实是完全等效的。但是在在用sizeof的时候是例外1。当我们在对数组名用sizeof的时候它返回的是数组中所有元素和的大小,而对指针用sizeof操作的时候编译器并不知道它指向的是一个数组所以返回的只是指针本身的大小。

int a[10];
int *c;
c = a;
printf("The size of a:%ld\n",sizeof(a)/sizeof(int));
printf("This size of c:%ld\n",sizeof(c)/sizeof(int));

/*
* output
* The size of a:10
* This size of c:2
*/

2 字符串数组与字符串指针2

char message[] = "I can do it!";
char *pmessage = "I can do it!";
message[0] = 'Y'; //yes you can do that
pmessage[0] = 'Y'; //error

当我们用数组来声明一个字符串的时候,编译器会根据声明的元素数量保留内存空间,然后再创建数组名,数组名的值是一个常量指针,指向空间的起始位置。当我们使用指针来声明一个指向字符串的指针的时候,它会找一个内存空间来储存这些字符(这些内存空间可能是只读的),然后让这个指针指向这段内存空间的首部。因为这段内存空间可能是只读的,所以当你想要修改里面元素的值的时候会发生错误。所以当需要修改字符串数组里面的元素的时候最好使用第一种声明方法,如果使用第二种方法很有可能会造成程序的崩溃。

3 作为函数的参数

一维数组的数组名是指向第一个元素的指针,多维数组也是一样的,不过他的第一个元素还是一个数组指针,也就说他的数组名是一个指向指针的指针。所以在当作参数传入函数中的时候表达也有些差异。

3.1 一维数组

int pointer_parameter(char a[], char *b)

将一个一维数组传入函数中,有上面两种方法,一种是通过数组的名称另一种则是通过指针,在使用第一种方式的时候我们并没指定数组的大小,因为它的实质也是传入的指针,所以并不需要知道它的大小。

3.2 二维数组

void func2( int (*mat)[10] );
void func2( int mat[][10] );

编译器对于二维数组在进行下标运算的时候是需要知道数组的具体维度的,所以在这两个表达式中都需要填入数组的维度,一维数组不需要是以为一维数组的元素是单纯的int的可以直接进行下标运算。对于二维数组是不可以将他写作下面这种指针的形式的

void func2( int **mat );

这里表示的是指向整型指针的指针,它和指向整型数组的指针是不同的。


  1. In C, are arrays pointers or used as pointers? - Stack Overflow↩︎

  2. C FAQ: Question 1.32 (c-faq.com)↩︎