三个关于字符串的考点

来源:互联网 发布:天盾苹果手机数据恢复软件 编辑:程序博客网 时间:2024/06/06 01:41

最近常常遇到字符串相关的考题,于是整理出来了三个常考的知识点。

一、

       C/C++中每个字符串都以’\0’作为结尾,这样就能很方便地找到字符串的最后尾部。但由于这个特点,每个字符串都有一个额外字符的开销(如空字符串其实有一个字符’\0’),如果不加以注意就会造成字符串的越界。另外,在进行字符串复制的时候,忘记复制’\0’也会引起错误。关于这方面的实例参考strcpy函数的实现

二、

       C/C++为了节省内存,把常量字符串放到一个单独的内存区域,即静态内存区。当几个字符指针被相同的常量字符串赋值时,字符指针都指向常量字符串的首地址,也就是说它们指向了相同的内存地址。但是,用常量字符串初始化数组时,会为数组重新分配内存,并把字符串逐一复制到数组的内存中去,也就是说数组的内存地址与常量字符串的内存地址不同。

为帮助理解,来一道例题,判断以下程序的输出结果是什么,并说明原因。

int main() {

    char *str1 = "abc";

    char *str2 = "abc";

    const char str3[] ="abc";

    const char str4[] ="abc";

    const char *str5 ="abc";

    const char *str6 = "abc";

    char *str7 = "abc";

    char *str8 = "abc";

    cout<< ( str1 == str2 )<<" ";

    cout<< ( str3 == str4 )<<" ";

    cout<< ( str5 == str6 )<<" ";

    cout << (str7 == str8 );

}

输出结果为:1 0 1 1

原因:str3,str4是数组,所以它们有各自不同的内存空间;str1,str2,str4,str5,str6,str7为字符指针,所以它们指向了相同的内存地址。

三、

       当函数返回值为非引用或指针类型时,返回值不管是局部变量或全局变量,还是静态变量,返回的是值的一个复制。当函数返回值为引用或指针类型时,不能返回局部变量的指针或引用。因为函数执行完毕后会释放分配给局部变量的存储空间,所以函数返回的对局部变量的引用或指针会指向不确定数据的内存。

这个知识点说的有点不清不楚,来看一道例题:

以下两段程序,判断两段程序的输出结果是否相同,如果不相同请说明原因。

程序一

  char *getm() {

  char p[]=”Hello World”;

  return p;

}

 int main() {

 char *str=NULL;

 str=getm();

 printf(str);

}

程序二

  char *getm() {

  char *p=”Hello World”;

  return p;

}

 int main() {

 char *str=NULL;

 str=getm();

 printf(str);

}

答案是输出不同的结果。程序一输出乱码,程序二输出”Hello World”

程序一用常量字符串”Hello World”初始化数组p,所以编译器为数组p重新分配了内存,并把”Hello World”逐字符复制到了P数组的内存中。但是,getm函数中声明的数组p为局部变量,在执行完getm函数后编译器会释放数组p的内存。getm函数返回的数组p的首地址指向未知数据内存地址。

程序二用常量字符串”Hello World”初始化指针p,所以p指向了存储”Hello World”的静态内存区。执行getm函数不会释放静态内存区的内存,所以getm函数返回的指针指向常量字符串”Hello World”的首地址。