第12章 存储类别、链接和内存管理

作用域

  1. 作用域描述程序中可以访问标识符 的区域.
  2. 一个C变量的作用域可以是块作用域、函数作用域、函数原型作用域或文件作用域。
  3. 块是用一对花括号括起来的代码区域
#include <stdio.h>

int main(void)
{
    int x;
    x = 1;
    printf("%d\n", x);
    {
        int x = 5;          // 新的x 
        printf("%d\n" , x); // x作用域结束 
    }
    printf("%d\n", x);      // 原来的x 

    return 0;
}

链接

C变量用3种属性:外部链接、内部链接或无链接。具有块作用域、函数作用域或函数原型作用域的变量都是无链接变量。
简单来说就是有链接的变量都是全局变量。不过之间也有点不同

存储期

C对象有4中存储期: 静态存储期、线程存储期、自动存储期、动态分配存储期。

  • 静态存储期:一直存在
  • 线程存储期:从被声明时到线程结束一直存在。
  • 自动存储期:当程序进入这些块时分配内存。推出时释放内存
  • 动态分配:用特殊的关键字来创建和释放内存


    image.png

块作用域的静态变量

#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;           //执行3次都是1
    static int stay = 1;    //会记录住原来的

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

image.png

内部链接的静态变量

该存储类别的变量具有静态存储期、文件作用域和内部链接。定义在所用函数外部(和上面那个不一样)

static int svil = 1;   //静态变量,内部链接
int main(void)
{
      extern int svil;   //使用定义在别处的
}
注:作用域只有本文件有效

外部链接的静态变量

int Errupt;
int main(void)

1.不使用全局变量, 从写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.重写上面

//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;   //存储字符串
    char *temp; //用于零时存储
    int words;  //单词数量
    int len;    //计算长度,方便后面拷贝
    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 *));   //数组里的每一个元素是一个指针,指向char类型(数组里存储的是指向char类型的指针)
    temp = (char *) malloc(SIZE * sizeof(char));    //分配一段内存,用于存储字符串
    for ( i = 0; i < words; i++)
    {
        scanf("%s", temp);      //输入字符串,scanf将空格回车视为一个单词的结束
        len = strlen(temp);     //计算单词占多少空间
        p[i] = (char *) malloc((len + 1) * sizeof(char));   //p里面每个元素都是一个指针,分配内存让他指向该内存,+1是为了存储\0
        strcpy(p[i], temp);     //拷贝
    }
    free(temp);     //释放temp的空间
    for ( i = 0; i < words; i++)
    {
        puts(p[i]);
    }
    free(p);    //释放p空间
    
    return 0;

}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容