随笔- 54  文章- 0  评论- 1  阅读- 16734 

数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。

数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。

int arr[] = { 99, 15, 100, 888, 252 };为例,该数组在内存中的分布如下图所示:

数组名可以认为是一个指针,它指向数组的第 0 个元素。在C语言中,我们将第 0 个元素的地址称为数组的首地址。以上面的数组为例,下图是 arr 的指向

数组名的本意是表示整个数组,也就是表示多份数据的集合,但在使用过程中经常会转换为指向数组第 0 个元素的指针,

所以上面使用了“认为”一词,表示数组名和数组首地址并不总是等价。初学者可以暂时忽略这个细节,

把数组名当做指向第 0 个元素的指针使用即可

 

sizeof(arr) 会获得整个数组所占用的字节数,sizeof(int) 会获得一个数组元素所占用的字节数,它们相除的结果就是数组包含的元素个数,也即数组长度。

arr 是数组名,指向数组的第 0 个元素,表示数组首地址, arr+i 指向数组的第 i 个元素,*(arr+i) 表示取第 i 个元素的数据,它等价于 arr[i]。

arr 是 int* 类型的指针,每次加 1 时它自身的值会增加 sizeof(int),加 i 时自身的值会增加 sizeof(int) * i

复制代码
#include <stdio.h>

int main(){
    int arr[] = { 99, 15, 100, 888, 252 };
    int len = sizeof(arr) / sizeof(int);  //求数组长度
    printf("Size of len = %d\n", len );
    printf("Size of int = %d\n", sizeof(int));
    printf("Size of array = %d\n", sizeof(arr));
    int i;
    for(i=0; i<len; i++){
        printf("  %d th time = %d\n", i, *(arr+i) );  //*(arr+i)等价于arr[i]
    }
    return 0;
}

Size of len = 5
Size of int = 4
Size of array = 20
0 th time = 99
1 th time = 15
2 th time = 100
3 th time = 888
4 th time = 252

如果一个指针指向了数组,我们就称它为数组指针(Array Pointer)。
arr 本身就是一个指针,可以直接赋值给指针变量 p。arr 是数组第 0 个元素的地址,
所以 int *p = arr; 也可以写作int *p = &arr[0];。也就是说,arr、p、&arr[0] 这三种写法都是等价的,它们都指向数组第 0 个元素,或者说指向数组的开头。
复制代码
#include <stdio.h>

int main(){
   int arr[] = { 99, 15, 100, 888, 252 };
   int *p = arr;
    printf("%u\n",arr[0]);
    printf("%u\n",arr);
    printf("%u\n",&arr);
    printf("%u\n",*p);
    printf("%u\n",p);    
}
复制代码

99
3676766512
3676766512
99
3676766512

再强调一遍,“arr 本身就是一个指针”这种表述并不准确,严格来说应该是“arr 被转换成了一个指针”。这里请大家先忽略这个细节,我们将在VIP教程《数组和指针绝不等价,数组是另外一种类型》和《数组到底在什么时候会转换为指针》中深入讨论。

数组指针指向的是数组中的一个具体元素,而不是整个数组,所以数组指针的类型和数组元素的类型有关,

上面的例子中,p 指向的数组元素是 int 类型,所以 p 的类型必须也是int *

复制代码
#include <stdio.h>

int main(){
   int arr[] = { 99, 15, 100, 888, 252 };
   int i, *p = arr, len=sizeof(arr)/sizeof(int);
    printf("%d\n", *p);   //解指针  
    printf("P = %d\n", p);    //存的是地址    
    printf("P+1 = %d\n",p+1);//存的是地址
    printf("&p = %d\n", &p);   // 指针的地址
    printf("arr = %d\n", arr);  //第0元素 首地址
    
    printf("arr[0] = %d\n", arr[0]);
    printf("&arr[1] = %d\n", &arr[1]);
    printf("&arr[0] = %d\n", &arr[0]);    
    printf("arr+1 = %d\n", arr+1);


    for(i=1; i<len; i++){
        printf("%d\n", *(p+i));
    }
    return 0;
}
复制代码

 

复制代码
#include <stdio.h>

int main(){
    int arr[] = { 99, 15, 100, 888, 252 };
    int i, *p = arr, len = sizeof(arr) / sizeof(int);
    printf("%d\n ", *p);      // 99
    printf("%d ", sizeof(p)); //  8 
    printf("\n");
        
    for(i=0; i<len; i++){
        printf("%d ", *p++ );
    }             //99 15 100 888 252  
    printf("\n");
    
    printf("%d\n", sizeof(arr)); // 20
    printf("%d, %d,  %d, %d, %d \n", *p,p,++p,p++,&p );   
    // 5, 746887612,  746887612, 746887604, 746887576 
    printf("\n");
    
    for(i=0; i<len; i++){
        printf("%d  ", *++p ); 
    }  //4199040  0  -383549285  32620  0     
    return 0;
}
复制代码

 

复制代码
 posted on   Real_Yuan  阅读(535)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示