zoukankan      html  css  js  c++  java
  • volcanol的工控博客

      前面说了写关于数组和指针的内容,这次在这里讨论一下字符串,讨论一下C语言风格的字符串。 在C语言里面我们利用字符数组来对字符串进行处理,

    在C++里面我们前面说过一种类类型string可以对字符串进行处理, 这里需要引起注意,因为两种机制存在一定的区别。

    一、字符串

    1、字符串字面值

      利用左、右分号 " 和 " 括起来的字符是一个字符串字面值, 字符串字面值可以自引用,可以通过数组、指针进行引用。如下所示:

      ""       空字符串, 占用1个字节, 这个字节用来存储空字符:''

      "volcanol"   字符串volcanol.  

    int main()
    {
        "volcanol";  //do nothing
    
        cout<<sizeof("")<<endl;
    
        return 0;
    }

    程序的执行结果如下所示:

    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    1

    2、字符串数组、字符串与指针

      在定义字符数组的时候,可以通过字符串字面值在定义的时候进行初始化,如下所示。字符串数组可以通过下标来访问,同时也可以通过指针来访问,具体

    实例如下所示。

    Exp:

    int main()
    {
        char cStrArray[]="volcanol";
    
        for(size_t i=0; i != sizeof("volcanol"); i++)
            cout<<cStrArray[i]<<endl;
    
        char *pCh = "volcanol";
        for(;*pCh != '';pCh++)
            cout<<*pCh<<endl;
    
        cout<<endl;
    
        char *pCh1 = "volcanol";
        for(;*pCh1 != '';++pCh1)
            cout<<*pCh1<<endl;
    
        return 0;
    }

    程序执行的街结果如下所示:

    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    v
    o
    l
    c
    a
    n
    o
    l
    
    v
    o
    l
    c
    a
    n
    o
    l
    
    v
    o
    l
    c
    a
    n
    o
    l

      这里要多说一句,字符串字面值的数据类型为 const char * 类型,我们定义的数组和指针一般都不会定义为const的, 如果确定不能改变数组的内容,则可以将

    数组定义为const类型的,这样就可以避免不修改数组的内容。 利用指针和字符串字面值进行操作的时候,需要注意在指针没有改变指向的时候,不能通过指针来修改

    字符串字面值的值。

    int main()
    {
        char *pCh ="volcanol";
        *pCh = 'A';
        cout<<*pCh<<endl;
        return 0;
    }

    这段代码编译不会出错,但是运行的时候会出现段错误, 执行情况如下所示:

    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    段错误

    就是通常说的segment error。

    3、利用字符串本身访问

      字符串本身具有一个特殊的特性,字符串字面值本身就具有字符数组名的作用。如下所示:

    int main()
    {
        for(size_t i = 0; i != sizeof("volcanol"); i++)
            cout<<("volcanol"[i])<<endl;
    
        return 0;
    }

    和下面的例子:

    int main()
    {
        //for(size_t i = 0; i != sizeof("volcanol"); i++)
           //cout<<("volcanol"[i])<<endl;
    
        for(size_t i=0; i!=sizeof("volcanol");i++)
            cout<<"volcanol"[i]<<endl;
    
        return 0;
    }

      这个地方的实例要注意字符串字面值的和下标操作符的使用。两个程序的执行结果都如下所示:

    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    v
    o
    l
    c
    a
    n
    o
    l

    4、字符串中的转义字符

      在字符串字面值中需要注意转义字符的组成,这一点需要特别注意。如下所示:

    int main()
    {
        cout<<"volcnaol	hi,nice to meet you"<<endl;
        printf("volcanox	hi,nice to meet you
    ");
    
        return 0;
    }

    程序执行的情况如下:

    [root@localhost cpp_src]# vim test.cpp 
    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    volcnaol        hi,nice to meet you
    volcanox        hi,nice to meet you

    今天发现编译器的一个特殊情况:当我们同时连续输出 的时候,会出现“淹没”的情形。

    int main()
    {
        cout<<"volcnaol	hi,nice to meet you"<<endl;
        printf("volcanol	hi,nice to meet you
    ");
    
        return 0;
    }

    程序执行的结果如下所示:

    [root@localhost cpp_src]# g++ test.cpp 
    [root@localhost cpp_src]# ./a.out 
    volcnaolhi,nice to meet you
    volcanolhi,nice to meet you

    可以发现这个地方执行的结果与我们预期不一样。就是我说的出现了“淹没”的情形 和 的效果全淹没啦。

    5、 cstring头文件支持

      C语言中提供了很多标注库函数支持字符串的操作,通过包含头文件<string.h>的实现引进库, 而在C++中通过头文件<cstring>提供支持,提供的函数有:

      strlen   字符串长度,不包括最后的空字符null;  

      strcmp(str1,str2)    按照字典序比较str1、str2, 若str1> str2则返回正数, 若str1== str2则返回0, 如果str1<str2则返回负数; 注意这个函数区分

                    字符的大小写

      strcat(str1, str2)     将字符串str2连接到str1之后, 这个函数需要保证 sizeof(str1) >= strlen(str1) + strlen(str2); 函数返回str1。

      strcpy(str1,str2)    将字符串str2复制到str1中,注意要保证 sizeof(str1) >= str2 ; 函数返回str1;

      strncat(str1,str2,n)   将字符串str2的前n个字符,连接到字符串str1之后,函数返回str1;

        strncpy(str1,str2,n)  将字符串str2的前n个字符,复制到字符串str中,函数返回str1;

      cstring提供的支持要注意留足够的空间来进行操作,否则就会出现异常, 同时要注意字符串最后的null字符的特殊性。

    二、动态数组

      数组在定义的时候需要指定数组的大小,而且指定数组大小必须是一个整型字面值或者cosnt修饰的整型变量或者可以在编译时计算出结果的整型表达式。

    C++提供了另外的一种机制-----动态数组, 在定义的时候可以通过变量来指定数组的大小。

      在程序运行的时候系统会为程序维护一块特殊的内存区域,这块内存区域在程序运行的时候用于程序来自由的使用,但是需要程序自己来管理,这块区域

    就是堆区域(heap)。

     1、定义动态数组

      在C++中通过new操作符来定义动态数组。例如定义一个int型的动态数组,如下所示:

      int  array_size;
    
      cout<<"please input the size of the array you want alloc:";
    
      cin>>array_size;  
    
      int *pInt = new int[array_size];

      这里我们可以看到我们可以动态的定义数组,可以根据实际需要来分配数组的大小。操作符 new 返回指向数组第一个元素的地址,这里这个地址用来初始化int *

    的指针pInt。这样定义后,就可以利用指针来访问新分配的数组了,如下所示:

    int main()
    {
        int array_size;
        cout<<"please input the size of array you want alloc:";
        cin>>array_size;
    
        int *pInt = new int[array_size];
    
        for(size_t i = 0; i != array_size; ++i)
            *(pInt + i ) = i;
    
        for(size_t i = 0; i != array_size; i++)
            cout<<*(pInt + i)<<endl;
    
    
        return 0;
    }

    程序执行的结果如下:

    [root@localhost cpp_src]# ./a.out 
    please input the size of array you want alloc:5
    0
    1
    2
    3
    4

    2、释放动态分配的内存

      为了定义动态数组需从堆里面分配的内存,这些内存需要在不使用的时候进行释放,否则申请多了就会将系统的内存耗尽,造成内存泄露。 

      C++用 delete操作符来释放动态分配的内存。如下所示:

    Exp:

     int array_size;
        cout<<"please input the size of array you want alloc:";
        cin>>array_size;
    
        int *pInt = new int[array_size];
        delete [] pInt;

      这里就将申请的内存空间释放完毕,相当于C语言标准库中的free()函数.

  • 相关阅读:
    IIS7中的几种身份鉴别方式(一)Basic身份验证
    IIS7中的几种身份鉴别方式(二)集成身份验证
    java集合
    SharePoint 2010中welcome page的设置细节
    SharePoint中使用Linq出现未将对象引用到实例化的解决方法
    SharePoint 2010中关于An error was encountered while retrieving the user profile的处理方式记录
    The Need for an Architectural Body of Knowledge
    The Softer Side of the Architect
    Event Receivers 学习小结
    使用SmtpClient发送带图片的邮件的代码实现
  • 原文地址:https://www.cnblogs.com/volcanol/p/4008333.html
Copyright © 2011-2022 走看看