数组中的元素和元素地址是两个不同的概念:

- 数组元素:数组中每个数据的值,如整数、字符等。

- 数组元素地址:每个元素在内存中的存储地址。

例如,有一个5个元素的整数数组a:

a = {1, 2, 3, 4, 5}

那么:

- 数组元素是:1, 2, 3, 4, 5

- 数组元素地址根据元素在数组中的位置不同而不同,通常以a[0]、a[1]...a[n-1]表示,这里是:

a[0]: 元素1的地址

a[1]: 元素2的地址

a[2]: 元素3的地址

a[3]: 元素4的地址

a[4]: 元素5的地址

数组名a本身也代表这个数组的起始地址,即a[0]的地址。

在C++中,我们可以通过两种方式访问数组元素和元素地址:

1. 通过下标访问元素:

cpp

a[0] = 1;     // 访问第一个元素,值为1

a[3] = 4;     // 访问第四个元素,值为4

2. 通过指针访问元素地址:

cpp

int *p = a;     // p指向数组a的起始地址

*p = 1;          // 通过解引用指针访问第一个元素,值为1

*(p + 3) = 4;   // 通过指针加上偏移量访问第四个元素,值为4

上面两种访问方式看似不同,但本质上都是通过数组的元素地址来读取和修改元素值。

数组元素和元素地址的关系是:

- 数组名代表数组起始地址,每个元素地址都可以计算出来

- 我们通过元素地址访问对应的元素

- 元素地址由数组名和元素下标共同决定

a[0]可以代表数组a的第一个元素,也可以代表这个元素的地址,这取决于它 being used在什么上下文中。

当a[0]出现在赋值语句的左侧时,它代表第一个元素:

a[0] = 5;     // 表示给数组a的第一个元素赋值5

当a[0]出现在取值语句中时,它可以代表第一个元素的值:

x = a[0];      // x得到数组a的第一个元素的值

- 如果该函数的参数类型是元素类型(如int),那么a[i]表示元素值

    func(a[0])相当于func(元素值),它传递的实际上是数组a的第一个元素的值。

   

- 如果该函数的参数类型是指针类型(如int*),那么a[i]表示元素地址

当函数期望指针参数时,func(a[0])和func(&a[0])形式上可以传递同样的实参。但func(a[0])会多进行一次自动转换,这可能影响效率或产生意外结果。为了健壮性和效率,通常推荐func(&a[0])的直接传址方式。

1.
func(a[0])中,a[0]首先表示数组第一个元素的值。在函数调用时,由于函数期望的参数是指针,所以a[0]会被自动转换为指针,最终传递给函数的是数组第一个元素的地址。

2. func(&a[0])直接就传递第一个元素的地址,没有自动转换的过程。

所以,从形式上来说,这两个调用会传递同样的实参(第一个元素地址)给函数。

数组名arr:

1. 表示整个数组,它的值是第一个元素的地址

2. 可以理解为数组占用的内存块的起始和结束地址

3. 我们可以通过sizeof(arr)得到整个数组占用的内存大小

4. 可以将整个数组作为函数参数传递,实际传递的是起始地址和占用大小

&arr[0]:

1. 表示数组首元素的地址,它的值是第一个元素的实际内存地址

2. 只能访问第一个元素,若要访问整个数组只能通过其他方法(指针运算、数组下标等)

3. 无法直接得到整个数组的大小,需要结合数组长度使用

4. 只能将第一个元素的地址作为函数参数传递

所以,这两者的主要区别是:

arr代表整个数组,&arr[0]仅代表第一个元素。

arr可以直接得到数组大小和将整个数组传参,&arr[0]不能。

* 简单的说,就是数组名出现在赋值符号“=”左边的就是左值,出现的右边的就是右值。

a作为右值时代表的意义和 &a[0]的意义是一样的, 代表 数组首元素的首地址 ,而不是数组的地址。注意:这里只是“当作”,并没有一个地方来存储这个地址。

* a不能作为左值
!!!编译器会认为数组名作为左值代表的是a的首元素的首地址,但是这个地址开始的一块内存是一个整体,我们只能访问数组的某个元素,而无法把数组数组当做一个整体来进行访问。所以,我们可以把a[i]当左值,无法把a当左值。也可以这么理解:a的内部是由很多小部分组成,我们只能通过访问这些小部分来达到访问
a的目的。

 数组名代表数组首元素的地址,并不代表数组中的全部元素。因此用数组名作函数实参时,不是把实参数组的值传递给形参,而只是将实参数组首元素的地址传递给形参。形参可以是数组名,也可以是指针变量,它们用来接收实参传来的地址。如果形参是数组名,它代表的是形参数组首元素的地址。在调用函数时,将实参数组首元素的地址传递给形参数组名。这样,实参数组和形参数组就共占同一段内存单元

声明形参数组并不意味着真正建立一个包含若干元素的数组,在调用函数时也不对它分配存储单元,只是用array[]这样的形式表示array是一维数组名,以接收实参传来的地址。因此array[]中方括号内的数值并无实际作用,编译系统对一维数组方括号内的内容不予处理。形参一维数组的声明中可以写元素个数,也可以不写。C++实际上只把形参数组名作为一个指针变量来处理,用来接收从
实参传过来的地址

如果用二维数组名作为实参和形参,在对形参数组声明时,必须指定第二维(即列)的大小,且应与实 参的第二维的大小相同。第一维的大小可以指定,
``` #include<stdio.h> #include<string.h> int main() {     //char
a[5]={'1','2','3','4'};     char a[5]="1234";     struct {int a;int b;} st ;  
  st.a =1;     st.b=2;                                   puts(a);              
              //:1234     printf("%d\n",sizeof(a));            //:5    
printf("%d\n",sizeof(a[0]));         //:1     printf("%d\n",sizeof(&a[0]));    
   //:4     printf("%p\n",(&a[0]));              //:0x28cc7b    
printf("%p\n",(&a[0]+1));            //:0x28cc7c     printf("%p\n",(a));      
           //:0x28cc7b     printf("%p\n",(a+1));                //:0x28cc7c    
printf("%p\n",(&a));                 //:0x28cc7b     printf("%p\n",(&a+1));    
          //:0x28cc80     printf("%d\n",sizeof(st));           //:8    
printf("%p\n",&st);                  //:0x28cc70     printf("%d\n",st.a);      
          //:1     printf("%d\n",st.b);                 //:2    
memset(&st,0,sizeof(st));                 printf("%d\n",st.a);                
//:0     printf("%d\n",st.b);                 //:0     //memset(a,0,sizeof(a));
    //memset(&a,0,sizeof(a));     memset(&a[0],0,sizeof(a));     puts(a);     }
```

技术
今日推荐
PPT
阅读数 106
下载桌面版
GitHub
百度网盘(提取码:draw)
Gitee
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:ixiaoyang8@qq.com
QQ群:766591547
关注微信