C语言从零开始——memory初识(2)

####   代码段   ####

/*
        代码段:存放函数代码,字符串常量。只读,不可更改
*/

#include <stdio.h>
int main(void)
{
        char buf[] = "123456"; //栈变量
        char buf1[] = "123456";

        printf("buf address = %p \n",buf);
        printf("buf1 address = %p \n",buf1);

        char *p1 = "123456"; //指向代码段变量
        char *p2 = "123456";
        printf("p1 address = %p \n",p1);
        printf("p2 address = %p \n",p2);
/*
buf address = 0x7fffc87b58b0 
buf1 address = 0x7fffc87b58a0 
p1 address = 0x400687 
p2 address = 0x400687
p1 和 p2 都是指向了同一个字符串(存放再代码段的字符串),所以p1和p2的大小一样
而buf 和buf1是在栈内开辟的新空间存放两个字符串(栈内存上),所以buf和buf1不相等
*/
        return 0;
}
####   其他内存段   ####
/*
        4,只读段:const修饰的变量,生命周期伴随整个程序,作用域:代码块作用域
        5,文件映射区:打开的文件(动态文件)存放的地方
        6,OS内核映射区:每个进程都必须需要一个内核映射区
        7,data段(数据段):非0的全局变量和static修饰的非0的局部变量,生命周期伴随整个程序,作用域:创建后(全局)一直可以使用,代码块(局部)作用域
        static修饰的全部变量,改变的是连接属性,变成了内链接,只能本文件使用。
        函数默认是外链接,整个工程(很多.c文件),static修饰的函数,可以改变函数
的链接属性,使之成为内链接,使函数仅能再本文件使用
        注意:
        C程序:编写,编译(编译和链接两步),单纯执行编译,就已经是二进制文件,但是没有顺序,链接的目的就是让这些二进制文件有序
        8,.bss段:不初始化的全剧变量和不初始化的static修饰的局部变量,或者初始化为0的全剧变量,static修饰的局部变量
*/
/*
        有操作系统下的C语言程序:
        你自己写的C程序,是不能运行的,依赖于操作系统给你提供的引导代码,将程序>加载进虚拟内存。引导代码不是自己写的,是操作系统帮忙实现的。在程序位进行编译之前
,.data段就已经完成了赋值,而且.bss段进行清0
        无操作系统下的C程序(典型例子就是单片机)
        写好的C程序,必须放到固定的地址才可以执行。这些固定的地址,由手册提供。
        注意:
        这块有个概念:地址无关码和地址有关码。一般来说操作系统提供引导代码的都是
地址无关码,而无操作系统下的程序,大多数是地址有关码(仅仅是大多数)
*/

#include <stdio.h>
int func_static(void)
{
        static int a = 1;
        a++;
        return a;
}

char *func_string(void) //代码段
{
        char *p = NULL;
        p = "123";
        return p;
}

extern int g_a;
//extern int g_b; 
extern func_quanju();
//extern int g_c = 22;//warning: ‘g_c’ initialized and declared ‘extern’
                //注意:声明时不能有初始化语句,因为会把次认作为定义。注意定义和
声明的区别
int g_d = 0;//定义一个全剧变量,如果没有初始化,则默认是0(不初始化的全局变量再.bss段,而.bss段内数据全被写0);注意:当有局部定义时,局部定义优先(强龙不压地头蛇
)
void func_g(void)
{
        g_d = 33;
}
int main()
{
#if 1
        func_g();//调用子函数,子函数里使用全剧变量
        printf("g_d = %d \n",g_d);
        static int g_d = 44;//局部变量,并且存储位置发生了变化。存在了数据段
        printf("g_d = %d \n",g_d);
#endif

//      printf("g_c = %d \n",g_c);

        printf("g_b = %d \n",func_quanju());
        printf("g_a = %d \n",g_a);
        printf("p = %s \n",func_string());
#if 0 
        int num = 3, ret = 0;
        while (num--)
        {
                ret += func_static();
                //2 5 9
                //2:ret = ret +func_static() = 0+2
                //5:ret = ret +func_static() = 2+3
                //9:ret = ret +func_static() = 5+4
                //注意:static修饰的局部变量只初始化一次,多次调用维持上次的结>果不变;也就是说,子函数func_static()函数中a = 1;只被初始化了一次,第二次执行子
函数时,a初始值已经时2,执行a++ 返回3
                printf("ret = %d \n",ret);
        }
#endif
        return 0;
}
创建第二个.c文件

int g_a = 24;
int g_b = 24;
int g_c = 24;
//static int g_a = 24;//error: ld returned 1 exit status 错误:链接错误;因为static修饰后改变链接属性,改为内链接,不能通过声明被其他.c文件调用;

int func_quanju()
{

        g_b = 12;
        return g_b;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值