关于C++中char型数组、指针及strcpy函数的细节观察

1.声明字符数组时,[]中的数应为数组中字符个数,包括'/0'

   如 char p[5] = "dddd";

   则实际为:'d' 'd' 'd' 'd' '/0'.

   若 char p[5] = "ddddd";

   则编译出错,提示越界.

2.(1)初始化字符数组时,会自动补充'/0'

   如  char p[5] = "dd";

   则实际为:'d' 'd' '/0' '/0' '/0'

   再如  char p[3] = "";

   则实际为:'/0' '/0' '/0'

   (2)若没有只是声明字符数组,没初始化并不会自动补'/0'

   如  char p[3];

   则实际字符数组内容并不可知,因为实际上p也是个指针,现在并不知道它的指向

   (3)同理,声明字符指针并不初始化时,也不知道指针的指向

   如  char *p;

   (4)声明并初始化指针,由于"内存对齐"(由编译器实现),对32位机

    则会补齐4位,自动补'/0'

    如 char *p = "a";

    则实际为:p[0]='a',p[1]='/0',p[2]='/0',p[3]='/0'.

    若 char *p ="";

    则实际为:p[0]='/0',p[1]='/0',p[2]='/0',p[3]='/0'.

  

3.strlen(const char* p)函数返回的是字符数组中字符个数,不包括'/0'

   如 char p[5] = "dddd";

       char p2[3] = "";

       int i = strlen(p);

       int j = strlen(p2);

   此时 i = 4 , j = 0

4.关于strcpy函数

   函数的实现为:

   char *strcpy(char *strDestination, const char *strSource)

 {

    assert(strDestination && strSource);

    char *strD=strDestination;

    while ((*strDestination++=*strSource++)!='/0')

    NULL;

    return strD;

 }

   这个函数并不会检查是否下标越界,所以使用时要注意:

   ->给函数传的第一个参数必须是字符数组或者是已经指向字符数组的字符指针.   

   ->并且第一个参数的数组大小应该大于或等于第二个参数.

   (1)先讨论正确的传参,如下代码:

   char a[] = "123";char b[] = "123456";// 也可以是char *a = "123";char *b = "123456";

   char p1[4];char p2[9];    //[]中的数一定要大于等于第二个参数字符数组大小

   char *p3;p3 = p1;

   char *p4;p4 = p2;

   strcpy(p1,a);strcpy(p2,b);

   strcpy(p3,a);strcpy(p4,b);

   以上代码中实现复制是正确的.

   (2)错误代码一:

   char a[] = "123";   char *p1;  

   char *p2 = "";

   strcpy(p1,a);  //--------1  

   strcpy(p2,b);  //--------2

   以上代码编译可以通过,但运行时1,2两行都会出现错误并被退出.

   原因是p1并没有初始化,指向并不确定,将p1所指内容用"123"覆盖会导致错误,

   覆盖p2也有可能修改原先指向的并不确定的值而导致错误

 

 这里的结果和编译器非常有关系!

   (3)代码二:

   char a[] = "123456";

   char p[2];

   strcpy(p,a);

   printf("%s/n%s",p,a)

   编译不会出错,运行结果为

   123456

   3456 

   发现到,p的确得到了想要的值,但是a竟然被修改了

   原因是,复制时具体的操作如下:

   复制前的内存结构为p在前,a在后  :'/0' '/0'  '1' '2'  '3' '4' '5' '6' '/0'

   p指向第一个'/0',a指向'1'.虽然声明为p[2],但由于"内存对齐",编译器自动补充两字符并填'/0'

   复制后的内存结构仍为p在前,a在后:'1'  '2'  '3'  '4'  '5' '6' '/0' '6' '/0'

   p和a所指的内存地址并不会变,所以此时p指向的是'1',a指向的是'3'

   因此就出现了上述的现象

 这个是在codeblocks里面测试的,如果定义p[3]的话,结果a会是456,也就是说,在这里p不存在一个内存对齐的概念

 而其他的编译器可就不一定是这样了,可能会在进去之前给p分配四个字节的空间,那样的话,在输出a的时候应该就是 56 了!

原文地址:https://www.cnblogs.com/pmars/p/2724000.html