zoukankan      html  css  js  c++  java
  • Character Array and Character Pointer

    最近复习数据结构实验时,碰到这么一行代码,看的有点不爽。

    typedef char** HuffmanCode;
    

    借此梳理下数组和指针。

    int* p; //指针变量p中存的地址代表的内存单元中的数据是整型
    

    在32位平台下,由于p存的是地址,故p的值是32位。
    不论p指向什么类型的数据,指针变量p本身都是整型。

    c中没有string类型,所以一般用字符数组表示字符串。

    char str[15] = "Hello World";
    

    c规定数组名表示数组在内存中的首地址,就是str = &str[0],我们一般输出字符串时printf("%s",str);,首地址就可以输出整个字符串。

    在c中可以这么干:

     char *s;
     s = "Hello";
    

    一个字符串赋值给一个指针变量??

    事实上,c的编译器会给字符串常量分配内存,假设"Hello"的地址是0x0000000000404000 0x0000000000404001 0x0000000000404002 0x0000000000404003 0x0000000000404004 0x0000000000404005,(我是64位环境)
    其实是s = "Hello" = 0x0000000000404000,c编译器把这个串看作首地址。

    做个测试:

    printf("%s
    ",s);
    printf("%s
    ",0x0000000000404000);
    这两行的效果是一样的。
    
    char str[10];
    char* s;
    

    str表示首地址,s也保存首地址,所以可以这样:

    s = str;
    但是不可以 str = s;
    

    因为数组名是一个常量,不能被赋值。
    事实上,char str[10]编译器会分配10个内存单元,而char* s只是定义了一个指针变量,32位环境下只分配4个字节,用来保存字符串首地址。

    不信测试下:

    sizeof(str) = 10;
    sizeof(s) = 4;   //分配四个字节来保存地址
    

    所以数组名和指针变量本质上是不同的。

    接下来我们看看char**与char* a[]
    对于char* a[],a实质上还是一个数组,这个数组保存的元素是char*类型的,char*也就是存着地址的变量。

    所以可以这样:

    char* a[] = {"me","you","him"};
    

    这时在32位环境下sizeof(a) = 12,因为a中的3个元素都是char*指针,而指针变量占4个字节。
    可以打印出来看看:

    printf("%p %p %p
    ",a[0],a[1],a[2]);
    printf("%p %p %p
    ",&a[0],&a[1],&a[2]);
    

    在这里插入图片描述
    数组中3个元素保存了3个地址,也就是3个字符串的首地址。

    对于char** s
    二级指针变量s保存一级指针char*的地址,我们可以:

    s = a;
    

    数组名a=&a[0]=62FE30,而这个地址中(即a[0])保存的是404000这个地址,也就是字符串"me"的首地址,即:

    *s = 404000 = "me";
    

    易错点1:

    char** s = "Hello";
    

    这是错的,因为s是char** ,而"Hello"是char*
    虽然都是地址,但是"Hello"表示的地址中内容是H,char型;
    s存的地址中的内容(*s)是char*型,指针类型。

    易错点2:

    char** s;
    *s = "Hello";
    

    这样编译不会错,但是运行时printf("%s",*s);就会崩溃。

    假设s=0x1000,在0x1000内存单元中存的是"Hello"的地址0x2000,即*s = 0x2000,这样执行时先找到0x1000,然后是0x2000,没有问题。

    char** s;,s存的是一个随机的地址,也就是野指针,*s就可能会崩溃。

    所以要先分配一个地址:

    char** s;
    s = (char**) malloc(sizeof(char**));
    *s = "Hello";
    

    这样s就有了可用的地址。

    参考:
    https://blog.csdn.net/liusicheng2008_liu/article/details/80412586

  • 相关阅读:
    IDEA tomcat热部署方法及乱码问题解决
    访问WEB-INF下JSP资源的几种方式(转)
    SpringMVC 静态资源处理
    SpringMVC中的拦截器
    SpringMVC中的异常处理
    SpringMVC实现文件上传
    IDEA 热部署
    响应数据和结果视图
    SpringMVC中的常用注解
    js获取当前根目录的方法
  • 原文地址:https://www.cnblogs.com/EIMadrigal/p/12130794.html
Copyright © 2011-2022 走看看