第12章 存儲(chǔ)類(lèi)別、鏈接和內(nèi)存管理

作用域

  1. 作用域描述程序中可以訪問(wèn)標(biāo)識(shí)符 的區(qū)域.
  2. 一個(gè)C變量的作用域可以是塊作用域沐批、函數(shù)作用域纫骑、函數(shù)原型作用域或文件作用域。
  3. 塊是用一對(duì)花括號(hào)括起來(lái)的代碼區(qū)域
#include <stdio.h>

int main(void)
{
    int x;
    x = 1;
    printf("%d\n", x);
    {
        int x = 5;          // 新的x 
        printf("%d\n" , x); // x作用域結(jié)束 
    }
    printf("%d\n", x);      // 原來(lái)的x 

    return 0;
}

鏈接

C變量用3種屬性:外部鏈接九孩、內(nèi)部鏈接或無(wú)鏈接惧磺。具有塊作用域、函數(shù)作用域或函數(shù)原型作用域的變量都是無(wú)鏈接變量捻撑。
簡(jiǎn)單來(lái)說(shuō)就是有鏈接的變量都是全局變量磨隘。不過(guò)之間也有點(diǎn)不同

存儲(chǔ)期

C對(duì)象有4中存儲(chǔ)期: 靜態(tài)存儲(chǔ)期、線程存儲(chǔ)期顾患、自動(dòng)存儲(chǔ)期番捂、動(dòng)態(tài)分配存儲(chǔ)期。

  • 靜態(tài)存儲(chǔ)期:一直存在
  • 線程存儲(chǔ)期:從被聲明時(shí)到線程結(jié)束一直存在江解。
  • 自動(dòng)存儲(chǔ)期:當(dāng)程序進(jìn)入這些塊時(shí)分配內(nèi)存设预。推出時(shí)釋放內(nèi)存
  • 動(dòng)態(tài)分配:用特殊的關(guān)鍵字來(lái)創(chuàng)建和釋放內(nèi)存


    image.png

塊作用域的靜態(tài)變量

#include <stdio.h>
void trystat(void);

int main(void)
{
    int count;

    for ( count = 1; count <= 3; count++)
    {
        printf("Here comes iteration %d:\n", count);
        trystat();
    }
    return 0;
}

void trystat(void)
{
    int fade = 1;           //執(zhí)行3次都是1
    static int stay = 1;    //會(huì)記錄住原來(lái)的

    printf("fade = %d and stay = %d\n", fade++, stay++);
}

image.png

內(nèi)部鏈接的靜態(tài)變量

該存儲(chǔ)類(lèi)別的變量具有靜態(tài)存儲(chǔ)期、文件作用域和內(nèi)部鏈接犁河。定義在所用函數(shù)外部(和上面那個(gè)不一樣)

static int svil = 1;   //靜態(tài)變量鳖枕,內(nèi)部鏈接
int main(void)
{
      extern int svil;   //使用定義在別處的
}
注:作用域只有本文件有效

外部鏈接的靜態(tài)變量

int Errupt;
int main(void)

1.不使用全局變量, 從寫(xiě)12.4

#include <stdio.h>
int critic(void);

int main(void)
{
    int units;

    printf("How many pounds to a firkin of butter?\n");
    scanf("%d", &units);
    while (units != 56)
    {
        units = critic();
    }
    printf("You must have looked it up!\n");

    return 0;
}

int critic(void)
{
    int i;
    printf("No luck, my friend. Try again.\n");
    scanf("%d", &i);
    return i;
}

2

//pe12-2b.c

#include <stdio.h>
#include "pe12-2a.h"

int main(void)
{
    int mode;

    printf("Enter 0 for metric mode, 1 for US mode: ");
    scanf("%d", &mode);
    while (mode >= 0)
    {
        set_mode(mode);
        get_info();
        show_info();
        printf("Enter 0 for metric mode, 1 for US mode");
        printf(" (-1 to quit): ");
        scanf("%d", &mode);
    }
    puts("Done");
    
    return 0;
}

//pe12-2a.c

#include <stdio.h>
#include "pe12-2a.h"

static int mode = 0;
static double distance;
static double energy;

void set_mode(int n)
{
    if (n == 0 || n == 1)
        mode = n;
    else
        printf("Invalid mode specified.Mode %s used.\n", (mode ? "1(US)" : "0(metric)"));
}

void get_info(void)
{

    if (mode == 0)
    {
        printf("Enter distance traveled in kilometers: ");
        scanf("%lf", &distance);
        printf("Enter fuel consumed in liters: ");
        scanf("%lf", &energy);
    }
    
    else
    {
        printf("Enter distance traveled in miles: ");
        scanf("%lf", &distance);
        printf("Enter fuel consumed in gallons: ");
        scanf("%lf", &energy);
    }
    
}

void show_info(void)
{
    double consuption;
    if (mode == 0)
    {
        consuption = energy / distance * 100;
        printf("Fuel consumption is %.2lf liters per 100 km\n", consuption);
    }
    else
    {
        consuption = distance / energy;
        printf("Fuel consumption is %.1lf miles per gallon\n", consuption);
    }

}

//pe12-2a.h

void set_mode(int);

void get_info(void);

void show_info(void);

3.重寫(xiě)上面

//pe12-2b.c

#include <stdio.h>
#include "pe12-2a.h"

int main(void)
{
    int mode;
    int num = 0;
    double distance, energy;

    printf("Enter 0 for metric mode, 1 for US mode: ");
    scanf("%d", &mode);
    while (mode >= 0)
    {
        num = set_mode(num, mode);
        get_info(num, &distance, &energy);
        show_info(num, distance, energy);
        printf("Enter 0 for metric mode, 1 for US mode");
        printf(" (-1 to quit): ");
        scanf("%d", &mode);
    }
    puts("Done");
    
    return 0;
}

//pe12-2a.c

#include <stdio.h>
#include "pe12-2a.h"


int set_mode(int n,int m)
{
    if (m == 0 || m == 1)
        n = m;
    else
        printf("Invalid mode specified.Mode %s used.\n", (n ? "1(US)" : "0(metric)"));
    return n;
}

void get_info(int n, double *distance, double *energy)
{

    if (n == 0)
    {
        printf("Enter distance traveled in kilometers: ");
        scanf("%lf", distance);
        printf("Enter fuel consumed in liters: ");
        scanf("%lf", energy);
    }
    
    else
    {
        printf("Enter distance traveled in miles: ");
        scanf("%lf", distance);
        printf("Enter fuel consumed in gallons: ");
        scanf("%lf", energy);
    }
    
}

void show_info(int mode , double distance, double energy)
{
    double consuption;
    if (mode == 0)
    {
        consuption = energy / distance * 100;
        printf("Fuel consumption is %.2lf liters per 100 km\n", consuption);
    }
    else
    {
        consuption = distance / energy;
        printf("Fuel consumption is %.1lf miles per gallon\n", consuption);
    }

}

//pe12-2a.h


int set_mode(int, int);

void get_info(int, double *, double *);

void show_info(int, double, double);

4

#include <stdio.h>

int ret_num(void);

int main(void)
{
   int i;
   ret_num();
   i = ret_num();
   printf("%d\n", i);
}

int ret_num(void)
{
   static int count = 0;
   return ++count;
}

5

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 100

void stsrt(int *st[], int num);

int main(void)
{
    int number[SIZE];
    int i;
    int *p[SIZE];
    
    srand((unsigned int) time(0));
    for ( i = 0; i < SIZE; i++)
    {
        number[i] = rand() % 10 + 1;
        p[i] = &number[i];
    }
    stsrt(p, SIZE);
    puts("排序后:"); 
    for ( i = 0; i < SIZE; i++)
    {
        printf("%d ", *p[i]);
    }
    
    
    printf("\n");
    puts("排序前:");
    for ( i = 0; i < SIZE; i++)
    {
        printf("%d ", number[i]);
    }

    return 0;
}

void stsrt(int *st[], int num)
{
    int *temp;
    int top, seek;
    int i = 0;
    for ( top = 0; top < num - 1; top++)
    {
        for ( seek = top + 1; seek < num; seek++)
        {
            if ( *st[top] < *st[seek])
            {
                temp = st[top];
                st[top] = st[seek];
                st[seek] = temp;
            }
            
        }
        
    }
}

6出自:https://blog.csdn.net/o707191418/article/details/81904734

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void)
{
    int random_[10] = {0};
    int i, num;

    srand((unsigned int) time(0));
    for(i = 0; i < 100; i++)
    {
        num = rand() % 10 +1;
        random_[num - 1]++;
    }
    for ( i = 0; i < 10; i++)
    {
        printf("%d : %d\n", i + 1, random_[i]);
    }
    
}

7

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int roll_n_dice(int , int );
int main(void)
{
    int size, dice, many, status;
    int i, roll;

    srand((unsigned int) time(0));
    puts("Enter the number of sets; enter q to stop.");
    while (scanf("%d", &many) == 1 && many > 0)
    {
        puts("How many sides and how many dice?");
        if ((status = scanf("%d %d", &size, &dice)) != 2)
        {
            if (status == EOF)
                break;
            else
            {
                puts("You should have entered an integer.");
                puts("Let's begin again.");
                while (getchar() != '\n')
                    continue;
                puts("Enter the number of sets; enter q to stop.");
                continue;
            }
            
        }
        printf("Here are %d sets of %d %d-sided throws.\n", many, dice, size);
        for ( i = 0; i < many; i++)
        {
            roll = roll_n_dice(dice, size);
            printf("%d ", roll);
        }

        puts("\nEnter the number of sets; enter q to stop.");
        
    }
    
}

int roll_n_dice(int dice, int size)
{
    int total = 0;
    int i;
    if (size < 2)
    {
        printf("Need at least 2 sides.\n");
        return -2;
    }
    if (dice < 1)
    {
        puts("Need at lease 1 die.\n");
        return -1;
    }
    for ( i = 0; i < dice; i++)
    {
        total += rand() % size + 1;
    }
    return total;
}

8

#include <stdio.h>
#include <stdlib.h>

int * make_array(int elem, int val);
void show_array(const int ar[], int n);

int main(void)
{
    int * pa;
    int size;
    int value;

    printf("Enter the number of elements:");
    while (scanf("%d", &size) == 1 && size > 0)
    {
        printf("Enter the initialization value: ");
        scanf("%d", &value);
        pa = make_array(size, value);
        if (pa)
        {
            show_array(pa, size);
            free(pa);
        }
        printf("\nEnter the number of elements (<1 to quit): ");
        
    }
    printf("Done.\n");
    return 0;
}

int * make_array(int elem, int val)
{
    int *p;
    int i;
    p = (int *) malloc(elem * sizeof(int));
    for ( i = 0; i < elem; i++)
    {
        p[i] = val;
    }
    
    return p;
}

void show_array(const int ar[], int n)
{
    int i;
    for ( i = 0; i < n; i++)
    {
        printf("%d ", ar[i]);
        if ((i + 1) % 8 == 0)
            printf("\n");
    }
    
}

9https://blog.csdn.net/o707191418/article/details/81904734

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 64

int main(void)
{
    char **p;   //存儲(chǔ)字符串
    char *temp; //用于零時(shí)存儲(chǔ)
    int words;  //單詞數(shù)量
    int len;    //計(jì)算長(zhǎng)度桨螺,方便后面拷貝
    int i;

    printf("How many words do you wish to enter? ");
    scanf("%d", &words);
    printf("Enter %d words now:\n", words);
    p = (char **) malloc(words * sizeof(char *));   //數(shù)組里的每一個(gè)元素是一個(gè)指針宾符,指向char類(lèi)型(數(shù)組里存儲(chǔ)的是指向char類(lèi)型的指針)
    temp = (char *) malloc(SIZE * sizeof(char));    //分配一段內(nèi)存,用于存儲(chǔ)字符串
    for ( i = 0; i < words; i++)
    {
        scanf("%s", temp);      //輸入字符串灭翔,scanf將空格回車(chē)視為一個(gè)單詞的結(jié)束
        len = strlen(temp);     //計(jì)算單詞占多少空間
        p[i] = (char *) malloc((len + 1) * sizeof(char));   //p里面每個(gè)元素都是一個(gè)指針魏烫,分配內(nèi)存讓他指向該內(nèi)存,+1是為了存儲(chǔ)\0
        strcpy(p[i], temp);     //拷貝
    }
    free(temp);     //釋放temp的空間
    for ( i = 0; i < words; i++)
    {
        puts(p[i]);
    }
    free(p);    //釋放p空間
    
    return 0;

}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末肝箱,一起剝皮案震驚了整個(gè)濱河市哄褒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌煌张,老刑警劉巖呐赡,帶你破解...
    沈念sama閱讀 217,734評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異骏融,居然都是意外死亡链嘀,警方通過(guò)查閱死者的電腦和手機(jī)井辜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,931評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)管闷,“玉大人,你說(shuō)我怎么就攤上這事窃肠“觯” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 164,133評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵冤留,是天一觀的道長(zhǎng)碧囊。 經(jīng)常有香客問(wèn)我,道長(zhǎng)纤怒,這世上最難降的妖魔是什么糯而? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,532評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮泊窘,結(jié)果婚禮上熄驼,老公的妹妹穿的比我還像新娘。我一直安慰自己烘豹,他們只是感情好瓜贾,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,585評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著携悯,像睡著了一般祭芦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上憔鬼,一...
    開(kāi)封第一講書(shū)人閱讀 51,462評(píng)論 1 302
  • 那天龟劲,我揣著相機(jī)與錄音,去河邊找鬼轴或。 笑死昌跌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的照雁。 我是一名探鬼主播避矢,決...
    沈念sama閱讀 40,262評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼囊榜!你這毒婦竟也來(lái)了审胸?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,153評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤卸勺,失蹤者是張志新(化名)和其女友劉穎砂沛,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體曙求,經(jīng)...
    沈念sama閱讀 45,587評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡碍庵,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,792評(píng)論 3 336
  • 正文 我和宋清朗相戀三年映企,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片静浴。...
    茶點(diǎn)故事閱讀 39,919評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡堰氓,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出苹享,到底是詐尸還是另有隱情双絮,我是刑警寧澤,帶...
    沈念sama閱讀 35,635評(píng)論 5 345
  • 正文 年R本政府宣布得问,位于F島的核電站囤攀,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏宫纬。R本人自食惡果不足惜焚挠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,237評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望漓骚。 院中可真熱鬧蝌衔,春花似錦、人聲如沸蝌蹂。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,855評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)叉信。三九已至亩冬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間硼身,已是汗流浹背硅急。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,983評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佳遂,地道東北人营袜。 一個(gè)月前我還...
    沈念sama閱讀 48,048評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像丑罪,于是被迫代替她去往敵國(guó)和親荚板。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,864評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容