zoukankan      html  css  js  c++  java
  • 浅谈C语言 extern 指针与数组

    /*
    * d.c
    *
    * Created on: Nov 15, 2011
    * Author: root
    */
    #include "apue.h"
    int a[] = {3,2};
    void hello()
    {
    printf("d.c %d",a);
    }
    /*
    ============================================================================
    Name : hello.c
    Author :
    Version :
    Copyright : Your copyright notice
    Description : Hello World in C, Ansi-style
    ============================================================================
    */

    #include "apue.h"
    extern void hello();
    extern int *a;

    int main(void)
    {
    hello();
    printf("\n : %d",a);
    return EXIT_SUCCESS;
    }

    上面的代码的输出为 

    d.c 134520856  
    : 3

    第一行代码是第一个文件d.c输出了int a[];a的内容

    第二行代码是第二个文件hello.c输出了extern int *a;指针a的内容

    gcc编译的时候,在链接阶段了,hello.o有extern a符号,在d.o中找到,所以extern a 和d.o的a是同一个符号(我认为称他们“指向相同”有歧义)

    也可以用图像表示

    。数组第一项在内存地址134520856处。

    第一个文件d.c将a当成数组来处理,可以按照想象的进行输出,但是

    但是第二个文件是把符号a当成指针来操作的(因为 extern int *a), 指针所在的地址是134520856,但是指针的值是3(理解吗?)。

    如果将hello.c改成下面这样

    #include "apue.h"
    extern void hello();
    extern int *a;

    int main(void)
    {
    hello();
    printf("\n : %d",a[1]); // 这里被修改了
    return EXIT_SUCCESS;
    }


    在main函数中,按照编译器的规矩,a[1]可以被我们这样认为 *(a+1);

    因为a等于3,a+1等于4,*(a+1)的意思就是取内存地址为4的字节内容,我不知道地址为4的那个字节里面是什么东西。但是起码不是我们想要的。

     转载请注明出处:http://www.cnblogs.com/stonehat/archive/2011/11/15/2250091.html 

    二、再看下面的代码。

    // file : d.c
    #include "apue.h"
    int *a;
    void hello()
    {
    a =(int *) malloc(2);
    a[0]=3;
    a[1]=2;
    printf("d.c %d",a);
    }
    // file : hello.c

    #include "apue.h"
    extern void hello();
    extern int *a;

    int main(void)
    {
    hello();
    printf("\n : %d",a);
    return EXIT_SUCCESS;
    }

    输出结果:

    d.c 161968136
    : 161968136

    我说了实际上 只要是extern a就表示这两个a符号,实际上是同一个符号a,(你可以将两个文件的函数输出&a,就会发现他们的地址是一样的)。

    这种情况下的内存分配是这样的。

    如果main函数改成这样的,就是输出a[1]的值,

    int main(void)
    {
    hello();
    printf("\n : %d",a[1]);
    return EXIT_SUCCESS;
    }

    按照规矩,输出*(a+1),a等于161968136, 加1,就等于161968140(懂?),就会输出2.

    三、再看一种情况。

    // d.c
    #include "apue.h"
    int *a;
    void hello()
    {
    a =(int *) malloc(2);
    a[0]=3;
    a[1]=2;
    printf("d.c value:%d\n",a);
    printf("d.c address:%d\n",&a);
    }



    // hello.c

    extern void hello();
    extern int a[];

    int main(void)
    {
    hello();
    printf("hello.c value:%d\n",a);

    printf("hello.c address:%d\n",&a);

    printf("hello.c a[1]",a[1]);
    return EXIT_SUCCESS;
    }



    输出结果为:

    d.c value:160223240
    d.c address:134520864
    hello.c value:134520864
    hello.c address:134520864
    hello.c a[1]

    内存分布图为:

    在hello.c中,a被当成int a[];

    a的值为160223240, *(a+1),就能够访问到2.

     转载请注明出处:http://www.cnblogs.com/stonehat/archive/2011/11/15/2250091.html 





  • 相关阅读:
    儿童教育:孩子要买东西,怎么办?
    儿童教育:是否应该让他写好字
    Python on VS Code
    AI
    Java: Replace a string from multiple replaced strings to multiple substitutes
    Visual Studio 2015 Test Explorer does not show anything
    SpringIOC容器创建过程
    spring的组件工厂后置处理器——BeanFactoryPostProcessor
    spring与quartz的整合
    启动tomcat报错One or more listeners failed to start,却找不到任何错误日志的临时解决方案
  • 原文地址:https://www.cnblogs.com/stonehat/p/2250091.html
Copyright © 2011-2022 走看看