IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言:存储类、链接和内存管理 -> 正文阅读

[C++知识库]C语言:存储类、链接和内存管理

博主:鸿渐之翼
个人介绍:一个搞底层的FW,喜欢发一点没用的东西。
在这里插入图片描述

存储类:

作用域:
作用域描述程序中可以访问的一个标识符或多个区域。我们使用的局部变量,包括函数的形式变量,都是代码块作用域。

double A(double b)
{
double j=1;
int i;
for(i=0;i<10;i++)
double k =j+i;//k的作用域开始
...
       j *=k;//k的作用域结束
}
return j;

函数原型作用域(function prototype scope)
适用于函数原型中使用的变量名称:

int A(int a, double b);

链接:
c语言中变量具有以下链接:
外部链接(external linkage),内部链接(internal linkage)
空链接(no linkage)

存储时期:
c变量中两种存储时期:
静态存储时期(static storage duration)
自动存储时期(automantic storage duration)

自动变量:
默认情况下,在代码块或函数的头部定义的任意变量都属于自动存储类。

寄存器变量:
寄存器变量可以被存储在CPU寄存器中。
在这里插入图片描述

因为寄存器变量多放在一个寄存器而非内存中,所以无法获得寄存器变量的地址。
以下声明寄存器变量:

int main(void)
{
register int quick;
}


具有代码块作用域的静态变量
静态变量(static variable)“静态”指的是位置固定不动。
从函数条用到下一次调用,它们并不会消失。
具有外部链接的静态变量
包含了
1.文件作用域2.外部链接3.静态存储时期。
这一类型被称为external storage class

int out;//外部定义的变量
double a[10];//外部定义的数组
extern char a;
int main(void){
    extern int out; //可选择声明
    extern double a[]; //可选择声明
}

out的两次申明是链接的例子。它们都指向同一个变量,外部变量具有外部链接。
具有内部链接的静态变量

static int a=1int main(void{
int a=1//外部链接
statci int b=2; //内部链接
}

在这里插入图片描述

存储类总结

自动变量具有代码块作用域、空链接和自动存储时期,一般是一个函数私有。
寄存器变量和自动变量具有相同的属性,编译器能使用更快的内存或存储器来存储它们,但无法获取一个寄存器变量的地址。
具有静态存储时期的变量可能具有外部链接、内部链接或空链接。
当程序执行到包含变量声明的代码块时,给具有自动存储时期的变量分配内存,并在代码块结束时释放这部分内存。如果没有没有初始化,这样的变量具有一个无效值。具有代码块作用的变量局部包含变量声明的代码块。
example:

#include<stdio.h>
void report_count();
void accumulate(int a);
int count=0;//文件作用域,外部链接
int main(void){
int value;//自动变量
register int i;//寄存器变量
extern int count; //引用声明,外部链接
static int total = 0; //静态定义,内部链接
void accumulate(int k) //函数原型
printf("Enter a positive interger:");
while(scanf("%d",&value)==1 && value>0)
{
++count;//使用文件作用域变量
for(i==value;i>=0;i--)
accumulate(i);
printf("Enter a positive integer;");
}
report_count();
return 0;
}
void report_count()
{
printf("Loop executed %d times\n",count);
}
void accumulate(int k)
{
 static int subtotal =o; //静态、空链接
 if (k<=0)
 {
 printf("loop cycle: %d\n",count);
 printf("subtotal:%d total:%d\n",subtotal,total);
 subtotal=0;
 }
 else
 {
   subtotal +=k;
   total +=k;
 };
}

int count=0;//文件作用域,外部链接
int value;//自动变量
register int i;//寄存器变量
++count;//使用文件作用域变量
extern int count; //引用声明,外部链接
static int total = 0; //静态定义,内部链接
void accumulate(int k) //函数原型

存储类与函数

double a();
static double b();
extern double c();

double a()默认为外部,函数a()与函数c()可以被程序其他文件中的函数使用,b()不能,因为b被限定在一个文件中。
static存储类就是创建一个特定的模版私有的函数。从而避免可能的名字冲突。

在这里插入图片描述

分配内存 malloc()与free()

除了常规的分配内存方式

float a;
char a[] = "aaaaa";
int a[100];

c语言中还有函数malloc(),malloc()分配了内存,但是没有为它制定名字。然而,malloc可以返回内存第一个字节的地址。

double * a;
a = (double *)malloc(20 *sizeof(double));

这段代码请求20个double类型的空间,并且把a指向该空间所在位置。a是作为一个double类型值的指针声明,而不是指向20个double类型值的数据块指针。
例如程序

//dyn_arr.c
#include<stdio.h>
#include<stdlib.h>//为malloc()和free函数提供原型
int main(int argc, char const *argv[])
{
    double *pointer;
    int max;
    int number;
    int i=0;
    puts("what is maximum number of type double entries?");
    scanf("%d",&max);
    pointer =(double *)malloc(max *sizeof(double));
    if(pointer == NULL)
    {
    	puts("Memory allocation failed.Goodby.");
    	exit(EXIT_FAILURE);
    }
    /*pointer现在指向max个元素的数组*/
    puts(" Enter teh values:");
    while(i < max && scanf("%lf",&pointer[i])==1);
         ++i;
    printf("Here are you %d entries:\n",number=i);
    for(i = 0; i < number;i++)
    {
         	printf("%7.2f",pointer[i]);
         	if(i % 7 == 6)
         		putchar('\n');
    }
    if(i % 7 !=0)
         	putchar('\n');
         puts("done.");
    free(pointer);

	return 0;
}

分配对应存放所请求数目足够大的内存空间,并把该内存的地址赋给指针pointer

pointer =(double*)malloc(max *sizeof(double));

malloc()可能无法获得所需数量的内存,在这种情况下,函数返回空指针,程序终止;

if(pointer ==NULL)
{
 puts("Memory allocation failed.Goodbye.");
 exit(EXIT_FAILURE);
}

如果成功分配内存,程序把pointer当作max个的数组名字
最后使用free()释放内存。

free()的重要性importance of Free()!
example:

int main()
{
double a[2000];
int i
}
for (i=0; i<=1000;i++)
gobble(a,2000);
void gobble(double argv[],int n)
{
double * p =(double *)malloc(n *sizeof(double));
/*free(temp);*/
//忘记使用free();
}

第一次调用gobble(),它创建了指针p,斌使用了maclloc()分配16000字节内存(设double是8字节)。
当函数终止时,指针p作为一个自动变量消失。但它指向的16000个字节内存依然存在,我们无法访问这些内存,因为地址没了。由于没有调用free(),不可以再使用它了。
第二次调用gobble(),它创建了一个p,再次使用malloc()分配的16000个字节内存。第一次的内存不能使用,因此malloc()不得不再找一个16000字节的块。
当程序完成循环1000次,已经有1600万字节的内存从内存池中移走了。程序已经出现了内存溢出。我们称为memory leak。

在这里插入图片描述

本篇完

在这里插入图片描述

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-17 11:43:20  更:2021-07-17 11:43:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/6 15:19:57-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码