C语言: 指针与数组的联系

1.指针与数组没有关系!

指针在32位系统下永远只占4个字节,存储着一个地址。它可以指向任何地方,但不一定能够通过指针访问到。
数组的大小和他的元素类型与数量多少有关,可以存储任何类型的元素(除了函数)。

2.以指针的方式访问和以下标的方式访问。

<1.访问指针
    char* p = "abcdefg";
	char receive1;
	char receive2;
	receive1 = *(p + 4);
	receive2 = p[4];

vs2013实验结果如下
在这里插入图片描述
两种写法都可以达到访问目的。

<2.访问数组
	char p[] = "abcdefg";
	char receive1;
	char receive2;
	receive1 = *(p + 4);
	receive2 = p[4];

vs2013实验结果如下
在这里插入图片描述
同样的,两种写法都可以达到访问目的。

3.数组名的意义。

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。
    下面看一个例子:
	int a[5] = { 1, 2, 3, 4, 5 };
	int*ptr = (int*)(&a + 1);
	printf("%d,%d", *(a + 1), *(ptr - 1));

&a为整个数组地址
&a+1则应加上整个数组大小,为下一个数组的地址(即指向5的后面一个元素的位置)。
*(a+1)中a则是数组首元素的地址。
结果易得为 2 ,5。

4.指针数组与数组指针

指针数组是 数组! 数组的元素是指针
数组指针是 指针! 指针指向的是数组
举个栗子!

int *p1[10];
int(*p2)[10];

“[]”的优先级比“*”要高

故p1先与[10]结合,它首先是一个数组,元素个数为10,元素类型为int *。

p2先与*结合,它首先是一个指针,指向一个元素个数为10的数组,元素类型为int。

5.二维数组

二维数组可看成元素类型为数组的一维数组。
那么多维呢?
n维数组可看为元素为n-1维数组的一维数组。
至此,所有数组都可看成一维数组。
举个栗子!

char a[3][4];

a先与[3]结合,他是一个元素个数为3的数组,元素类型为char[4](一个元素个数为4的数组,而它的元素类型为char)

6.二级指针

char **p;

p 是一个指针变量,它与一级指针不同的是,一级指针保存的是数据的地址,二级指针保存的是一级指针的地址。

7.一维数组传参

当一维数组作为函数参数的时候,编译器总是把它解析成一个指向其首元素首地址的指针。
无论你是这样写

void fun(char *p) 
{
     char  c = p[3];//或者是 char c = *(p+3);
}

还是这样写

void fun(char a[10])
 {
char c = a[3];
}

还是这样写

void fun(char a[]) 
{
char c = a[3];
}

传向函数的都只是数组首元素的地址,并非传过去了整个数组。
并且传参是对实参做一份 拷贝并传递给被调用的函数。即对 参数p 做一份拷贝,假设其拷贝名为_p。那传递到函数内部的就是_p 而并非 p 本身。

8.二维数组传参

最直观的的写法

void fun(char a[3][4]);

现在我们将其看作一个一维数组a[3],元素类型为char [4]。
函数声明便可改写为:

void fun(char (*a)[4]);//第二维的维数却不可省略,他确定了元素类型!

或者

  void fun(char a[][4]);

当一维数组作为函数参数的时候,编译器总是把它解析 成一个指向其首元素首地址的指针。这条规则并不是递归的,也就是说只有一维数组才是 如此,当数组超过一维时,将第一维改写为指向数组首元素首地址的指针之后,后面的维再也不可改写。

9.函数指针

看一个函数指针的定义的例子

char (*p)(char p1,char p2);

如果看不懂,可以类比

char(*)[10] p;

就很容易看出这是一个指针,但它指向的是一个函数,函数的参数为(char p1,char p2)。
那么怎么通过函数指针调用函数呢?
假设函数指针 p=&fun;
如果跟其他指针一样
*p就可以调用函数,不过函数调用需要传入对应的参数
那么把参数才后面加上即可

	(*p)(a, b);//a,b为char类型

10.函数指针数组

根据指针数组的定方法和指针数组的定义,我们就可以尝试去定义一个函数指针数组了。
只需要将char (*p)(char p1,char p2);稍作修改
将变成char (*p[3])(char p1,char p2);
它便是一个指针数组了,数组存放的都是函数指针。
那么,我们又该怎么通过函数指针数组调用函数呢?
假设p中存储函数地址。
同样的p[0]中是一个函数指针*p[0]就是调用啦。
然后因为我们调用需要参数,完整调用方式则是

(*p[0])(a,b);

11.指向函数指针数组的指针

让我们再来尝试下定义这个拗口的指针
首先它说到天边还是个指针,

char*p

不过它指向函数指针数组,于是我们将之前定义好的函数指针数组拿下来替换p便成了

char(*(*p[3]))(char  p1,char p2);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值