精华内容
下载资源
问答
  • 今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题:null reference。 Animals [] an=new Animals[5];//这只是个对象类型数组的声明的时候 需要 for(int i=0;i<5;i+...

    今天写代码的时候,发现我写的对象数组,只声明,而没有初始化,所以记录一下这个问题null reference

    Animals [] an=new Animals[5];//这只是个对象类型数组的声明用的时候

    需要

    for(int i=0;i<5;i++)an[i]=new Animals();

    进行初始化!

     

    所以报null reference的错误,去看下容器是否初始化,也适用于list类型。

     

    转载于:https://www.cnblogs.com/H-BolinBlog/p/5558109.html

    展开全文
  • 有没有办法初始化一个形状numpy数组并添加?我将列表示例解释我需要。如果我想创建一个循环中生成的对象列表,我可以做:a = []for i in range(5):a.append(i)我想做一个类似于numpy数组。我知道vstack,连接...

    有没有办法初始化一个形状的numpy数组并添加?我将用列表示例解释我需要的。如果我想创建一个循环中生成的对象列表,我可以做:

    a = []

    for i in range(5):

    a.append(i)

    我想做一个类似于numpy数组。我知道vstack,连接等。但是,似乎这些需要两个numpy数组作为输入。我需要的是:

    big_array # Initially empty. This is where I don't know what to specify

    for i in range(5):

    array i of shape = (2,4) created.

    add to big_array

    big_array应该有一个形状(10,4)。如何做到这一点?

    编辑:

    我想补充以下澄清。我知道,我可以定义big_array = numpy.zeros((10,4)),然后填满它。但是,这需要提前指定big_array的大小。我知道在这种情况下的大小,但如果我不是?当我们使用.append函数扩展python中的列表时,我们不需要提前知道它的最终大小。我想知道是否存在类似的事情,从较小的数组创建一个更大的数组,从一个空数组开始。

    展开全文
  • 目录数组的存储与初始化一维数组的存储一维数组的初始化二维数组的存储二维数组的初始化数组作为函数的参数对象数组对象数组的定义和访问对象数组的初始化数组元素所属类的构造函数基于范围的for循环指针的初始化和...

    数组的存储与初始化

    一维数组的存储

    数组元素在内存中顺次存放,它们的地址是连续的。元素间物理地址上的相邻,对应着逻辑次序上的相邻。

    例如:

    一维数组的初始化

    在定义数组时给出数组元素的初始值。

    • 列出全部元素的初始值

      static int a[10]={0,1,2,3,4,5,6,7,8,9};
      
    • 可以只给一部分元素赋初值

      static int a[10]={0,1,2,3,4};
      
    • 在对全部数组元素赋初值时,可以不指定数组长度

      static int a[]={0,1,2,3,4,5,6,7,8,9};
      

    二维数组的存储

    • 按行存放,如:

      float a[3][4];
      

      可以理解为:
      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JqCLiPKA-1594979262981)(C:\Users\qbzxb\AppData\Roaming\Typora\typora-user-images\image-20200715190630718.png)]

    其中数组a的存储顺序为:a00 a01 a02 a03 a10 a11 a12 a13 a20 a21 a22 a23

    二维数组的初始化

    • 将所有初值写在一个{}内,按顺序初始化

      static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12};
      
    • 分行列出二维数组元素的初值

      static int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
      
    • 可以只对部分元素初始化

      static int a[3][4]={{1},{0,6},{0,0,11}};
      
    • 列出全部初始值时,第1维下标个数可以省略

      static int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
      // 或者
      static int a[][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
      

    注意:

    • 如果不作任何初始化,块作用域中的局部数组中会存在垃圾数据,static数组中的数据默认初始化为0;
    • 如果只对部分元素初始化,剩下的未显式初始化的元素,将自动被初始化为零;

    数组作为函数的参数

    • 数组元素做实参,与单个变量一样。
    • 数组名作参数,形、实参都应是数组名,类型要一样,传递的是数组的首地址。对形参数组的改变,会直接影响到是实参数组。

    注意:数组作为形参时弱化成为指针

    示例:使用数组名组函数参数

    #include <iostream>
    using namespace std;
    
    void rowSum(int a[][4],int nRow){
        for(int i=0;i < nRow;i++){
            for(int j = 1;j < 4;j++)
                a[i][0] += a[i][j];
        }
    }
    
    int main(){
        int table[3][4] = {{1,2,3,4},{2,3,4,5},{3,4,5,6}};
        
        // 输出数组元素
        for(int i = 0;i < 3;i++){
            for(int j = 0;j < 4;j++)
                cout << table[i][j] << "	";
            cout << endl;
        }
        rowSum(table,3);  // 调用子函数,计算各行和
        // 输出计算结果
        for(int i = 0; i < 3; i++)
            cout << "Sum of row " << i << table[i][0] << endl;
        return 0;
    }
    

    对象数组

    对象数组的定义和访问

    • 定义对象数组

      类名 数组名[元素个数]
    • 访问对象数组元素——通过下标访问

      数组名[下标].成员名
      

    对象数组的初始化

    • 数组中每一个元素对象被创建时,系统都会调用类构造函数初始化该对象。

    • 通过初始化列表赋值。

      Point a[2]={Point(1,2),Point(3,4)};
      
    • 如果没有为数组元素指定显式初始值,数组元素便使用默认值初始化(调用默认构造函数)。

    数组元素所属类的构造函数

    • 元素所属的类不声明构造函数,则采用默认构造函数。
    • 各元素对象的初值要求为相同的值时,可以声明具有默认形参值的构造函数。
    • 各元素对象的初值要求为不同的值时,需要声明带形参的构造函数。
    • 当数组中每一个对象被删除时,系统都要调用一次析构函数。

    基于范围的for循环

    // 普通类型的 for 循环
    int main(){
    	int array[3] = {1,2,3};
    	int *p;
    
    	for(p = array; p < array + sizeof(array) / sizeof(int); ++p){
    		*p += 2;
    	    std::cout << *p << std::endl;
    	}
    
     	return 0;
    }
    
    // 基于范围的 for 循环
    int main(){
    	int array[3] = {1,2,3};
    	for(int & e : array){
    	    e += 2;
    	    std::cout<<e<<std::endl;
    	}
    return 0;
    
    }
    

    指针的初始化和赋值

    指针变量的初始化

    • 语法形式

      存储类型 数据类型* 指针名=初始地址;
      int* pa = &a;
      
    • 注意事项

      1. 用变量地址作为初值时,该变量必须在指针初始化之前已声明过,且变量类型应与指针类型一致。
      2. 可以用一个已有合法值的指针去初始化另一个指针变量。
      3. 不要用一个内部非静态变量去初始化 static 指针

    指针变量的赋值运算

    • 语法形式

      指针名 = 地址;
      

      注意:“地址”中存放的数据类型与指针类型必须相符

    • 向指针变量赋的值必须是地址常量或变量,不能是普通整数

      1. 通过地址运算“&”求得已定义的变量和对象的起始地址
      2. 动态内存分配成功时返回的地址
    • 例外:整数0可以赋给指针,表示空指针(NULL)。

    • 允许定义或声明指向void 类型的指针。该指针可以被赋予任何类型对象的地址。

      void *general;
      

    指针空值nullptr

    • 以往用0或者NULL去表达空指针的问题:
      C/C++的NULL宏是个被有很多潜在BUG的宏。因为有的库把其定义成整数0,有的定义成 (void*)0。在C的时代还好。但是在C++的时代,这就会引发很多问题。
    • C++11使用nullptr关键字,是表达更准确,类型安全的空指针

    指针的算术运算

    • 指针与整数的加减运算
    • 指针++,-- 运算

    运算的结果值取决于指针指向的数据类型,总是指向一个完整数据的起始位置。

    当指针指向连续存储的同类型数据时,指针与整数的加减运算和自增自减算才有意义。

    指针p加上或减去n

    其意义是指针当前指向位置的前方或后方第n个数据的起始位置。

    指针的++、–运算

    • 意义是指向下一个或前一个完整数据的起始。

    指针类型的关系运算

    • 指向相同类型数据的指针之间可以进行各种关系运算。
    • 指向不同数据类型的指针,以及指针与一般整数变量之间的关系运算是无意义的。
    • 指针可以和零之间进行等于或不等于的关系运算。例如:p==0或p!=0

    用指针访问数组元素

    数组名是数组的首地址,并且是常量,既然是常量,就不能改变其指向的地址。

    定义指向数组元素的指针

    • 定义与赋值

      int a[10],*pa; 
      pa = a; // 或 pa = &a[0]; &是地址运算符
      
      *pa就是a[0]*(pa+1)就是a[1]...*(pa+i)就是a[i].
      a[i], *(pa+i), *(a+i), pa[i]都是等效的。
      

      注意:不能写 a++,因为a是数组首地址、是常量。

    指针与数组

    指针数组

    • 数组的元素是指针型
    • 利用指针数组存放矩阵
    #include 
    using namespace std;
    int main() {
    	int line1[] = { 1, 0, 0 };	//矩阵的第一行
    	int line2[] = { 0, 1, 0 };	//矩阵的第二行
    	int line3[] = { 0, 0, 1 };	//矩阵的第三行
    	
    	//定义整型指针数组并初始化
    	int *pLine[3] = { line1, line2, line3 };	
    	cout << "Matrix test:" << endl;
      //输出矩阵
    	for (int i = 0; i < 3; i++) {
    	  for (int j = 0; j < 3; j++)
    	    cout << pLine[i][j] << " ";
        cout << endl;
    	}
    	return 0;
    }
    输出结果为:
    Matrix test:
    1,0,0
    0,1,0
    0,0,1
    
    • 指针数组与二维数组对比

      int array2[3][3] ={ { 1,0,0 }, { 0,1,0 }, { 0,0,1 } };
      

    可以看出,指针数组和普通数组相比,指针数组可以构建在相对灵活的内存空间中,不同指针所指向的数组间不必连续。而普通数组的所有元素则是存放在一个连续的内存空间中。

    思考,高维数组本质上可以看作是广义的一维数组。在这个广义的一维数组中,每一个元素可以被看作是一个一维及以上的数组。

    指针与函数

    以指针作为函数参数

    为什么需要用指针作参数?

    • 需要数据双向传递时(引用也可以达到此效果)
      • 用指针作为函数的参数,可以使被调函数通过函数形参指针存取主调函数中实参指针指向的数据,实现数据的双向传递
    • 需要传递一组数据,只传首地址运行效率比价高
      • 实参是数组名时形参可以是指针

    指针类型的函数

    • 若函数的返回值是指针,该函数就是指针类型的函数。

    指针函数的定义形式:

    存储类型  数据类型  *函数名() 
    { //函数体语句
    }
    

    注意:

    • 不要将非静态的局部地址用作函数的返回值。想想其内存的分配过程就会很明白为什么这么说
      • 错误例子:在子函数中定义局部变量后,将其地址返回给主调函数,就是非法地址
    • 返回的指针要确保在主调函数中是有效的、合法的地址
      • 正确的例子1:主调函数中定义的数组,在子函数中对该数组元素进行某种操作后,返回其中一个元素的地址,这就是合法有效的地址。
      • 正确的例子2:在子函数中通过动态内存分配new操作,取得的内存地址返回给主函数是合法有效的,但是内存的分配和释放不在同一级别,要注意不要忘记释放,避免内存泄漏

    正确的例子1:

    #include
    using namespace std;
    int main(){
        int array[10]; //主函数中定义的数组
        int* search(int* a, int num);
        for(int i=0; i<10; i++)
          cin>>array[i];
        int* zeroptr= search(array, 10);  //将主函数中数组的首地址传给子函数
        return 0;
    }
    int* search(int* a, int num){ //指针a指向主函数中定义的数组
        for(int i=0; i<num; i++)
          if(a[i]==0)
            return &a[i]; //返回的地址指向的元素是在主函数中定义的
    }//函数运行结束时,a[i]的地址仍有
    

    正确的例子2:

    #includeusing namespace std;
    int main(){
        int* newintvar();
        int* intptr= newintvar();
        *intptr=5; //访问的是合法有效的地址
        delete intptr; //如果忘记在这里释放,会造成内存泄漏
        return 0;
    }
    int* newintvar (){ 
        int* p=new int();
        return p; //返回的地址指向的是动态分配的空间
    }//函数运行结束时,p中的地址仍有效
    

    指向函数的指针

    定义形式:

    存储类型 数据类型 (*函数指针名)(); 
    

    所以定义函数指针时,不仅要声明函数指针名,还要声明函数的返回类型和函数的参数列表

    含义:函数指针指向的是程序代码存储区

    函数指针的典型用途——实现函数回调

    • 通过函数指针调用的函数

      例如将函数的指针作为参数传递给一个函数,使得在处理相似事件的时候,可以灵活的使用不同方法。

    • 调用者不关心谁是被调用者

      • 仅需知道存在一个具有特定原型和限制条件的被调用函数。

    对象指针

    定义

    对象指针定义形式类名 *对象指针名;

    // 举例
    Point a(5,10);
    Piont *ptr;
    ptr=&a;
    

    通过指针访问对象成员对象指针名->成员名

    ptr->getx() 相当于 (*ptr).getx(); // 这两种方式都可以访问到对象成员
    

    示例:使用指针来访问Point类的成员

    #include <iostream>
    using namespace std;
    
    class Point {
    public:
    	Point(int x = 0, int y = 0) : x(x), y(y) { }
    	int getX() const { return x; }
    	int getY() const { return y; }
    
    private:
    	int x, y;
    };
    
    int main() {
    	Point a(4, 5);
    	Point *p1 = &a; //定义对象指针,用a的地址初始化
    	cout << p1->getX() << endl;  //*******用指针访问对象成员
    
    	cout << a.getX() << endl; //**********用对象名访问对象成员
    
    	return 0;
    }
    

    this指针

    • 指向当前对象自己
    • 隐含于类的每一个非静态成员函数
    • 指出成员函数所操作的对象
      • 当通过一个对象调用成员函数时,系统先将该对象的地址赋给this指针,然后调用成员函数,成员函数对对象的数据成员进行操作时,就隐含使用了this指针

    例如:Point类的getX函数中的语句:

    return x;
    相当于:
    return this->x;
    

    曾经出现过的错误例子:

    class Fred; //前向引用声明
    
    class Barney {
    	Fred x; //错误:类Fred的声明尚不完善
    };
    
    class Fred {
    	Barney y;
    };
    

    正确的程序:

    正确的程序
    class Fred; //前向引用声明
    	class Barney {
    	Fred *x; // 指针本身的大小是确定的,因此这里的声明没有问题
    };
    
    class Fred {
    	Barney y;
    };
    

    要定义一个引用变量p,使之引用类MyClass的一个对象,正确的定义语句是(  )。

    正确答案D
    A MyClass p=MyClass;
    B MyClass p=new MyClass;
    C MyClass& p=new MyClass;
    D MyClass a,&p=a;

    【解析】

    A项错误,不能直接使用类给对象赋值;B项错误,p是类的对象,不能用对象的指针给其赋值;C项错误,p是引用变量,不能使用对象的指针进行赋值;D项正确,定义了MyClass类的一个对象a和引用变量p,并且声明p初始化为对a的引用。

    动态内存分配

    基本概念

    动态申请内存操作符 new

    • new 类型名T(初始化参数列表)
    • 功能:在程序执行期间,申请用于存放T类型对象的内存空间,并依初始化列表赋以初值。
    • 结果值:成功:T类型的指针,指向新分配的内存;失败:抛出异常。

    释放内存操作符delete

    • delete 指针p
    • 功能:释放指针p所指向的内存。p必须是new操作的返回值。

    示例:动态创建对象

    #include <iostream>
    using namespace std;
    
    class Point {
    public:
    	Point() : x(0), y(0) {
    		cout<<"Default Constructor called."<<endl;
    	}
    	Point(int x, int y) : x(x), y(y) {
    		cout<< "Constructor called."<<endl;
    	}
    	~Point() { cout<<"Destructor called."<<endl; }
    	int getX() const { return x; }
    	int getY() const { return y; }
    	void move(int newX, int newY) {
    		x = newX;
    		y = newY;
    	}
    
    private:
    	int x, y;
    };
    
    int main() {
    	cout << "Step one: " << endl;
    	Point *ptr1 = new Point; //调用默认构造函数
    	delete ptr1; //删除对象,自动调用析构函数
    	cout << "Step two: " << endl;
    	ptr1 = new Point(1,2);
    	delete ptr1;
    	return 0;
    }
    
    运行结果:
    Step One:
    Default Constructor called.
    Destructor called.
    Step Two:
    Constructor called.
    Destructor called.
    

    动态数组的分配和释放

    • 分配:new 类型名T [ 数组长度 ]
      • 数组长度可以是任何表达式,在运行时计算
    • 释放:delete[] 数组名p
      • 释放指针p所指向的数组。
        p必须是用new分配得到的数组首地址

    示例:动态创建对象数组

    #include<iostream>
    using namespace std;
    
    class Point { //类的声明和上一示例相同,略 };
    int main() {
    	Point *ptr = new Point[2]; //创建对象数组
    	ptr[0].move(5, 10); //通过指针访问数组元素的成员
    	ptr[1].move(15, 20); //通过指针访问数组元素的成员
    
    	cout << "Deleting..." << endl;
    	delete[] ptr; //删除整个对象数组
    	return 0;
    }
    
    运行结果:
    Default Constructor called.
    Default Constructor called.
    Deleting...
    Destructor called.
    Destructor called.
    

    动态创建多维数组

    预警,本节理解起来有点抽象,但务必理解

    创建格式:new 类型名T[第1维长度][第2维长度]…;

    • 如果内存申请成功,new运算返回一个指向新分配内存首地址的指针(这个指针指向第一个广义元素的地址)。

      char (*fp)[3]; // 这个语句等价于:char ch[3]; char *fp = ch;
      
      fp = new char[2][3];
      

      理解:任何高维数组(假设数组标记为(n,m,j,…)),本质上都可以看作是广义的一维数组,也就是任何一个(n,m,j,…)数组本质上就是由n个(m,j,…)子数组组成。

      示例:动态创建多位数组

      #include <iostream>
      
      using namespace std;
      int main() {
          
          // 请掌握这种动态创建数组的方式,(*p)[][]表示创建了变量指针指向的多维数组,这个指针变量 p 指向new出来的第一个广义元素[9][8]
          // 因为new返回的就是广义一维数组的第一个广义元素的地址,且new返回的地址必须和等号左边接受地址的指针的类型匹配,否则编译器会报错
      	int (*cp)[9][8] = new int[7][9][8]; 
          
      	for (int i = 0; i < 7; i++)
      		for (int j = 0; j < 9; j++)
      			for (int k = 0; k < 8; k++)
      				*(*(*(cp + i) + j) + k) =(i * 100 + j * 10 + k);
      
      	for (int i = 0; i < 7; i++) {
      		for (int j = 0; j < 9; j++) {
      			for (int k = 0; k < 8; k++)
      				cout << cp[i][j][k] << " ";
      
      			cout << endl;
      		}
      		cout << endl;
      	}
      	delete[] cp;
      	return 0;
      }
      

      再看一个举例:

      int a[2][3]={1,2,3,4,5,6}; 
      int (*fp)[3]; // 整体上看是定义了一个含有三个元素的一维数组。再分析,fp是一个指针,指向这个一维数组。
      fp = a;
      // 从广义一维数组的角度讲,*fp、*a、fp[0]、a[0]四个操作都抵达了广义一维数组的第一个广义元素(在这里就是一维数组):{1,2,3}
      // 也就是说此时的操作层面已降低至一维数组{1,2,3}的内部,但此时指向的依然是地址,也可以理解为返回的依然是地址。
      // *(*fp+i)、*(*a+i)、fp[0][i]、a[0][i]就是在{1,2,3}层面上偏移i元素宽度的字节,此时返回的就是具体的数值。
      
      int a[2][3]={1,2,3,4,5,6};
      int (*fp)[3];
      fp = a;
      
      cout << "fp[0]\t" << fp[0] << endl; // a代表指向数组第一个元素的指针
      cout << "*fp\t" << *fp << endl;
      cout << "**a\t" << **a << endl; //
      cout << "a+1:\t" << a+1 << endl;
      cout << "&a+1:\t" <<&a+1 << endl;
      cout << "**(a+1)\t" << **(a+1) << endl;
      cout << "*(&a+1)\t" << *(&a+1) << endl;
      cout << "**(*(&a+1)-1)\t" << **(*(&a+1)-1) << endl;
      cout << "==========================\n";
      cout << "fp\t" << fp << endl;
      cout << "*fp\t" << *fp << endl;
      cout << "**fp\t" << **fp << endl;
      cout << "*(*fp+1)\t" << *(*fp+1) << endl;
      cout << "**(fp+1)\t"<< **(fp+1) << endl;
      cout << "=================" << endl;
      cout << "sizeof(a)\t" << sizeof(a) << endl;
      cout << "sizeof(fp)\t" << sizeof(fp) << endl;
      cout << "sizeof(*a)\t" << sizeof(*a) << endl;
      cout << "sizeof(*fp)\t" << sizeof(*fp) << endl;
      cout << "sizeof(**a)\t" << sizeof(**a) << endl;
      cout << "sizeof(**fp)\t" << sizeof(**fp) << endl;
      
      // 结果:
      fp[0]   0x63fe00
      *fp     0x63fe00
      **a     1
      a+1:    0x63fe0c
      &a+1:   0x63fe18
      **(a+1) 4
      *(&a+1) 0x63fe18
      **(*(&a+1)-1)   4
      ==========================
      fp      0x63fe00
      *fp     0x63fe00
      **fp    1
      *(*fp+1)        2
      **(fp+1)        4
      =================
      sizeof(a)       24
      sizeof(fp)      8
      sizeof(*a)      12
      sizeof(*fp)     12
      sizeof(**a)     4
      sizeof(**fp)    4
      
      • 第一点要明白的是:a[i] = *(a+i),a本质上就是指针,只不过是一个常量指针(数组名都是常量指针)
      • 这里a的意义就是存放指向整个二维数组首地址,请注意,是指向二维数组的首地址,并没有说是指向了二维数组的第一个元素的地址,尽管二维数组的首地址和该二维数组的第一个元素的地址的字面值一样,但是含义和性质不在一个层面。
        • 所以*a不会直接取到第一个元素1这个值
      • 这里fp的意义就是存放着指向了二维数组的第一个含有三个元素的一维数组的首地址,请注意,是指向一维数组的首地址,并没有说是指向了一维数组的第一个元素的地址,尽管该一维数组的首地址和该一维数组的第一个元素的地址的字面值一样,但是含义和性质不同。
        • 所以*fp不会直接取到第一个元素1这个值
      • 依次递归下去,直到指向具体的数值元素。

      动态数组封装成类

      优势:

      • 更加简洁,便于管理
      • 可以在访问数组元素前检查下标是否越界

      示例:动态数组

    #include <iostream>
    #include <cassert>
    
    using namespace std;
    
    class Point { //类的声明之前相同 … };
    class ArrayOfPoints { //动态数组类
    public:
    	ArrayOfPoints(int size) : size(size) { // 构造函数,构造是创建动态数组
    		points = new Point[size];
    	}
    
    	~ArrayOfPoints() { // 退出前调用析构函数删除动态分配的数组对象
    		cout << "Deleting..." << endl;
    		delete[] points;
    	}
    
    	Point& element(int index) { // 获得指定元素,并检查下表是否越界
    		assert(index >= 0 && index < size);
    		return points[index];
    	}
    
    private:
    	Point *points; //指向动态数组首地址
    	int size; //数组大小
    };
    
    int main() {
    	int count;
    	cout << "Please enter the count of points: ";
    	cin >> count;
    	ArrayOfPoints points(count); //创建数组对象
    	points.element(0).move(5, 0); //访问数组元素的成员
    	points.element(1).move(15, 20); //访问数组元素的成员
    	return 0;
    }
    
    运行结果:
    
    Please enter the number of points:2
    Default Constructor called.
    Default Constructor called.
    Deleting...
    Destructor called.
    Destructor called.
    

    为什么element函数返回对象的引用?

    返回“引用”可以用来操作封装数组对象内部的数组元素。如果返回“值”则只是返回了一个“副本”,通过“副本”是无法操作原来数组中的元素的。

    vector对象

    为什么需要vector?

    • 封装任何类型动态数组,自动创建和删除。
    • 数组下标越界检查。

    vector对象的定义

    • vector<元素类型> 数组对象名(数组长度);

      vector<int> arr(5)
      // 建立大小为5的int数组
      

    vector对象的使用

    • 对数组元素的引用
      • 与普通数组具有相同形式:vector对象名 [ 下标表达式 ]
    • vector数组对象名不表示数组首地址
    • 获得数组长度
      • 用size函数:数组对象名.size()

    vector应用举例:

    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    //计算数组arr中元素的平均值
    double average(const vector<double> &arr){
    	double sum = 0;
    	for (unsigned i = 0; i<arr.size(); i++)
    		sum += arr[i];
    	return sum / arr.size();
    }
    
    int main() {
    	unsigned n;
    	cout << "n = ";
    	cin >> n;
    	vector<double> arr(n); //创建数组对象
    	cout << "Please input " << n << " real numbers:" << endl;
    	for (unsigned i = 0; i < n; i++)
    		cin >> arr[i];
    	cout << "Average = " << average(arr) << endl;
    	return 0;
    }
    
    //基于范围的for循环配合auto举例
    #include <vector>
    #include <iostream>
    
    int main(){
    	std::vector<int> v = {1,2,3}; // 为什么可以这样赋初值???
    	for(auto i = v.begin(); i != v.end(); ++i)
    		std::cout << *i << std::endl;
        
    	for(auto e : v)
    		std::cout << e << std::endl;
    }
    

    string 类

    • 使用字符串类string表示字符串
    • string实际上是对字符数组操作的封装

    string类常用的构造函数

    • string(); //默认构造函数,建立一个长度为0的串

      string s1;
      
    • string(const char *s); //用指针s所指向的字符串常量初始化string对象

      string s2 = “abc”;
      
    • string(const string& rhs); //复制构造函数

      string s3 = s2;
      

    string类常用操作

    • s + t 将串s和t连接成一个新串
    • s = t 用t更新s
    • s == t 判断s与t是否相等
    • s != t 判断s与t是否不等
    • s < t 判断s是否小于t(按字典顺序比较)
    • s <= t 判断s是否小于或等于t (按字典顺序比较)
    • s > t 判断s是否大于t (按字典顺序比较)
    • s >= t 判断s是否大于或等于t (按字典顺序比较)
    • s[i] 访问串中下标为i的字符

    示例1: string类应用举例

    #include <string>
    #include <iostream>
    using namespace std;
    //根据value的值输出true或false
    
    //title为提示文字
    inline void test(const char *title, bool value)
    {
    	cout << title << " returns "
    		<< (value ? "true" : "false") << endl;
    }
    
    int main() {
    	string s1 = "DEF";
    	cout << "s1 is " << s1 << endl;
    	string s2;
    	cout << "Please enter s2: ";
    	cin >> s2;
    	cout << "length of s2: " << s2.length() << endl;
    	//比较运算符的测试
    	test("s1 <= \"ABC\"", s1 <= "ABC");
    	test("\"DEF\" <= s1", "DEF" <= s1);
    	//连接运算符的测试
    	s2 += s1;
    	cout << "s2 = s2 + s1: " << s2 << endl;
    	cout << "length of s2: " << s2.length() << endl;
    	return 0;
    }
    
    结果:
    s1 is DEF
    Please enter s2: DFFA
    length of s2: 4
    s1 <= "ABC" returns false
    "DEF" <= s1 returns true
    s2 = s2 + s1: DFFADEF
    length of s2: 7
    

    考虑:如何输入整行字符串?

    • cin>>操作符输入字符串,会以空格作为分隔符,空格后的内容会在下一回输入时被读取

    输入整行字符串

    • getline可以输入整行字符串(要包string头文件),例如:
    getline(cin, s2);
    
    • 输入字符串时,可以使用其它分隔符作为字符串结束的标志(例如逗号、分号),将分隔符作为getline的第3个参数即可,例如:
    getline(cin, s2, ',');
    

    例6-24 用getline输入字符串

    include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
    	for (int i = 0; i < 2; i++){
    		string city, state;
    		getline(cin, city, ','); //以 逗号 作为分隔符
    		getline(cin, state);
    		cout << "City:" << city << “ State:" << state << endl;
    	}
    
    	return 0;
    }
    
    运行结果:
    Beijing,China
    City: Beijing State: China
    San Francisco,the United States
    City: San Francisco State: the United States
    

    C风格的字符串

    字符串常量

    例:“program”

    • 各字符连续、顺序存放,每个字符占一个字节,以‘\0’结尾,相当于一个隐含创建的字符常量数组

    • “program”出现在表达式中,表示这一char数组的首地址

    • 首地址可以赋给char常量指针:

      const char *STRING1 = "program";
      

    用字符数组存储字符串(C风格字符串)

    char str[8] = { 'p', 'r', 'o', 'g', 'r', 'a', 'm', '\0' };

    char str[8] = "program";

    char str[] = "program";

    在这里插入图片描述

    用字符数组表示字符串的缺点

    • 执行连接、拷贝、比较等操作,都需要显式调用库函数,很麻烦
    • 当字符串长度很不确定时,需要用new动态创建字符数组,最后要用delete释放,很繁琐
    • 字符串实际长度大于为它分配的空间时,会产生数组下标越界的错误
    展开全文
  • 1.对象数组的使用 对象也可以数组来存放,必须有两个步骤:(1)声明类类型的数组变量,并用new分配内存空间给数组(2)new产生新的对象,并分配内存空间给它 例:要创建三个Car类类型的数组元素 Car c[]=new...

    1.对象数组的使用

    对象也可以用数组来存放,必须有两个步骤:(1)声明类类型的数组变量,并用new分配内存空间给数组(2)用new产生新的对象,并分配内存空间给它

    例:要创建三个Car类类型的数组元素

    Car c[]=new Car[3];//创建Car类类型的数组元素,并 分配内存空间

    动态初始化,利用for循环完成对象数组内的初始化操作

    例:  for(int i=0;i<c.length;i++){

                      c[i]=new Car();

             }

    静态初始化

    例:   Car c[]={new Car(),new Car(),new Car()};

    public class Car {
              String color;
              String name;
              Car(String c,String n){
                  color=c;
                  name=n;
              }
             String show(){
                  return "这是"+color+name;
              }
    }
    public class car1 {
    
        public static void main(String[] args) {
            Car c[]={new Car("红色","奥迪"),new Car("白色","大众"),new Car("黑色","奔驰")}; 
               for(int i=0;i<c.length;i++){
                   System.out.println(c[i].show());
               }
        }
    
    }

    运行结果:

    这是红色奥迪
    这是白色大众
    这是黑色奔驰

    2.内部类

    内部类的基本格式:

    标识符 class 外部类名称{

      //外部类的成员

           标识符 class 内部类名称{

                //内部类的成员

             }

      }

     内部类可以直接调用外部类中的属性,外部类不可以访问内部类声明的属性。内部类用static声明后,内部类不能访问非static定义的外部类属性

    public class out1 {
          int score;
              void show(){
                  in1 in=new in1();
                  in.talk();
              }
          class in1{
              void talk(){
                  System.out.println("他的分数是;"+score);
              }
          }
          
    }
    public class out11 {
    
        public static void main(String[] args) {
            out1 out=new out1();
            out.score=98;
            out.show();
    
        }
    
    }

    3.在类外部引用内部类

    内部类可以通过创建对象从外部类之外被调用,只要将内部类声明成public。

    public class out1 {
          int score;
              void show(){
                  in1 in=new in1();
                  in.talk();
              }
          public class in1{
              void talk(){
                  System.out.println("他的分数是;"+score);
              }
          }
          
    }
    public class out11 {
    
        public static void main(String[] args) {
            out1 out=new out1();
            out1.in1 in=out.new in1();//用外部类的对象实例化内部类的一个对象
            out.score=98;
            in.talk();
    
        }
    
    }

    4.在方法中定义内部类

    public class out1 {
        int score;
        void show() {
            class in1 {
                void talk() {
                    System.out.println("他的分数是;" + score);
                }
            }
            in1 in = new in1();
            in.talk();
        }
    
    }
    public class out11 {
    
        public static void main(String[] args) {
            out1 out=new out1();
            out.score=98;
            out.show();
        }
    }

    在方法中定义的内部类只能访问方法中的final类型的 局部变量,因为用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期

    public class out1 {
        int score;
        void show(final String s) {
            final String name="lindy";
            class in1 {
                void talk() {
                    System.out.println(name+s+"的分数是;" + score);
                }
            }
            in1 in = new in1();
            in.talk();
        }
    
    }
    public class out11 {
    
        public static void main(String[] args) {
            out1 out=new out1();
            out.score=98;
            out.show("数学");
        }
    }

     

    转载于:https://www.cnblogs.com/dongdong-wang/p/6699318.html

    展开全文
  • C++创建动态对象数组

    2020-10-29 14:34:49
    已经建好一个Circle 类,并且对构造函数进行了重载。... // c是一个指向对象数组的首地址,类似普通数组,c[i]已经代表对象了。不能-》运算符,而是点点 cout << c[i].getArea() << endl; } ...
  • c++程序设计 遍历对象数组

    千次阅读 2020-01-30 20:17:30
    编写主函数,利用 std::array 创建包含10个对象的Circle数组初始化基于范围的for循环遍历Circle数组,求10个Circie对象的面积之和(10分) 题目内容: 类Circle有两个构造函数。无参构造函数没有函数体,...
  • //arrayWithObjects初始化一个不可变的数组对象。 //初始化的值之间使用逗号分开,以nil结束。 NSArray6 *city = [NSArray arrayWithObjects:@"上海",@"广州",@"重庆",nil]; for(int i=0; i [city count];i++)
  • 面向对象的一些知识暂时告一段落,从本文开始,...数组的定义及初始化定义及动态初始化方式一,java推荐用法: type [] 变量名 = new type[数组中元素的个数];  //举例  int[] a = new int[10]; for (int i = 0...
  • memset中sizeof(动态分配的数组)问题

    千次阅读 2016-03-06 14:59:47
    数组初始化的时候常用for()循环,不过如果考虑效率话,最好memset(),下面简单介绍以下memset()。 函数原型: void *memset(void *s, int ch, size_t n) 函数解释:将s中前n个字节替换为ch并返回s;  memset:它...
  • 4. 数组和指针

    2016-04-13 21:58:02
    数组的维数必须值大于等于1的常量表达式定义(整型常量,枚举常量,const修饰已初始化对象),不能为非const变量或者在运行阶段才知道值的const变量。 不允许数组直接复制和赋值。(只能循环一个个赋值) int a2...
  • 若想要输出数组,需要用for循环来实现。最终实现的效果为java中数组的格式。如: {1,2,3} 一、新建一个数组 // 初始化数组 int[] array = {5,4,5,9}; 二、遍历数组 System.out.print("{"); for(int i = 0;i<...
  • Python 中初始化一个8*8的数组时,应该使用:Chess = [[0 for column in range(8)] for row in range(8)]而初始化一个一维数组的时候,可以:Queen = [0] * 8但是初始化二维数组,也就是:Chess = [[0] * 8] * 8...
  • // 初始化日期数组,任意赋值 days[1] = new Dates(2014,3,1); days[2] = new Dates(2013,4,5); days[3] = new Dates(2014,5,28); days[4] = new Dates(2012,8,9); days[5] = new Dates(2001,12,11)...
  • c++变量初始化(猜想......)

    千次阅读 2009-07-24 16:58:00
    堆,容器中和类显式空构造函数的对象会被调用其构造函数初始化,但并不会被初始化为相应0,(没有数组)如 char ch[10]; for(int i = 0; i cout 结构和类成员的初始化:谈到结构和类成员,除非提供显示...
  • 介绍 C+ + 03初始化是前后矛盾。例如,它不让你初始化POD数组...c++限制规则变得更明显03初始化时,你需要初始化一个容器对象填充。通常,你要强迫自己用的是一种笨重回路作为一个解决办法: std::vector vi; for (in
  • 接下来代码和原文差不多,建立一个数组用来存放动画帧,然后用数组初始化一个CCAnimation动画对象.接着将牛放在屏幕中心,然后运行动画:NSMutableArray *walkAnimFrames = [NSMutableArray array]; for (int i = 1...
  • Java for 循环语句用法详解for循环包含普通for循环和for each循环,它可以更简单地方式来遍历数组和Collection等类型的对象。Javafor循环包含下面2中语法。语法for(初始化条件; 判断条件; 条件改变){//执行操作}...
  • 参数对象去执行init初始化函数。init函数中先进行了大量参数初始化操作<pre><code>this.xxx = blabla</code></pre>,然后剩下这么几行代码(后文所有英文注释是尤雨溪所写,中文是...
  • 接下来代码和原文差不多,建立一个数组用来存放动画帧,然后用数组初始化一个CCAnimation动画对象.接着将牛放在屏幕中心,然后运行动画: NSMutableArray *walkAnimFrames = [NSMutableArray array]; for (int i...
  • foreach语句

    2020-09-20 19:20:55
    foreach是for语句特殊简化版本,不能完全取代for语句,但任何foreach语句都可以改写为for语句版本,这个并不是一个关键字,此语句在遍历数组方面提供了很大便利。 句法如下: for(元素变量x:遍历对象obj){ 引用...
  • 如果我们想初始化这个数组,我们可以通过初始化列表语法直接执行: int main() { int array[5] { 5, 4, 3, 2, 1 }; //初始化列表 for (int count=0; count &lt; 5; ++count) std::cout &lt...
  • 初始大小和动态扩容策略</li><li>有效解决散列冲突</li><li>对一个工业级散列表实现要遵守几点:首先支持快速查询、删除、插入等操作;其次,内存占用要合理,不要过多浪费内存;...
  • 因 此在赋值后应该及时销毁或者初始化 L2,以免发生不可预见错误。 比较 使用 Contains 方法。 ArrayList Array1=new ArrayList(); Array1.Add("as"); bool b1=Array1.Contains("as"); MessageBox.Show(b1....
  • java之阶段性胜利

    2019-11-29 22:15:16
    - 多态(polymorphosm) - 对象的转型(casting) - 关于final修饰符 - 关于数组的使用 - 数组的初始化方式 - 遍历数组以及for-each循环 明天开始就一个小项目来练手
  • Java SE 第二篇

    2019-09-27 10:23:28
    二、 Java SE 第二篇 1. Arrays 数组 // 声明一维数组,[]内不允许有值 ...// 对一维数组元素的初始化,动态初始化用 for 循环 int arr[] = {1, 2, 3};// 静态初始化; // 声明二维数组...
  • //为原型添加初始化的方法(作用:在页面上显示这个食物) //因为食物要在地图上显示,所以,需要地图这个参数(map---就是页面上.class=map这个div) Food.prototype.init=function(map){ //先删除这个小...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 263
精华内容 105
关键字:

对象数组的用for初始化