字符数组

【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 }

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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值