• 现代程序设计 homework-08


    现代程序设计 homework-08

    第八次作业。

    理解C++变量的作用域和生命周期

    作用域就是一个变量可以被引用的范围,如:全局作用域、文件作用域、局部作用域;而生命周期就是这个变量可以被引用的时间段。不同生命周期的变量,在程序内存中的分布位置是不一样的。一个程序的内存分为代码区、全局数据区、堆区、栈区,不同的内存区域,对应不同的生命周期。

    int* aa(int a)
    {
        int b = a;
        return &b;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
        int i=0;
        if (i==0){int* p = &i;}//这里的p的作用域在if语句中
        int* p = aa(12);  //可以再次定义p,因为上面的p的生命周期已完结
        cout<<&p<<endl;     //不能正确输出,因为指针所指地址生命周期已经完结
        return 0;
    }

    理解堆和栈,两种内存的申请和释放的方式

     C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。

     ,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

     ,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

     自由存储区,就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

     全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

     常量存储区,这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改。

    简单来说,由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 

    一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 

    一下用简单的代码说明C++中堆和栈:

    int a = 0; // 全局初始化区 
    char *p1; // 全局未初始化区 
    main() 
    { 
      int b; //
      char s[] = "abc"; //
      char *p2; //
      char *p3 = "123456"; // 123456在常量区,p3在栈上。 
      static int c =0// 全局(静态)初始化区 
      p1 = (char *)malloc(10); 
      p2 = (char *)malloc(20); // 分配得来得10和20字节的区域就在堆区。 
      strcpy(p1, "123456"); // 123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 
    } 

    理解unique_ptr和shared_ptr

    首先,智能指针都具有普通指针的功能。

    unique_ptr是一种不能共享的智能指针,我们不能复制它、在函数中传递它的值或者是在需要使用其副本的STL中使用。总之,unique_ptr所指向的内存只能被它所指,如果其他unique_ptr想要指向同一块内存,需要使用move()语句。

    shared_ptr是可以共享地址的指针。其实就是不同于unique_ptr的一种存在。一个shared_ptr可以被复制,给其他shared_ptr赋值,许多shared_ptr指向同一的内存,并都可以修改所指地址中内容。shared_ptr之所以智能,就是当指向一个存储块的shared_ptr数量减至0时(超出生命周期等原因),该存储块会被自动释放。

    用“C++0x”,“C++11 & STL”两种不同的代码风格分割一个url,并上传代码到博客上

    代码如下:

    #include "stdafx.h"
    #include <stdio.h>
    #include <regex>
    #include <string>
    #include <iostream>
    using namespace std;
    
    class urlDiv
    {
    public:
        urlDiv()
        {
            str = "";
            isUrl = true;
        }
        urlDiv(string s)
        {
            str = s + '#';
            isUrl = true;
        }
        void divStr()//C++0x风格
        {
            resL = 0;
            string tmp = "";    //暂存字符串
            bool hasC = false;    //是否出现':'
            //string tmpDiv = "";
            int i=0;
            while (i < str.length())
            {
                if ((str[i]<='z' && str[i]>='a')||(str[i]<='Z' && str[i]>='A')||(str[i]<='9' && str[i]>='0')||str[i]<0)        //数字字母或中文
                {
                    tmp+=str[i];
                }else
                {
                    if (str[i]==':')        //当前字符为':'判断
                    {
                        if (i<str.length()-2 && hasC==false)    //判断后两位是否为"//"
                        {
                            if (str[i+1]=='/' && str[i+2]=='/')
                            {
                                hasC = true;
                                result[resL++] = tmp;
                                tmp="";
                                i+=2;
                            }else
                            {
                                isUrl = false;
                                return;
                            }
                        }else
                        {
                            isUrl = false;
                            return;
                        }
                    }else if (str[i] == '-' || str[i] == '_')//-_正常连接
                    {
                        tmp+=str[i];
                    }else if (str[i] == '.' || str[i] == '/' || str[i]=='#')//只用'.' '/' '#'分割,其中手动'#'是在字符串末尾加的,便于处理
                    {
                        if (tmp=="")//如果分隔符前是非法字符,则报错
                        {
                            isUrl = false;
                            return;
                        }
                        result[resL++] = tmp;    //否则加入分隔结果中
                        tmp = "";
                    }else
                    {
                        char c=str[i];
                        isUrl = false;
                        return;
                    }
                }
                i++;
            }
        }
        void divStrBySTL()//C++11 & STL风格,用lambda表达式实现
        {
            resL = 0;
            char s[100];    //与str相等的字符数组
            int i;
            string tmp="";
            string tmp2="";
            for (i=0;i<str.length();i++)
                s[i]=str[i];
            s[i]='';
            for_each(s,s+i,[&] (char c){
                if ((c<='z' && c>='a')||(c<='Z' && c>='A')||(c<='9' && c>='0')|| c<0 || c=='-' || c=='_')    //合法字符加入tmp中
                {
                    tmp+=c;
                    if (tmp2=="." || tmp2=="/" || tmp2=="://" || tmp2=="#" || tmp2=="")    //如果合法字符前分隔符非法,则报错
                        tmp2="";
                    else
                        isUrl = false;
                }else 
                {
                    tmp2+=c;
                    if (tmp!="")    //tmp2为分隔符暂存字符串
                    {
                        result[resL++] = tmp;
                        tmp="";
                    }
                }
            });
        }
        void outputResult()//输出分隔结果
        {
            if (isUrl)
            {
                int i;
                for (i=0;i<resL-1;i++)
                    cout<<result[i]<<',';
                cout<<result[i]<<endl;
            }else
                cout<<"is not a URL"<<endl;
        }
    private:
        string str;        //输入字符
        bool isUrl;        //是否为合法URL
        string result[100];//存分隔结果
        int resL;        //结果数组长度
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        string s = "http://msdn.microsoft.com/en-us/library/vstudio/啊哈.aspx";
        urlDiv *div = new urlDiv(s);
        div->divStr();        //使用c++0x风格分隔
        div->outputResult();    //使用c++11 & STL风格分隔
        div->divStrBySTL();
        div->outputResult();
        return 0;
    }

    测试输入的URL为:http://msdn.microsoft.com/en-us/library/vstudio/啊哈.aspx

    输出结果如下:

  • 相关阅读:
    Java Class的field如果以小写t开头
    ACM集训日志——day1——15.7.8
    分金币 Uva 11300
    RMQ小结
    Poj 水题
    Codeforces Round #278 (Div. 2)
    poj 3685
    poj 3579
    vConsole
    js更换自定义鼠标指针图片
  • 原文地址:https://www.cnblogs.com/z-mac/p/3427427.html
Copyright © 2020-2023  润新知