在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:這不是抄襲,是原創

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM