c primer plus第12章总结:存储类、连接和内存管理

作用域 :代码块、文件作用域;
连 接 :外部连接(extern)、内部连接(static)、空连接;
存储时期:静态存储时期、自动存储时期;
注:static表面的是连接类型,并非存储时期;文件作用域变量,不管何种连接,都是静态存储时期;

5种存储类型

存储类存储时期作用域连接声明方式初始化
自动自动代码块、函数头部代码块内,关键字auto需要初始化
寄存器自动代码块代码块内,关键字register
外部连接静态静态文件外部所有函数之外自动赋初值0
内部连接静态静态文件内部所有函数之外,关键字static自动赋初值0
空连接静态静态代码块代码块内,关键字static,作用域结束后不清空

存储类型说明符auto、static、register、extern、typedef:

    auto:有意覆盖外部函数定义,或表明不能改变为其他存储类;只能在代码块作用域中使用;
    static:对函数参数不能使用;例如:int move (static int flu); extern :
    register:属于请求,而非命令;只能用于代码块作用域变量,但不能获取变量地址;
    extern:变量在其他文件中定义,必须使用extern来声明变量;除了显示外部文件变量,还表明该函数或变量在其他地方已经定义过了;

外部变量定义和声明:

  • 不同于自动变量,只能用常量表达式来初始化文件作用域变量;
  • 一个外部变量只能进行一次初始化,而且必须是变量被定义时进行;
  • 可以用extern 来再次声明任何文件作用域的变量,并不改变连接类型;
int avr1 = 1;
static int avr2 = 1;
int main()
{
extern int avr1; // 使用全局变量,可以被其他文件使用;
extern int avr2; // 使用全局变量,但仍属于内部连接;
....
}

分配内存:malloc()和free()

  • malloc()可接收一个变量参数,匿名分配内存;可返回数组指针、结构指针等内存块的第一个字节地址;
  • 若malloc()找不到所需空间,返回空指针;
double* ptr = (double*)malloc(30 * sizeof(double));
// ptr指向一个double类型值的指针;
// 跟new有什么区别?
free(ptr);
// 除了malloc()和calloc(),不能用free来释放其他方式分配的内存;
    calloc()函数:
double* ptr = (double*)calloc(30,  sizeof(double));
//第一个参数,内存单元数量;第二个参数,内存单元字节大小;
//与malloc()不同,它将块中全部位均置为0;

类型限定词:

const:
    不能通过赋值、增量、加减运算来修改const变量值;
const float* pf; // pf指向常量浮点值;指向的值不能修改;
float* const pt; // pt是常量指针;指向地址不能变,但值能变;
float const* pt; // 同第一句,主要看const位于*的左边还是右边;

*Bjarne在他的The C++ Programming Language里面给出过一个助记的方法:
把一个声明从右向左读。
char * const cp; ( * 读成 pointer to )
cp is a const pointer to char
const char * p;
p is a pointer to const char;

volatile:
    表明数据除了可被程序修改,还可通过其他方式修改;

restrict:
    限定指针所指向的数据块只能有唯一访问途径;

课后习题

第2题:使用static文件作用域变量;

//main文件
int main()
{
    int mode;  // s_mode为static内部连接,所以同一变量尽量定为不同名称的;
               // pe12-2a.cpp文件中,再将mian文件中的参数赋值给s_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);
    }
    printf("Done.\n");

    return 0;
}
//pe12-2a.cpp文件
#include "stdafx.h"
#include "pe12-2a.h"

static int  s_mode;             // static类型参数命名时注意使用s_;
static double s_distance;  
static double s_fuelamount;

// 判断计算模式;
void set_mode(int mode)
{
    s_mode = mode;              

    if (s_mode == 0)
        printf("you choose for metric mode.\n");
    else if (s_mode == 1)
        printf("you choose for US mode.\n");
    else 
        printf("Invalid mode specified.Mode 1(US) used.\n");    
}

// 获取参与计算的distance 、fuelamount;
void get_info()
{
    if (s_mode == 0)
    {
        printf("Enter distance traveled in kilometers:");   
        get_double(&s_distance);
        printf("Enter fuel consumed in liters:");
        get_double(&s_fuelamount);
    }
    else 
    {
        printf("Enter distance traveled in miles:");
        get_double(&s_distance);
        printf("Enter fuel consumed in gallon:");
        get_double(&s_fuelamount);
    }
}

// 显示计算结果
void show_info()
{
    if (s_mode == 0)
    {
        printf("Fuel consumption is %.1lf liters per 100km.\n",
            s_fuelamount / (s_distance /100));
    }
    else 
    {
        printf("Fuel consumption is %.1lf miles per gallon.\n",
            s_distance / s_fuelamount);
    }
}

// 获取一个double类型值,注意使用double* 做参数;
void get_double(double* x)
{
    while (scanf("%lf", x) != 1)
    {
        while (getchar() != '\n')
            ;                    
        printf("please input the right number:\n");
    }
}

第5题:产生100个1-10范围随机数;

// 产生随机数;
int* random_number(int count, int range)
{
    srand((unsigned int) time(0));                 // 以系统时间为种子,初始化rand();
    int* ptr = (int*) malloc(count * sizeof(int)); // 注意free(ptr);

    for (int i = 0; i < count; i++)
    {           
        *ptr = rand() % range + 1;  
        //*ptr = 1 + (int)(10.0 * rand() / (range + 1.0));
        printf("%d ", ptr[i]);
    }
    printf("\n");

    return  ptr;
}
// 降序排列数组内的元素
void sort_number(int *number_ptr, int num)
{
    int top, seek, temp;

    for (top = 0; top < num-1; top++)
        {
            for (seek = top + 1; seek < num; seek++)
                {
                    if (number_ptr[top] - number_ptr[seek] < 0)
                    {
                        temp = number_ptr[top];
                        number_ptr[top] = number_ptr[seek];
                        number_ptr[seek] = temp;
                    }
                }
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值