代码变量内存分布、变参函数、inline关键字的用法

一、代码变量的内存分布

查看别人的对代码内存的了解:资料1-变量的探索内存分布的探索详细C语言的5大内存
看了很多帖子,我发现我要买一本《程序员的自我修养》

了解了一些elf的相关命令

readelf xxx.out -S     #产看elf文件的文件

readelf -X .text    #一16进制查看某个段的信息

readeld xxx.out -a   #很详细的查看xxx.out的各种信息的总览

size xxx.out      #查看xxx.out的三个段的信息

引用别人的代码:适合自己见解的代码引用

#include <stdio.h>
const int    g_A       = 10;            //代码段
int            g_B       = 20;            //数据段
static int    g_C       = 30;            //数据段
static int    g_D;                    //BSS段
int            g_E;                    //BSS段
char        *p1;                    //BSS段

void main( )
{
    int            local_A;            //栈
    static int    local_C = 0;        //数据段
    static int    local_D;            //数据段
    
    char        *p3 = "123456";     //123456在代码段,p3在栈上

    p1 = (char *)malloc( 10 );      //堆,分配得来得10字节的区域在堆区
    strcpy( p1, "123456" );         //123456{post.content}放在常量区,编译器可能会将它与p3所指向 的"123456"优化成一块
    printf("\n");
    printf( "代码段,全局初始化变量, 只读const,  g_A,     addr:0x%08x\n", &g_A);
    printf("\n");
    printf( "数据段,全局变量,       初始化      g_B,     addr:0x%08x\n", &g_B);
    printf( "数据段,静态全局变量,   初始化,     g_C,     addr:0x%08x\n", &g_C);
    printf("\n");
    printf( "BSS段, 全局变量,       未初始化    g_E,     addr:0x%08x\n", &g_E, g_E );    
    printf( "BSS段, 静态全局变量,   未初始化,   g_D,     addr:0x%08x\n", &g_D );
    printf( "BSS段, 静态局部变量,   初始化,     local_C, addr:0x%08x\n", &local_C);
    printf( "BSS段, 静态局部变量,   未初始化,   local_D, addr:0x%08x\n", &local_D);
    printf("\n");
    printf( "栈,    局部变量,                   local_A, addr:0x%08x\n", &local_A );
    printf("\n");
    printf( "堆,    malloc分配内存,             p1,      addr:0x%08x\n", p1 );
}

代码和现象得出的结论:
内存变量的总结
在这里插入图片描述

二、变参函数的了解

臭不要脸的我剽窃的帖子:参考的帖子1变参函数的应用探索
va_list、va_start、va_arg、va_end的相关资料:函数的标准解答
示例代码

#include<stdio.h>
#include<string.h>
#include<stdarg.h>    //va_list、va_start、va_arg和va_end的头文件 
/*
va_list类型用于声明一个变量,该变量依次引用各参数,在函数minprintf中,将该变了成为ap,意思是参数
指针,在使用ap前,该宏必须先被调用一次,参数表至少包含一个有名参数,va_start将最后一个有名参数
做为起点,每次调用,va_arg,该参数返回一个参数,并将ap指向下一个参数,va_arg使用一个类型名来决定
返回对象的类型,指针移动的步长,最后必须在函数返回之前调用va_end,以便完成一些必要的清理工作。

#define _INTSIZEOF(n) ((sizeof(n)+sizeof(int)-1)&~(sizeof(int) - 1) )
#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) ) //第一个可选参数地址
#define va_arg(ap,t) ( *(t *)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)) ) //下一个参数的值
#define va_end(ap) ( ap = (va_list)0 ) // 将指针置为无效
*/
void minprintf(char *fmt,...)
{
    va_list ap;    //va_list表示可变参数列表类型,实际上就是一个char指针
    char *p,*sval;
    double dval;
    int ival;
    va_start(ap,fmt);   //sizeof(fmt)=8  fmt=0x7fff3ae4b3b8  ap=0x7fff3ae4b3e0  两个字符的指针  获取字符串的首地址\
    我猜想,这一句是fmt的首地址赋给ap       现在还在疑惑
    for(p=fmt;*p;p++)
    {
        if(*p!='%')
        {
            putchar(*p);   
            continue;
        }
        switch (*++p)
        {
            case 'd':
                ival=va_arg(ap,int);  //获取int类型的参数
                printf("%d",ival);
                break;
            case 'f':
                dval=va_arg(ap,double);
                printf("%f",dval);
                break;
            case 's':
                for(sval=va_arg(ap,char *);*sval;sval++)   //获得字符串的首地址
                {
                    putchar(*sval);
                }
                break;
            default :
                putchar(*p);
                break;
        }
    }
    va_end(ap);
}
int sum(int m,...)
{
    va_list ap;//依次指向每个无名参数
    va_start(ap,m);//将ap指向第一个无名参数
    int sum=0;
    while(m--)
    {
       sum+=va_arg(ap,int);
    }
    va_end(ap);//结束时候的清理工作
    return sum;
 
 
}
int main(int argc,char *argv[])
{
  minprintf("ajsdsajksdvasda  %d   %s  %f \n",10,"asa",20.1);  
  printf("%d\n",sum(3,10,20,32));
  return 0;
}

结果:
在这里插入图片描述

三、inline关键字(内联函数)的应用

查略的相关资料:较全的inline资料嵌软的inline学习
编译器的相关:GCC的安装

gcc flag.c -L ./     #添加头文件的地址

头文件

#ifndef __A_H__
#define __A_H__

#include<stdio.h>

//函数定义为inline即:内联函数
inline char* dbtest(int a);

#endif

源文件

#include "A.h" 
 
char* dbtest(int a) 
{  
    return (a % 2 > 0) ? "奇" : "偶";  
}   
  
int main()  
{  
    int i = 0;  
    for (i=1; i < 10; i++) 
    {  
        printf("i:%d    奇偶性:%s \n", i, dbtest(i));      
    }  
} 

运行现象:
在这里插入图片描述
这个inline的关键字和#define、const等的比较。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值