您的位置:首页 > 其它

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

2013-07-03 14:58 267 查看
在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:这不是抄袭,是原创
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: