c语言之分不开的数组和指针

据本人道听途说的统计,很多人表示,c语言学完对于数组还有点拿捏不准,对于指针那就不是拿捏不准的问题,整个到绝望边缘,其实啊,小编我刚学的时候也整天在怀疑人生,怀疑自己,回想自己为什么要报这样一个“脱头发,长痘痘”的专业,好好的去学个经济,让人经管学院妹子一样美美的不好吗?后来,当我从内心觉得编程牛逼,感受到编程的魅力时,我觉得整个人豁然开朗,对于问题也变得好理解一些,现在的我虽然也只是菜鸟,但是在编程路上也在不断奋斗,如果你能搜到这篇博客,也许你也像我以前一样迷茫过,希望这段话能帮助你,鼓励你,给你勇气,加油哦!

下面,和我一起进入正题。。。。

一.数组

1.数组的定义:数组是只能存放一种类型元素的集合,安苏比如有int类型的数组,float类型的数组,数组里边存放的就是 元素。
2.数组的长度:(前面我写过一篇关于sizeof关键字的博客),比如,int arr[] = {1,2,3};数组arr的长度为sizeof(arr)/sizeof(arr[0]);
3.数组的格式:元素类型 数组名 [元素个数]
比如:int arr[10];float brr[2]。。。
4.数组的初始化:以下四种初始化方式都是正确的哦!
1.int arr[ ] = {1,2,3,4};//未给元素个数
2.int brr[10 ] = {1,2,3,4};//给定的元素个数比数组实际元素个数大
3.int crr[ 4 ] = {1,2,3,4};
4.int arr[ 5 ] = {arr[2] = 1,arr[0] = 2};//在花括号里面复赋值,且顺序不限
接下来我们写一小段代码,提醒一下,这个题有坑哦:

#include<stdio.h>
int main()
{
    int arr[] = {(2,3),(11,34),(3,4)};
    printf("%d\n",arr[0]);
    return 0;
}

是不是很简单,两行主要代码,你觉得输出应该是多少呢?
答案揭晓:
这里写图片描述
答案并不是2,3对吧!为什么是3呢!其实这道题很简单,只是里边有一点小奥秘,就是逗号运算符,大家很容易不注意这里,我们都知道逗号运算符的结果是最后一个逗号后边的值,这样看来,就应该是3啦!
其实数组没有什么难的,单的就是数组指针的结合,这些我们往下走。。

二.指针

1.指针的概念
“指针”是指地址, 是常量,“指针变量”是指取值为地址的变量。 定义指针的目的是为了通过指针去访问内存单元。
2.指针所占空间的大小
指针所占空间的大小其实就是对指针求sizeof的值,我们要知道,各个类型直接求sizeof值也许会不相同,但是任何类型的指针求sizeof的值都为4,任何类型的指针都占四个字节。
3.指针的形式
指针的一般形式是 类型说明符 *变量名
例如:
int *p;
这里的p就是变量名,存储的是某一变量的地址。
4.指针变量的类型说明
对指针变量的类型说明包括三个内容:
(1)指针类型说明,即定义变量为一个指针变量;
(2)指针变量名;
(3)变量值(指针)所指向的变量的数据类型。
5.指针变量的初始化
指针变量需要初始化,否则就是野指针。指针变量的初始化一般有两种:
(1) int a;
int *p = &a;
(2) int a;
int *p;
p = &a;
6.指针变量的运算
(1)指针运算符 & 和 *
&是取地址运算符, * 是取内容运算符,两个运算符都是单目运算符。
(2)加减算术运算
其实指针的加减算术运算要注意一点,两个指针变量之间的运算只有指向同一数组的两个指针变量之间才能进行运算, 否则运算毫无意义。
例如:
int arr[2] = {1,2};
int *p = arr;
p = p + 1;
int a = *p;
我们知道,&arr指的是数组arr的首元素的地址,所以p指向的是arr[1],所以p的值为p[1]。
这里写图片描述
三.数组函数和函数数组
1.先来看一个问题:
下面到底哪个是数组指针,哪个是指针数组呢:
A), int *p1[10];
B), int (*p2)[10];
答案揭晓:
A是指针数组,因为[]的优先级高于,所以p1会优先与[]结合,成为一个有10个元素的数组,这个数组里边的每一个元素是一个int类型的指针。所以它是指针数组。
B是数组指针,因为()的优先级高于[],所以p2与*结合为指针,指针的内容指向的是一个整型数组,p2为指针变量名,所以它为数组指针。
2.那现在我们再从题来看一下:

int main()
{
char a[5]={'A','B','C','D'};
char (*p3)[5] = &a;
char (*p4)[5] = a;
return 0;
}

上面对 p3 和 p4 的使用,哪个正确呢? p3+1 的值会是什么? p4+1 的值又会是什么?
答:首先应该明确一点,&a和a都是指数组首元素的地址,但两者意义不同。P3和p4都是数组指针,“=”左右两边应该类型相同,否则应该做隐式转换,p3的“=”左右两边完全相同,p4就不同啦,左边指的是指向整个数组的指针,右边指的是指向单个字符的指针,所以p3和p4都是指向整个数组的,所以p3+1和p4+1的值都为&a[0]+5*sizeof(char)。
3.在 x86 系统下,其值为多少?

int main()
{
    int a[4]={1,2,3,4};
    int *ptr1=(int *)(&a+1);
    int *ptr2=(int *)((int)a+1);
    printf("%x,%x",ptr1[-1],*ptr2);
    return 0;
}

答:&a+1表示的是数组a的首地址加上4*sizeof(int),强转为int*类型,所以ptr1[-1]就是指后退一个,也就是a数组的最优一个元素,所以打印为4,第二个,先把a数组强转为int类型,这时候加一就是给那个地址加一,强转为int*类型,所以*ptr2以十六进制打印的值为2000000.(我的电脑是小端存储)
这里写图片描述
我觉得函数数组和数组函数没什么难理解,只要能分清楚就行啦,指针和数组这里最难的应该是他们结合起来,多做题,见得多了就无所畏惧啦。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值