zoukankan      html  css  js  c++  java
  • 由字符串常量引发的思考

      晚上帮WL做些阿里的面试题,遇到一个关于字符串常量和字符串变量的问题,感觉有些不确定,就回来研究一下。

      首先看个例子吧:char *p="hello";p[2]='j';   这里有问题吗?既然这样问了,肯定有噻。

      这里普及下我之前没注意的事实:char *p="hello"得到的是字符串常量;char p[]="hello"得到的是字符串变量。事实上,字符串常量都放在一个称之为文字常量区的神奇地方。

      我们看个代码吧:

    #include <iostream>
    using namespace std;
    
    int j=3;
    char *a="lihuan";
    char *b="lihuan";
    char e[]="lihuan";
    char f[]="lihuan";
    
    int main(){
        cout<<(void*)a<<endl<<(void*)b<<endl;
        cout<<&j<<endl<<&a<<endl<<&b<<endl;
        cout<<(void*)e<<endl<<(void*)f<<endl;
        return 0;
    }

    猜猜结果是什么?

    我们可以发现,a和b指向同一个地方,而e和f指向的地方不一样,且和a、b的地方也不一样。而j、e、f的地址是挨着的。其实,a和b指向的就是文字常量区,而j、e、f都在静态存储区(因为他们都是全局变量)。

    这里普及一个知识:

    一个程序的运行起来后,其在内存中有5个区域
    1. 程序代码区
    这个很简单,代码要执行,肯定要加载进内存, 我们不必关心。

    2. 文字常量区
    一般我们这样定义一个字符串时,其是在文字常量区的:
    char* s1 = "hello, world";
    char* s2 = "hello, world";

    这里, s1和s2指向的是同一个字符串

    文字常量区存储的都是常量,常量一经初始化,就不允许被修改

    3. 静态存储区
    全局变量,静态变量会放在这个区域,事实上,全局变量也是静态的。

    4. 栈
    局部变量就是在栈里的。另外,函数调用时的参数也是在栈里的,这个现在不必关心

    5. 堆
    malloc或new出来的内存就是在堆里的,需要程序员自己管理清除。

    顺便聊一下指针常量与常量指针的区别吧:

    1.常量指针:

    在C/C++中,常量指针是这样声明的:

    1)const int *p;

    2)int const *p;

    常量指针的使用要注意,指针指向的对象不能通过这个指针来修改,可是仍然可以通过原来的声明修改,也就是说常量指针可以被赋值为变量的地址,之所以叫做常量指针,是限制了通过这个指针修改变量的值。例如:

    int a = 5;

    const int *c = &a; // 这是合法的,非法的是对c的使用

    *c = 6; // 非法,但可以这样修改c指向的对象的值:a = 6;

    2.指针常量:

    在C/C++中,指针常量这样声明:

    int a;

    int *const b = &a; //const放在指针声明操作符的右侧

    因为指针常量是一个常量,在声明的时候一定要给它赋初始值。一旦赋值,以后这个常量再也不能指向别的地址。

    虽然指针常量的值不能变,可是它指向的对象是可变的,因为我们并没有限制它指向的对象是常量。

    char *a = "abcde1234";

    char *const c = &a;

      下面的操作是可以的。

      a[0] = 'x'; // 我们并没有限制a为常量指针(指向常量的指针)

    3.指向常量的指针常量:

    在C/C++中,这么声明:

      const int a = 25;

    const int * const b = &a;

    看,指针声明操作符左边有一个const,说明声明的是一个指向常量的指针。再看,指针声明操作符右边有一个const,说明声明的是一个指针常量。前后都锁死了,那么指向的对象不能变,指针常量本身也不能变。

    可以参考下:http://www.cnblogs.com/witty/archive/2012/04/06/2435311.html

  • 相关阅读:
    从零教你在Linux环境下(ubuntu)如何编译hadoop2.4
    springboot集成redis
    缓存穿透
    关于HashMap,HashTable,HashSet浅析
    关于多线程的几点总结
    java设计模式--工厂模式
    java设计模式--单例模式
    初识Linux(五)--VI/VIM编辑器
    初识Linux(四)--系统常用命令
    初识Linux(三)--文件系统基本结构
  • 原文地址:https://www.cnblogs.com/jiu0821/p/4388941.html
Copyright © 2011-2022 走看看