C语言的数组和指针的区别


1.看到这个题目大家应该知道了,数组和指针它俩不是一回事儿,它俩是有区别的!

  我原来看数组的时候,一直都是用数组名表示数组内容的首地址,但是当我认真在网上看了数组和指针之后,发现数组和指针不等价!

举个例子,相信大家见过这种写法:

int arr[] = { 1,2,3,4,5};
int *b = arr;

  我们一般的认识是 arr是一个指针,指向数组的首地址,然后它把这个地址的值赋给了指针变量b。

  但是这种理解是有一点的不准确,严格来说应该是 arr被转换为了一个指针。

再举个例子:

#include <stdio.h>
#include <string.h>

int main(){

    int a[6] = {1,2,3,4,5,6};
    int *b = a;
    
    int len_a = sizeof(a) / sizeof(int);
    int len_b = sizeof(b) / sizeof(int);
    
    printf("len_a = %d\n",len_a);
    printf("len_b = %d",len_b);

    return 0;
}

  如果,咱们说如果哦,如果数组和指针等价,那么这两个结果应该是一样的,但是我们来看一下运行结果:

  这特么是什么玩意,这个 2 是哪来的。

  我们来看一下C语言中文网上的描述:

  数组是一系列数据的集合,没有开始和结束标志,b 仅仅是一个指向 int 类型的指针,编译器不知道它指向的是一个整数还是一堆整数,对 b使用 sizeof 求得的是指针变量本身的长度。也就是说,编译器并没有把 b 和数组关联起来,b仅仅是一个指针变量,不管它指向哪里,sizeof 求得的永远是它本身所占用的字节数。

  站在编译器的角度讲,变量名、数组名都是一种符号,它们最终都要和数据绑定起来。变量名用来指代一份数据,数组名用来指代一组数据(数据集合),它们都是有类型的,以便推断出所指代的数据的长度。

  对,数组也有类型,这是很多读者没有意识到的,大部分C语言书籍对这一点也含糊其辞!我们可以将 int、float、char 等理解为基本类型,将数组理解为由基本类型派生得到的稍微复杂一些的类型。sizeof 就是根据符号的类型来计算长度的。

  对于数组 a,它的类型是int [6],表示这是一个拥有 6 个 int 数据的集合,1 个 int 的长度为 4,6 个 int 的长度为 4×6 = 24,sizeof 很容易求得。

  对于指针变量 b,它的类型是int *,在 32 位环境下长度为 4,在 64 位环境下长度为 8。(这就是为什么会输出 2 了!)

  归根结底,a 和 b 这两个符号的类型不同,指代的数据也不同,它们不是一码事,sizeof 是根据符号类型来求长度的,a 和 b 的类型不同,求得的长度自然也不一样。

  总结:我们定义的数组 a 它是以个实实在在的数组类型的数据,它有自己的类型和长度,在内存中有自己的空间,而 指针变量b 它只是一个指针变量啊,一个指向int * 类型的变量!

  那就有一个问题来了,既然数组a是一个数组类型的数据,那为什么 数组名a 可以代表数组的首地址呢?这就又涉及到一个知识点了---------------与普通变量名相比,数组名既有一般性也有特殊性:一般性表现在数组名也用来指代特定的内存块,也有类型和长度;特殊性表现在数组名有时候会转换为一个指针,而不是它所指代的数据本身的值。

  特么的问题又来了,数组名什么时候会转换为指针呢?

  C语言标准规定,当数组名作为数组定义的标识符(也就是定义或声明数组时)、sizeof 或 & 的操作数时,它才表示整个数组本身,在其他的表达式中,数组名会被转换为指向第 0 个元素的指针(地址)。

举例吧!

#include <stdio.h>
#include <string.h>

int main(){

    int a[6] = {0,1,2,3,4,5};                 // a表示数组本身 
    
    int len_a = sizeof(a) / sizeof(int);  // a表示数组本身
    
    int *b = &a[1];                    // a 表示数组本身 
    
    int *p_a = a;                    // a 转换为首地址 
    
    return 0;
}

我感觉这个看的有点点小懂了!


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM