zoukankan      html  css  js  c++  java
  • 算法之美--2.2 Array

    2016-12-02    00:24:12

          利用抽象数据类型实现Array;主要用C++模板实现数组类;体会一个完整的C++类的写法,能顺利写出来的人不多了,特别是对复制构造函数和重载= []运算,都需要扎实的基本攻。然后在测试程序中巧妙的实现了质数序列的输出,和一般的求质数方法有些不一样!

    //#include "Array.h"
    #include <stdio.h>
    
    const int DefaultSize = 100;
    
    template <class Type>
    class Array
    {
    private:
        Type *elements;   //数组存放的空间
        int ArraySize;    //当前长度
    public:
        Array(int Size = DefaultSize);
        Array(const Array<Type>& x);   //复制构造函数
        ~Array(){ delete[] elements; }
    
        Array<Type>& operator =(const Array<Type>& rhs);  //数组复制
        Type& operator [] (int i);                        //取元素值
        int Length()const { return ArraySize; };
        void ReSize(int sz);
    };
    
    template <class Type>
    Array<Type>& Array<Type>::operator =(const Array<Type>& rhs)
    {
        int n = rhs.ArraySize; //取rhs的数组大小
        if(ArraySize!=n)
        {
            delete[] elements;
            elements = new Type[n];  //重新分配n个元素的内存
            if (elements==NULL)
            {
                ArraySize = 0;
                cerr << "存储分配错误!" << endl;
                exit(1);
            }
            ArraySize = n;
        }
        //从rhs向本对象复制元素
        Type *destptr = elements;
        Type *srcptr = rhs.elements;
        while (n--)
        {
            *destptr++ = *srcptr++;
        }
        return *this;
    }
    
    template <class Type>
    Array<Type>::Array(int sz)
    {
        if (sz <= 0)
        {
            ArraySize = 0;
            cerr << "非法数组大小" << endl;
            return;
        }
        elements = new Type[sz];
        if (elements==NULL)
        {
            ArraySize = 0;
            cerr << "存储分配错误!" << endl;
            exit(1);
        }
        ArraySize = sz;
    }
    
    template <class Type>
    Array<Type>::Array(const Array<Type>& x)
    {
        int n = x.ArraySize;
        ArraySize = n;
        elements = new Type[n];
        if (elements==    NULL)
        {
            ArraySize = 0;
            cerr << "存储分配错!"<<endl;
            exit(1);
        }
        Type* srcptr = x.elements;
        Type* destptr = elements;
        while (n--)
        {
            *destptr++ = *srcptr++;
        }
    }
    
    template<class Type>
    Type& Array<Type>::operator [] (int i)
    {
        if (i<0||i>ArraySize-1)
        {
            cerr << "数组下标超界" << endl;
            exit(1);
        }
        return elements[i];
    }
    
    template <class Type>
    void Array<Type>::ReSize(int sz)
    {
        if (sz>=0&&sz!=ArraySize)
        {
            Type *newArray = new Type[sz];
            if (newArray==NULL)
            {
                cerr << "内存分配失败!" << endl;
                return;
            }
            int n = (sz <= ArraySize) ? sz : ArraySize;// 按照新的大小确定传送数据的个数
            
            Type *srcptr = elements;
            Type *destptr = newArray;
            while (n--)
            {
                *destptr++ = *srcptr++;
            }
            delete[] elements;
            elements = newArray;
            ArraySize = sz;
        }
    }
    
    
    #include <iostream>
    #include <iomanip>
    
    using namespace std;
    int main(int argc, char ** argv)   
    {
        Array<int> A(10);       //数组输出质数序列
        int n;
        int primecount = 0, i, j;
    
        cout << "Enter a value>=2 as upper limit for prime numbers:";
        cin >> n;
        A[primecount++] = 2;   //2是质数
        for (int i = 3; i < n;i++)
        {
            if (primecount==A.Length())
            {
                A.ReSize(primecount + 10);
            }
            if (i%2==0)  //偶数跳过
            {
                continue;
            }
            j = 3;
            while (j<=i/2&&i%j!=0)
            {
                j += 2;
            }
            if (j>i/2)
            {
                A[primecount++] = i;
            }
        }
    
        for (int i = 0; i < primecount;i++)
        {
            cout << setw(5) << A[i];
            if ((i+1)%10==0)
            {
                cout << endl;
            }
        }
        cout << endl;
    
        return 0;
    }

    exit(0):正常运行程序并退出程序;

    exit(1):非正常运行导致退出程序;

    return():返回函数,若在主函数中,则会退出函数并返回一值。

    详细说:

    1. return返回函数值,是关键字; exit 是一个函数。

    2. return是语言级别的,它表示了调用堆栈的返回;而exit是系统调用级别的,它表示了一个进程的结束。
    3. return是函数的退出(返回);exit是进程的退出。

    4. return是C语言提供的,exit是操作系统提供的(或者函数库中给出的)。exit是一个库函数,exit(1)表示发生错误后退出程序,exit(0)表示正常退出。在stdlib.h中exit函数是这样子定义的:void exit(int status)。这个系统调用是用来终止一个进程的,无论在程序中的什么位置,只要执行exit,进程就会从终止进程的运行。讲到exit这个系统调用,就要提及另外一个系统调用,_exit,_exit()函数位于unistd.h中,相比于exit(),_exit()函数的功能最为简单,直接终止进程的运行,释放其所使用的内存空间,并销毁在内存中的数据结构,而exit()在于在进程退出之前要检查文件的状态,将文件缓冲区中的内容写回文件。

    5. return用于结束一个函数的执行,将函数的执行信息传出给其他调用函数使用;exit函数是退出应用程序,删除进程使用的内存空间,并将应用程序的一个状态返回给OS或其父进程,这个状态标识了应用程序的一些运行信息,这个信息和机器和操作系统有关,一般是 0 为正常退出, 非0 为非正常退出。

    6. 非主函数中调用return和exit效果很明显,但是在main函数中调用return和exit的现象就很模糊,多数情况下现象都是一致的。

  • 相关阅读:
    python习题:操作mysql数据库,传入sql返回执行结果
    mysql-5.7.21-winx64.zip 下载安装
    Python用起来极度舒适的强大背后
    Python标准库映射类型与可散列数据类型的关系
    windows下《Go Web编程》之Go开发工具
    20行以内python代码画出各种减压图
    windows下《Go Web编程》之Go命令
    navicat连接Oracle数据库
    golang 报错illegal rune literal
    golang 缺少逗号报错问题
  • 原文地址:https://www.cnblogs.com/ranjiewen/p/6124228.html
Copyright © 2011-2022 走看看