C语言学习记录230702

        指针的知识在前面已经提过很多次了,但今天又进一步对指针进行了学习,但是今天讲师给出的说法,可能不太适合我,所以我接下来对今日学习的总结会以我自己的看法来阐述。

        此前大概是讲了二级指针的内容,其实多级指针的原理是同二级指针一致的,继续的三级、四级无非就是套娃罢了。现在要补充的新知识主要是关于指针数组和数组指针的。

        如果不将指针数组和数组指针这两个词摆到一起,我们可能还以为两个是同一个东西,包括此前,我也对数组指针没有多少的了解。实际上这是两个东西,顾名思义,一个是储存了指针的数组,而另一个是指向数组的指针,那么这里两者在定义上有什么区别呢?下面来依次讲解:

        (一)指针数组

                指针数组指的是数组内保存的各个元素数据是指针,数组的定义是相同类型数据的集合,所以不难理解。那么我们如何声明指针的数组呢?看下面的例子:

int *number[100];

                可以知道,其实我们要定义一个指针数组,只需要在数组名前面加一个星号就行了,这里我说一下我的想法,我认为在声明时,当出现*号是,这将表明,与这个星号结合的变量或者数组名是一个指针,这个*号的意义就是说明,这个变量或者说这个值是个指针。

                如果按上面的想法来思考,出现星号的那一刻,*号与number[100]结合,因为取下标运算符优先级比*号高,所以可以知道*号不是直接与number进行结合,那么*与number[100]结合,这意味着什么呢?我们知道数组本身就是一个变量集合,当我们说int number[100]时,说的是这个数组里有100个int类型的变量,*号与number[100]结合,说明number[100]有100个元素,保存的是指针,那其实说的就是number[100]是100个指针。所以指针数组就是这么定义出来的。

        (二)数组指针

                数组指针如果与指针数组结合起来看,会发现两者的定义容易令人混淆,之前我们也说过,通常情况下,一个数组的数组名代表的是数组内首个元素的地址,有两个情况是例外的,第一个是当采用sizeof运算符读取数组名时,这时sizeof读出来的将是整个数组的大小,而不是首个元素的大小;第二种情况是对一个数组名采用取地址运算符时,这时取出来的地址将会是一个数组的地址。这里要提一下,如果用取地址对数组名取地址、对数组首个元素取地址、以及直接拿数组名,都放到printf里用转换说明%p输出地址时,会发现三者的地址是一模一样的,原因在于不管从哪个角度看,他们的地址确实是一样的,从数组角度看,地址取第一个元素地址很合理,从数组首个元素角度看,这本来就是他应该有的地址,而直接拿数组名的地址,这也很合理。

                那么如何知道当对数组名取地址时,他出来的实际上是整个数组的地址呢?这里只需要我们在printf进行输出时,对上面三个数进行+1操作输出,这时就会发现区别了,当对数组名取地址后再+1,地址增加的幅度是以整个数组大小来考虑的,比如有十个元素的数组,那就是一次跨越了十个元素所占的内存,其他两个则是只增加了一个元素所占的内存。

                其实从上面的讲解,我个人角度猜测,这可能就是计算机识别上的问题了,就像我们定义了一个int类型的-1,当在printf里用无符号整数的转化说明输出时,输出将会把这个-1的补码按无符号整数的角度来看待。同理当我们对数组名取地址时,这时程序会认为这个地址指向的是一个数组,而不是某个元素。

                说了那么多,那么如何定义数组指针呢?看看下面的代码:

int (*a)[100];
int *(*a)[100];

                这里先看第一个声明,我们发现*号与a外面加了个括号,这意味着a不先于取下标运算符结合,而与*号结合,*号说a是一个指针,而*a这一块替代的是整个数组的数组名,所以这里的a就是一个指向数组的指针。

                第二条我们也来剖析,首先看最里面的星号,这说明a是一个指向数组的指针,而外面一个星号将与(*a)[100]结合,这个星号说(*a)[100]有100个元素,保存的是指针,所以最后就可以知道,变量a是指向数组的指针,这个数组里保存的是指向int类型的指针。

                感觉有点绕,捋清楚的话,会容易很多。

                实际上我个人觉得数组指针用起来很不方便,不如二级指针好用。

        (三)杂谈

                今天还有一点小小的注意点,那就是二维数组,我们知道他们的数据在内存里是连续排放的,但当我们采用动态内存分配,采用二级指针生成的模拟二维数组,他们的数据在内存中不一定是连续的。其实不难想象,二维数组从一开始就已经定义好了空间大小,所以将会是一个连续的空间,而采用二级指针进行动态内存分配生成的虚拟二位数组,首先我们需要动态分配内存,给二级指针,然后才能再利用动态内存分配生成一位数组的内存空间,这个过程时分开的。自然,在内存里,也没有所谓的连续性了。

                

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值