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()函数.

  • 相关阅读:
    [leetcode] Best Time to Buy and Sell Stock II
    [leetcode] Best Time to Buy and Sell Stock
    [leetcode] Binary Tree Maximum Path Sum
    [leetcode] Triangle
    [leetcode] Populating Next Right Pointers in Each Node II
    [leetcode] Pascal's Triangle II
    [leetcode] Pascal's Triangle
    第三周周总结
    基础DP
    第二周周总结
  • 原文地址:https://www.cnblogs.com/volcanol/p/4008333.html
Copyright © 2011-2022 走看看