在C中判断变量存储类型(字符常量/数组/动态变量)

在chinaunix论坛上有人问到关于变量存府类型的问题,我觉得可以写个测试代码加深大家对内存使用和布局的理解。下面我把原问题及处理办法贴出来,限供大家参考。

原问题:

static
void testB (char *src)
{
/* 判断传入的src 是属于 @1/2/3 ??? */
do_somthing ();
} static
void testA (char *src)
{
char *a = "hello world";
char b[100] = "hello world"; testB (a); /* @1 */
testB (b); /* @2 */
testB ("hello world" ); /* @3 */
}

@1 有名常量
@2 缓冲资源
@3 未名常量

怎么用宏去区别啊???

下面是对这个问题的处理办法:

编译器和语言并没有直观的提供什么功能去实现这个处理,可以换个思路,在C中有四个存储类型static,automatic,register,dynamic。每种类型的存储的地址都是可识别的,通过对存储地址的判断可以识别实事的变量或常量变型。
char *a = "hello world";testB (a); 和 testB ("hello world" );  这两个调用实际上是一样的。编译器在处理的时候会把对hello world的变引指向相同的地方(编译器基本都这么进行优化处理,不属于标准规定)。根据上述说法那下面的公式成立:编译器对常量变量的内存处理策略+操 作系统的内存布局=可明确定位的内存识别。由于操作系统的内存布局因系统而定,编译器的实现也各有不同,所以就算得出结论要实现相关处理的代码也是很难进 行移植的。下面是完成相关功能的代码在linux下测试通过。

#include <stdlib.h>
#include <stdio.h>
#include <string.h> int global_dummy = 0;
static
void testB (char *src)
{
/* 判断传入的src 是属于 @1/2/3/4*/
int local_dummy = 0;
if( (unsigned long)src < (unsigned long )&local_dummy ){
//if( src > testB ){
if( (unsigned long )src < (unsigned long )&global_dummy ){
printf("string literal\n\n");
}
else if ( (unsigned long ) src > (unsigned long ) &global_dummy){
printf("malloc string\n\n");
}
//}
}
else
{
printf("array: stack\n\n");
}
}
static
void testA ()
{
char *a = "hello world";
char b[100] = "hello world";
char *c = malloc(100);
strcpy(c,a);
printf("char *a = \"hello world\";\n");
testB (a); /* @1 */
printf("char b[100] = \"hello world\";\n");
testB (b); /* @2 */
printf(" (\"hello world\" )\n");
testB ("hello world" ); /* @3 */
printf("char *c = malloc(100);\n");
testB (c ); /* @4 */
free(c);
} int main(int argc,const char** argv)
{
testA();
return 0;
}

程序的运行结果如下:
char *a = "hello world";
string literal

char b[100] = "hello world";
array: stack

("hello world" )
string literal

char *c = malloc(100);
malloc string

虽然没有处理和测试所有情况,但以述代码我觉得针对理解内存布局和变量使用问题已经足够了。

下面贴个linux下程序运行的内存布局图,可以加深对上述代码的理解

ps:这不是抄袭,是原创

 
 
 
标签: 内存布局

在C中判断变量存储类型(字符常量/数组/动态变量)的更多相关文章

  1. python中判断变量的类型

    python的数据类型有:数字(int).浮点(float).字符串(str),列表(list).元组(tuple).字典(dict).集合(set) 一般通过以下方法进行判断: 1.isinstan ...

  2. JavaScript中判断变量类型最简洁的实现方法以及自动类型转换(#################################)

    这篇文章主要介绍了JavaScript中判断整字类型最简洁的实现方法,本文给出多个判断整数的方法,最后总结出一个最短.最简洁的实现方法,需要的朋友可以参考下 我们知道JavaScript提供了type ...

  3. 【react】利用prop-types第三方库对组件的props中的变量进行类型检测

    1.引言--JavaScript就是一个熊孩子   1.1对于JSer们来说,js是自由的,但同时又有许多让人烦恼的地方.javascript很多时候就是这么一个熊孩子,他很多时候并不会像C和java ...

  4. Js中判断变量存不存在的问题

    前面写过jquery对象存在与否的判断.现在谈下Js中判断变量存不存在的问题. 如果这样if(!a),当变量a在js中没有申明时,就会报错,那么接下去的代码将不会被执行.注意,这种判断只要变量申明过, ...

  5. JavaScript中判断整字类型最简洁的实现方法

    这篇文章主要介绍了JavaScript中判断整字类型最简洁的实现方法,本文给出多个判断整数的方法,最后总结出一个最短.最简洁的实现方法,需要的朋友可以参考下 我们知道JavaScript提供了type ...

  6. prop-types:该第三方库对组件的props中的变量进行类型检测

    利用prop-types第三方库对组件的props中的变量进行类型检测

  7. Python如何判断变量的类型

    Python判断变量的类型有两种方法:type() 和 isinstance() 如何使用 对于基本的数据类型两个的效果都一样 type() ip_port = ['219.135.164.245', ...

  8. js中判断对象具体类型

    大家可能知道js中判断对象类型可以用typeof来判断.看下面的情况 <script> alert(typeof 1);//number alert(typeof "2" ...

  9. C语言支持的四种变量存储类型

    http://blog.csdn.net/zhandoushi1982/article/details/5425835 一)auto:auto称为自动变量(局部变量).局部变量是指在函数内部说明的变量 ...

随机推荐

  1. Android自己定义控件系列五:自己定义绚丽水波纹效果

    尊重原创!转载请注明出处:http://blog.csdn.net/cyp331203/article/details/41114551 今天我们来利用Android自己定义控件实现一个比較有趣的效果 ...

  2. dom01

    事件冒泡:即事件最开始由最具体的元素(文档中嵌套层次最深的那个节点)接收,然后逐级向上传播至最不具体的那个节点(文档). 事件捕获:即不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件. ...

  3. 为Pythonic论坛添加一个“专题”功能(续)

    上篇博文<为Pythonic论坛添加一个“专题”功能>,在模板的层次上对发帖进行了限制.也就是根据用户是否拥有权限来决定是否显示发帖框. 但是自从这么“投机取巧”的写完模板后,整夜辗转反侧 ...

  4. Hbuilder jQuery 自定义代码块

    =begin 本文档是jquery代码块的编辑文件.修改其他的代码块,请在对应的激活代码助手点右下角的修改图标. HBuilder可使用ruby脚本来编辑代码块和增强操作命令. 1.编辑代码块 如果要 ...

  5. SQLServer 分组查询相邻两条记录的时间差

    原文:SQLServer 分组查询相邻两条记录的时间差 首先,我们通过数据库中表的两条记录来引出问题,如下图 以上为一个记录操作记录的表数据.OrderID为自增长列,后面依次为操作类型,操作时间,操 ...

  6. 【转】视差滚动(Parallax Scrolling)效果的原理和实现

    原文:http://www.cnblogs.com/JoannaQ/archive/2013/02/08/2909111.html 视差滚动(Parallax Scrolling)是指让多层背景以不同 ...

  7. Android借助Application重写App的Crash(简易版)

    MainActivity如下: package cn.testcrash; import android.app.Activity; import android.os.Bundle; /** * D ...

  8. 13个不可不知的ASP.NET MVC扩展点

    13个不可不知的ASP.NET MVC扩展点 ASP.NET MVC设计的主要原则之一是可扩展性.处理管线(processing pipeline)上的所有(或大多数)东西都是可替换的.因此,如果您不 ...

  9. 使用maven+eclipse搭建最简单的struts2的helloworld

    使用maven+eclipse搭建最简单的struts2的helloworld 一.web分层结构简介 1.web[细]粒度分层结构: 按细粒度分层可以分为以下6种: 1).表现层:html/css/ ...

  10. 图解 ENGLISH

    人在江湖,总得会几门手艺,英语必不可缺,下面几张图诠释了什么叫强大: