• 字符数组


    【1】 "abcdef"一定是常量吗?

    依情况而定。

    (1)不是常量的情况。当“abcdef”作为字符数组初始值时就不是常量。

    示例代码如下:

    char str[] = "abcdef";
    //或者
    char str[] ={"abcdef"};

    以字符串形式出现的,编译器都会为该字符串自动添加一个0作为结束符,如在代码中写"abcdef",那么编译器帮你存储的是"abcdef\0"。

    所以上面语句最终的结果是:

    char str = {'a', 'b', 'c', 'd', 'e', 'f','\0'};

    可以查看一下。如图所示:

    扩展:如果char str[] = "abcdef";是在函数内部写的话,那么这里 的"abcdef\0"因为不是常量,所以应该被放在栈上。

    (2)是常量的情况。当把字符串赋值于一个字符指针变量时。

    示例代码如下:

    char *ptr = "abcdef";

    因为定义的是一个普通指针,并没有定义空间来存放"abcdef",所以编译器得帮我们找地方来放"abcdef"。

    显然,把这里的"abcdef"当成常量并把它放到程序的常量区是编译器最合适的选择。

    所以,尽管ptr的类型不是const char *,并且ptr[0] = 'x';也能编译通过,但是执行ptr[0] = 'x';就会发生运行时异常。

    因为这个语句试图去修改程序常量区中的东西。

    记得哪本书中曾经说过char *ptr = "abcdef";这种写法原来在c++标准中是不允许的,但是因为这种写法在c中实在是太多了,为了兼容c,不允许也得允许。

    虽然允许,但是建议的写法应该是const char* ptr = "abcdef";

    这样如果后面写ptr[0] = 'x'的话编译器就不会让它编译通过,也就避免了上面说的运行时异常。

    再扩展一下,如果char* ptr = "abcdef";写在函数体内,那么虽然这里的"abcdef\0"被放在常量区中,但是ptr本身只是一个普通的指针变量,

    所以ptr是被放在栈上的,只不过是它所指向的东西被放在常量区罢了。

    【2】字符串常量的类型怎么分析?

    可以理解为相应字符常量数组的类型。如"abcdef"的类型就可以看成是const char[7]。

    【3】数组参数如何理解?

    对于函数参数列表中的以数组类型书写的形式参数,编译器把其解释为普通的指针类型。

    如对于函数

    void func(char sa[100], int ia[20], char *p)

    则sa的类型为char*,ia的类型为int*,p的类型为char*。

    【4】关于以上理论分析的相关示例代码如下:

     1 #include<iostream>
     2 #include<string.h>
     3 using  namespace std;
     4 char  st[]={'a','b','c','d','e','f'};
     5 char  *pt="abcdef";
     6 
     7 char  s[10]={'a','b','c','d','e','f'};
     8 char  ss[10];
     9 
    10 char  ch1[]={"abcdef"};
    11 char  ch2[]="abcdef";
    12 
    13 char  p[10]={"abcdef"};
    14 char  pr[10]="abcdef";
    15 
    16 char st3[]="\0";
    17 char *st4="\0";
    18 void  main()
    19 {
    20     cout<<"sizeof(st)="<<sizeof(st)<<endl;     // 6
    21     cout<<"strlen(st)="<<strlen(st)<<endl;     // 6
    22     cout<<"sizeof(pt)="<<sizeof(pt)<<endl;    // 4
    23     cout<<"strlen(pt)="<<strlen(pt)<<endl;    // 6
    24     
    25     char str[]={'a','b','c','d','e','f'};
    26     char *ptr="abcdef";
    27     cout<<"sizeof(str)="<<sizeof(str)<<endl;            // 6
    28     cout<<"strlen(str)="<<strlen(str)<<endl;            // 11    //不确定
    29     cout<<"sizeof(ptr)="<<sizeof(ptr)<<endl;           // 4
    30     cout<<"strlen(ptr)="<<strlen(ptr)<<endl;           // 6
    31     
    32     
    33     cout<<"sizeof(s)="<<sizeof(s)<<endl;          // 10
    34     cout<<"strlen(s)="<<strlen(s)<<endl;          // 6
    35     cout<<"sizeof(ss)="<<sizeof(ss)<<endl;       // 10
    36     cout<<"strlen(ss)="<<strlen(ss)<<endl;       // 0
    37     
    38        
    39     char  sr[10]={'a','b','c','d','e','f'};
    40     char  ssr[10];
    41     cout<<"sizeof(sr)="<<sizeof(sr)<<endl;           // 10
    42     cout<<"strlen(sr)="<<strlen(sr)<<endl;            // 6
    43     cout<<"sizeof(ssr)="<<sizeof(ssr)<<endl;         // 10
    44     cout<<"strlen(ssr)="<<strlen(ssr)<<endl;          // 18  //不确定
    45     
    46     
    47     cout<<"sizeof(ch1)="<<sizeof(ch1)<<endl;           // 7
    48     cout<<"strlen(ch1)="<<strlen(ch1)<<endl;           // 6
    49     cout<<"sizeof(ch2)="<<sizeof(ch2)<<endl;           // 7
    50     cout<<"strlen(ch2)="<<strlen(ch2)<<endl;           // 6
    51     
    52     char chr1[]={"abcdef"};
    53     char chr2[]="abcdef";
    54     cout<<"sizeof(chr1)="<<sizeof(chr1)<<endl;           // 7
    55     cout<<"strlen(chr1)="<<strlen(chr1)<<endl;           // 6
    56     cout<<"sizeof(chr2)="<<sizeof(chr2)<<endl;           // 7
    57     cout<<"strlen(chr2)="<<strlen(chr2)<<endl;           // 6
    58     
    59     cout<<"sizeof(p)="<<sizeof(p)<<endl;                   // 10
    60     cout<<"strlen(p)="<<strlen(p)<<endl;                   // 6
    61     cout<<"sizeof(pr)="<<sizeof(pr)<<endl;                // 10
    62     cout<<"strlen(pr)="<<strlen(pr)<<endl;                 // 6
    63     
    64     char  pp[10]={"abcdef"};
    65     char  ppr[10]="abcdef";
    66     
    67     cout<<"sizeof(pp)="<<sizeof(pp)<<endl;            // 10
    68     cout<<"strlen(pp)="<<strlen(pp)<<endl;            // 6
    69     cout<<"sizeof(ppr)="<<sizeof(ppr)<<endl;          // 10
    70     cout<<"strlen(ppr)="<<strlen(ppr)<<endl;          // 6
    71     
    72     
    73     cout<<"sizeof(st3)="<<sizeof(st3)<<endl;       // 2
    74     cout<<"strlen(st3)="<<strlen(st3)<<endl;       // 0
    75     cout<<"sizeof(st4)="<<sizeof(st4)<<endl;       // 4
    76     cout<<"strlen(st4)="<<strlen(st4)<<endl;       // 0
    77     
    78     char s3[]="\0";
    79     char *s4="\0";
    80     cout<<"sizeof(s3)="<<sizeof(s3)<<endl;       // 2
    81     cout<<"strlen(s3)="<<strlen(s3)<<endl;       // 0
    82     cout<<"sizeof(s4)="<<sizeof(s4)<<endl;       // 4
    83     cout<<"strlen(s4)="<<strlen(s4)<<endl;       // 0
    84 }

    希望仔细分析,有所收获。

    作者:kaizen
    声明:本文版权归作者和博客园共有,欢迎转载。但未经作者同意必须保留此声明,且在文章明显位置给出本文链接,否则保留追究法律责任的权利。
    签名:顺序 选择 循环
  • 相关阅读:
    [uboot] (番外篇)uboot relocation介绍(转)
    [uboot] (番外篇)global_data介绍(转)
    [uboot] (第三章)uboot流程——uboot-spl代码流程 后续2018版本分析
    AddressUtils
    ruoyi HttpUtils
    ruoyi IpUtils
    ruoyi StringUtils
    JSONObject
    jackson解析处理JSON
    spring boot pom demo
  • 原文地址:https://www.cnblogs.com/Braveliu/p/2841564.html
Copyright © 2020-2023  润新知