• 关于指针


    首先,要写这篇文章的原因非常之惭愧,在看do_fork实现的源码中,有如下(部分代码省略):

    do_fork:

    struct task_struct *p;

    p = alloc_task_struct();

    *p = *current;

    从代码上看很清晰,声明指针p,分配两个物理页内存,然后把当前进程的task_struct内容复制给p。本来都已经跳过了,但突然想到从来都是赋值地址,或者是strcpy的方式,还没有这样写过,然后打开编译器试了一下,结果就牵扯出了一堆问题,不过现在搞清楚了。总结如下:

    版本1:

    int main()
    {
        char *s = "abcdefg";
        char *a = NULL;
        a = s;
        printf("%s
    ", a);
        return 0;
    }

    平时常用该方法,输出结果:

    abcdefg

    版本2:

    int main()
    {
        char *s = "abcdefg";
        char *a = malloc(sizeof(char) * 8);
        strcpy(a, s);
        printf("%s
    ", a);
        return 0;
    }

    平时常用该方法,输出结果:

    abcdefg。

    版本2与版本1不同的地方在于,在2中为a动态分配了8个字节内存(包含),然后strcpy将s指向的内存单元中的字符串拷贝到a指向的内存单元,如果不动态分配内存,则a指向非法地址,strcpy导致程序崩溃。

    版本3:

    主要是对某些理论进行了验证。首先一个需要明确的概念为,任何一种类型的指针变量只与系统架构有关,即32位操作系统为4字节,64位操作系统为8字节,表明可以寻址的大小(当然这样的说法不全对,还与编译器等因素相关,但总之想表明与char *p, int *p的类型无关,这个概念差点都忘了)。先贴代码:

    int main()
    {
        char *s = "abcdefg";;
        printf("%p
    ", &s);
        printf("%p
    ", s);
        return 0;
    }

    输出结果:

    %p显示指针地址,与%#x类似。可以看到指针s所在的内存单元,地址为0x0060ff08,其保存了地址0x00403024(指针的本质)。

    版本4:

    之后我针对上述地址进行了测试。代码如下:

    int main()
    {
        char *s = "abcdefg";;
        printf("%p
    ", &s);
        printf("%p
    ", s);
        printf("%c
    ", *s);
        printf("%s
    ", 0x403024);
        printf("%s
    ", 0x403025);
        printf("%c
    ", *(char *)0x403026);
        return 0;
    }

    输出结果:

    可以看到c语言中的字符串,对于编译器而言保存的为地址,而且是字符串首字母的地址,我们看到的是char *s = "abcdefg",实际上保存的为 char *s = 0x403024 0x403025 ……,而char型的指针,指明了每个元素占用的内存大小为一个字节,即24中保存a,25中保存b,如果为int型指针,每个元素占用大小应该为4个字节。

    图示为:

    而且在printf一个字符串时,字符串默认以结尾,所以在遇到是系统判断字符串结束,所以如果上述代码改为char *s = "abcdefg",则打印结果为abc。

    最后补充一点,对于一个指针变量char *p, &p表示该变量自身的地址,p表示其保存的内容,*p表示将其内容作为一个地址读取其内容。如果其内容为未分配内存的地址,则会导致系统崩溃。

  • 相关阅读:
    第四章 开始Unity Shader学习之旅(3)
    第四章 开始Unity Shader学习之旅(2)
    第四章 开始Unity Shader学习之旅(1)
    堆中的变量、对象的使用
    goto语句 switch语句
    C/C++走过的坑(基础问题篇)
    EOF 与 getchar()
    char与 int 类型转化问题汇总
    运算符优先级记忆口诀及列表(转)
    SQL基础篇---函数及其函数配套使用的关键字
  • 原文地址:https://www.cnblogs.com/scu-cjx/p/7922881.html
Copyright © 2020-2023  润新知