第27课 数组的本质分析

By | 03月31日
Advertisement

1. 数组的概念

(1)数组是相同类型的变量的有序集合

第27课 数组的本质分析

(2)数组在一片连续的内存空间中存储元素

(3)数组元素的个数可以显示或隐式指定

【编程实验】数组的初始化

#include <stdio.h>

int main(){

    //数组初始化
    int a[5] = {1, 2};//第1、2个元素分别为1、2,其余为0
    int b[]  = {1, 2};//编译过程中,编译会为计算数组b的大小

    int i=0;
    for (i = 0;i < 4;i++)
    {
        printf("a[%d] = %d\n",i,a[i]);
    }

    printf("sizeof(a) = %d\n",sizeof(a));  //20
    printf("sizeof(b) = %d\n",sizeof(b));  //8

    printf("count for a: %d\n",sizeof(a)/sizeof(int));  //5
    printf("count for b: %d\n",sizeof(b)/sizeof(int));  //2

    return 0;
}

2. 数组地址(&a)与数组名a

(1)数组名a代表数组首元素的地址。因此,第2个元素的地址为a+1,以此类推……。注意a或a+i表示元素的地址。可以用*(a+i)取出元素的值,也可以用a[i]来取出元素的值,因为当编译中遇到a[i]会自动转为*(a+i)。反过来也可知,第1个元素的地址为a或&a[0],第2个元素的地址为a+1或&a[1],第i个元素的地址为(a+i)或&a[i]……

(2)数组的地址需要用取地址符&才能得到。即形如&a取的是整个数组的地址,所以&a+1表示指向整个数组的最后面的位置。

(3)数组的首元素的地址值与数组的地址值相同,但是两个不同的概念

【编程实验】数组名和数组地址

#include <stdio.h>

int main(){

    //将数组每个元素初始化为0
    int a[5] = {0};//含义,将第1个元素初始化为0,其余为0.

    printf("a = %p\n",a); //首元素的地址
    printf("&a = %p\n",&a); //整个数组的地址,从数值与看,与a一样。
    printf("&a[0] = %p\n",&a[0]);//第1个元素的地址

    return 0;
}

3. 数组名的盲点

(1)数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组。如int a[5]表示a的类型为int[5],所以sizeof(a)表示取整个数组的大小,&a表示数组的地址。

(3)数组名的外延:除了sizeof(a)和&a外,数组名经常可看作是一个常量指针。但要注意这里仅仅是“看作”,而不是真正的指针。不同于指针,数组名只是编译过程中的一个符号,编译器并不为其分配内存,有人称之为“伪变量”。因此,形式a++\a—或a=b(其中b是另一个数组名)这些都是错误的,因为a只是一个符号,编译器会把数组信息(如大小,地址)放入符号表中,每次遇到数组名a时,就会从符号表中取出这个数组的地址,然后用这个固定的地址代替 a,所以这个符号并没有被分配内存空间,而上述操作都是针对变量而言的,故数组名只能做为右值使用。

(4)对数组的引用,如a[i]或*(a+i),只需访问内存一次,而指针的引用如*(p+i)则需要两次,首选通过&p找到p指针,然后加i,再从p+i里面取出的内容。

(5)当数组名作为形参时,将退化为指针。即可以把数组名当成指针来用,这里的sizeof(数组名)为4,即指针的长度。

【实例分析】数组和指针并不相同

#include <stdio.h>

int main(){

    //将数组每个元素初始化为0
    int a[5] = {0};
    int b[2];
    int* p = NULL;

    p = a;

    printf("a = %p\n",a);  //首元素的地址
    printf("p = %p\n",p);  //p==a。
    printf("&p = %p\n",&p);//指针p的地址

    printf("sizeof(a) = %d\n",sizeof(a));//数组的大小:20
    printf("sizeof(p) = %d\n",sizeof(p));//指针的大小为4.

    printf("\n");

    p = b;

    printf("b = %p\n",b);  //首元素的地址
    printf("p = %p\n",p);  //p==b。
    printf("&p = %p\n",&p);//指针p的地址

    printf("sizeof(b) = %d\n",sizeof(b));//数组的大小:8
    printf("sizeof(p) = %d\n",sizeof(p));//指针的大小为4.

    //a = b; //编译错误,数组名不能作为左值;
    //a++;   //编译错误,数组名被编译一个固定地址,相当于0xaabbccdd++的错误
    return 0;
}

4. 小结

(1)数组是一片连续的内存空间

(2)数组的地址和数组首元素的地址意义不同

(3)数组名在大多数情况下被当成常量指针处理

(4)数组名其实并不是指针,不能将其等同于指针。

Similar Posts:

  • 第5课 引用的本质分析

    1. 引用的意义 (1)引用作为变量别名而存在,因此在一些场合可以代替指针 (2)引用相对于指针来说,具有更好的可读性和实用性 2. 特殊的引用--const引用 (1)const Type& name = var; //让变量拥有只读属性 (2)当使用常量对const引用进行初始化时,C++编译器会为这个常量值分配空间,并将引用名作为这段空间的别名.但这样用常量对const引用初始化将生成的是一个只读变量. [实例分析]引用的特殊意义 #include <stdio.h> void

  • 基于时间片优先级排课算法描述与分析

    基于时间片优先级排课算法描述与分析 排课问题实质上是时间.教师.班级.教室.课程这五维关系的冲突问题,要合理的解决这个问题首先要了解排课中的一些基本原则以及排课的一些基本要求. 3.1排课中的基本原则 在课程的编排中应遵循一定的规则, 只有按照基本规则来进行课程的编排才能够减少冲突的发生, 这些基本规则主要有以下几条: 1) 同一班级的学生在同一时间(某些特定的选修课时间除外) 不能安排两门课程 2) 同一教师在同一时间不能安排两门课程 3) 同一教室在同一时间不能安排两门课程 4) 同一时间安

  • 理解C语言-第22课 数组基础

    第22课 数组基础 数组是相同类型的变量的有序集合 int a[5]; 数组包含5个int类型的数据, a代表数组第一个元素的起始地址. 这20个字节空间的名字为a. a[0], a[1]等都是a中的元素,并非元素的名字. 数组中的元素没有名字. 每个元素都是int型数据. 数组的大小 数组在一片连续的内存空间中存储元素 数组元素的个数可以显示或隐式指定 问题: int a[5] = {1,2}; int b[ ] = {1,2}; a[2], a[3], a[4]的值是多少? b包含 了多少个

  • 大数据Spark “蘑菇云”行动前传Scala专家之路第27课:Scala的中面向对象实现的惊人内幕解密

    大数据Spark "蘑菇云"行动前传Scala专家之路第27课:Scala面向对象内幕实践解密 1 Scala的APP解密 2 Scala面向对象实战解密 package com.dt.spark.scala.bascis trait _Logger{   def log(msg:String):Unit={     println("Log:  "+msg)   } } trait RemoteLogger extends _Logger{   override 

  • 第27课 多线程详解 以及股票软件的分析

    首先老师推荐了4本书.<windows 95编程秘密>,<windows核心编程>,<windows高级编程指南>,<win32多线程程序设计>.个人推荐<windows核心编程>,<win32多线程程序设计>,原因就是核心编程的名气更高,而win32多线程程序设计对多线程编程做了详细的解释. 然后老师讲解了,线程和进程的一些概念,以及运行机制.这里老师也强调了由于很多条件的限制,所说的东西多是一家之言未必是对的.程序运行的时候就创建

  • 第34课 数组操作符的重载

    1. 字符串类的兼容性 (1)string类最大限度的考虑了C字符串的兼容性 (2)可以按照使用C字符串的方式使用string对象,如 string s = "abcedefg"; char c = s[i]; [编程实验]用C方式使用string类 #include <iostream> #include <string> using namespace std; int main() { string s = "a1b2c3d4e"; i

  • 【数据结构】数组与实现分析

    概念 所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标.组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量.数组是在程序设计中,为了处理方便, 把具有相同类型的若干变量按有序的形式组织起来的一种形式.这些按序排列的同类数据元素的集合称为数组. 数组有维度有分类,如一维.二维.三维等,而这个N维的N就是数组的向量了.结合数据结构的分类概念,只有一维数组属于线性结构类型

  • 汇编语言数组求和代码分析(1)

    是这么一段代码,来自于<Intel汇编语言程序设计>(第四版) ;---------------------------------------------------------------------------- ArraySum PROC ; ; Calculates the sum of an array of 32-bit integers. ; Receives : ESI = the array offset ; ECX = number of elements in the

  • Java中List与数组相互转换实例分析

    本文实例分析了Java中List与数组相互转换的方法.分享给大家供大家参考.具体如下: 今天写代码遇到一个奇怪的问题,具体代码不贴出了,写一个简化的版本.如下: ArrayList<String> list=new ArrayList<String>(); String strings[]=(String [])list.toArray(); 这样写代码个人觉得应该没什么问题,编译也没有问题.可是具体运行的时候报异常,如下:Exception in thread "mai

  • android anr本质分析及解决办法

    在android开发中经常碰到的一类问题是anr,全称是application not respond,应用程序没有响应,关于这类问题,究其本质是主线程无法响应.而导致主线程无法响应的原因大致如下: 1.主线程请求网络资源,数据库访问或者io访问,这些操作都是耗时操作,主线程处于阻塞状态,如果超时等待,会发生anr 2.cpu处于饥饿状态,无法让主线程运行,导致anr 3.其他进程或者线程占用cpu资源,无法释放资源让该主线程运行,导致anr 4.死锁,即主线程等待的锁正在被其它线程占用,无法释

Tags: