三种定义数组形式的区别
- int p[4];
- int (*p)[4];
- int *p[4];
初学C语言时,很难分清楚到底三者有何区别,尤其还涉及c语言的灵魂——C指针,下面,我将详细介绍一下三种定义方式,希望对正困惑的你有所帮助。
1.分析第一种方式——int p[4];
我相信接触过数组的,不管是任何所学的编程语言,这种定义应该最常见也最方便理解的吧。
1.1定义解释
int p[4];表示定义了一个整型数组,数组名为p(数组名表示该数组在内存存放的首地址,故p为数组的首地址),此数组有4个元素,并且每个元素也都是int类型,定义该数组会开辟sizeof(int) * 4个字节的连续存储空间。
1.2数组在内存中的存放形式:
2.分析第二种方式——int (*p)[4];
这种定义方式经常与二维数组联用
2.1解释定义
int (*p)[4];表示p是一个指针变量,指向一个存放4个整型元素的一维数组,且p+1(或p-1)是向前(或向后)移动数组长度个字节的大小。其中,指针变量指向一维数组的指针变量,指向二维数组中的某一行。
而第一种方式的p+1(或p-1)是向前(或向后)移动int个字节的大小。
2.2该方式在与二维数组的联用
设有如下二维数组:
int (*p)[4];
int a[3][4] = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12}
};
利用指向由4(二维数组列数)个元素组成的一维数组的指针变量引用二维数组
当执行 p = a时,内存存储情况变为:
当 p ++ 时:
即 此时p[0][0] 的值等于a[1][0]的值为5.
注:(*(a + i) + j)等价于 *(a[i] + j) 等价于a[i][j]*。
例如:(*(a + 1) + 2) = *(a[1] + 2) = a[1][2]
若:int (*p)[4];
p = a;
则:(*(p + 1) + 2) = *(p[1] + 2) = p[1][2]
3.分析第三种方式——int *p[4];
这种定义方式等价于 int *(p[4]); 代表定义了一个指针数组,p是指针数组名,数组中的每个元素存放的是指向整型变量的指针(int * 类型)
3.1内存中的存放形式
和普通数组一样,指针数组在内存中分配连续的存储空间,指针数组也可以初始化。指针数组元素在使用时与同类型的指针变量相同。
3.2定义一字符型指针数组
char *name[] = {"Beijing","Hebei","Shanxi"};
则在内存中的存储形式:
#include<stdio.h>
#include<string.h>
int main()
{
char *name[] = {"Beijing","Hebei","Shanxi"};
puts(name[0]); //输出Beijing
puts(*name); //输出Beijing
puts(name[2]); //输出Shanxi
puts(*(name + 1)); //输出Hebei
return 0;
}
如果是 char * s = name[1]; puts(s + 3) 则输出什么?
我们继续分析存储情况:
故输出:ei
讲到现在,我相信你对这三种定义方式大概有所熟悉,其实难理解的主要就是指针操作。C语言的指针,可以使得程序更加简洁、紧凑、高效。我们学习C语言的人,都应当熟练掌握指针操作,即使现在只是涉及入门内容。