关于数组和指针及函数和指针结合的理解

在理解数组和指针的结合关系之前,必须清楚数组和指针之间是没有任何关系的,除非我们自己给它们之间建立一定的关系。下面将以一个简单代码进行分析:

string.c
char arr[] = "abcdef";
test.c
extern char* arr;
#include<stdio.h>
int main()
{
    printf("%s\n",arr);
    return 0;
}

在string.c源文件中定义一个字符串数组,而在test.c源文件中外部声明成gchar* 类型的指针,那么此时会输出该字符串吗,结果如下图所示:这里写图片描述
由此可见,定义和声明类型不一致是不可取的,怎样才可以正确输出呢?当声明成指针时,由于指针的大小为4个字节,abcd刚好占四个字节,此时abcd的ASCII码值被误认为是首元素a的地址,然而该地址并没有指向要输出的字符串,显然不会输出正确结果。要想输出正确结果,该指针必须指向首元素a的地址,由于arr是char* 类型,所以&arr后再强转成char* 类型,即可输出正确结果,代码及输出结果如下:

string.c
char arr[] = "abcdef";
test.c
extern char* arr;
#include<stdio.h>
int main()
{
    printf("%s\n",(char*)&arr);
    return 0;
}

这里写图片描述
那么定义成指针,声明成数组,又会出现怎样的结果呢?代码及输出结果如下:

string.c
char* p = "abcdef";
test.c
extern char p[];

int main()
{
    printf("%s\n",p);
    return 0;
}

这里写图片描述
由此可见其输出是随机的,定义成指针,声明成数组也是不可取的,定义的p是指向字符串首元素a的地址,当p声明成数组时,则该数组的大小为四个字节,printf(“%s\n”,p);此时p代表首元素地址,输出字符串时,从P的首元素地址向后输出,与定义中指针p指向的字符串没有任何关系,所以其输出结果是随机的。要输出正确结果,必须拿到首元素a的地址,将p强转成int* 再解引用,即可得到p的内容(四个字节),再强转成char* 类型,即可输出正确结果,代码及结果如下:

string.c
char* p = "abcdef";
test.c
extern char p[];

int main()
{
    printf("%s\n",(char*)*(int*)p);
    return 0;
}

这里写图片描述
接下来依次数组和指针,函数和指针之间的结合

1.指针数组

所谓指针数组,首先它是一个数组,其次是一个存放指针的数组,如 int* arr [10]={0};由于[ ]的优先级高于*,arr先和[ ]结合,说明它是一个数组,一个大小为10的数组,其元素类型为整型指针。

2.数组指针

如:int(p)[10],由于p先和 结合,说明p变量是一个指针,一个指向大小为10的整型数组的指针。当定义一个整型数组int arr [10]={0}, &arr取出的是数组的地址,此时将需要一个数组指针来存储它。

3.函数指针

由于指针变量是存放地址的,由此可知,函数指针是存放函数地址的,先从一个简单代码看一下函数的地址:

#include<stdio.h>
void test()
{
    printf("haha\n");
}
int main()
{
    printf("%p\n",test);
    printf("%p\n",&test);
    return 0;
}

其输出结果如图所示:
这里写图片描述
即为函数的地址,用 void (*test)( )可存放函数的地址。

4.函数指针数组

所谓函数指针数组,是存放函数地址的数组,定义为:void (*parr[10])(),可用于转移表。

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

指向函数指针数组的指针是一个指针,该指针指向一个数组,数组元素的类型为函数指针。
定义为:void (* (*parr)[10])( )。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值