娓娓道来c指针 (2)内存分配
(2)内存分配
c语言中描写叙述变量的时候经常使用的两个用语
1.作用域:也叫可见域,指的是变量的作用范围。
在哪个范围内。该变量是可见的、能够使用的。
2.生存期:也叫存储期。指的是变量从创建到销毁的生存时间段。
作用域和存在域是两个不同的概念。比方在程序的某个位置。某变量存在(内存中分配了地址)但不可见(不可使用)。
作用域
从作用域看。变量分为下面三种:
1.全局变量
在c语言中,把在不论什么函数之外声明的变量称为全局变量。普通情况下。全局变量在不论什么地方都是可见的。
当然也有例外,比方在语句块{}内声明了一个同名的局部变量。则该全局变量会临时不可见。
//全局变量
int foo = 5;
void fun()
{
printf(" fun()->foo...%d\n", foo);
}
int main()
{
int bar = 3;
printf("main()->foo...%d\n", foo);
printf("main()->bar...%d\n", bar);
{
//局部变量,屏蔽同名全局变量foo
int foo = 6;
printf(" {}->foo...%d\n", foo);
//局部变量。屏蔽同名局部变量bar
int bar = 4;
printf(" {}->bar...%d\n", bar);
}
fun();
return 0;
}
执行
从执行结果能够看出全局变量的可见范围。当然,假设在全局变量未被声明之前就试图使用它,则也会出错。(这与规则:“未声明,不可使用”有关。
)
除此之外,c中的设计思想是:一个全局变量也是一个默认的外部变量(extern)。也就是说,一个全局变量不仅在本文件里是全局可见的。在别的文件里也是可见的。如
//1.c
int foo;
在还有一个文件里有
//2.c
int foo;
编译报错:foo被反复定义,命名冲突。
这样的默认行为被广为诟病。不少人觉得,变量的可见域默认下应仅限于当前文件,须要扩大时,应该由程序猿自己控制。
而且对于函数,也有相同的默认行为。
怎样防止这样的行为?
(1)若是确实须要使用一个同名的变量,则可对已存在的同名全局变量用static修饰,使之成为静态的全局变量。这样它的可见域,就仅限于它所在的文件之内。如
//1.c
static int foo; //可见域被限制于本文件内
在还有一个文件里又一次声明 int foo; 没有问题。
(2)不定义新的,直接使用别的文件里的全局变量。语法是 extern int foo; keyword extern 是外部的意思,表明变量 foo,已在别的地方定义,这里仅仅是在使用之前。作一个声明而已,不是反复定义。当然不作此声明也是不可用的。这再次体现了:可见,但不一定可用。
2.文件内部的静态变量
这就是上文中说的静态的全局变量。
3.局部变量
在函数中。或更直接的说是在语句块{}内定义的变量,是局部变量。它的可见域仅限于语句块内,在其他地方无法引用。局部变量在函数被调用时由系统分配存储区。在不同的函数中同名的变量实际上在内存中占不同的单元。因此在不同的函数中能够定义同样名字的局部变量。
如函数的形參。main函数中定义的变量都是局部变量。
对作用域进行总结
c语言中存在三种作用域
(1)块作用域
自己主动变量(auto、register)和内部静态变量(static)具有块作用域。在一个块内声明的变量,其作用域从声明点開始。到该块结束为止。
函数定义中声明的形參。其作用域限定在该函数体内,与其它函数中声明的同名变量不是一回事,同意在不同的函数中使用同样的变量名。编译器将为这些变量分配不同的存储单元。不会冲突。
(2)文件作用域
外部静态变量(static)具有文件作用域。从声明点開始到文件末尾,此处所指的文件是编译基本单位—c文件。
(3)全局(程序)作用域
全局变量(extern)具有全局作用域,仅仅要在使用前对其进行声明,便可在程序(由若干个文件组成)的任何位置使用全局变量。
生存期
从生存期看。分为下面三种:
1.静态变量(static variable)
全局变量和指定static的局部变量,都具有静态存储期。它们从程序開始一直到程序结束都存在,故被统称为静态变量。
2.自己主动变量(auto variable)
没有被指定为static的局部变量和寄存器变量(register variable)都是自己主动变量。函数的形參及代码块中定义的变量都属于auto变量,这是C语言中应用最广的一种变量,这类变量是栈分配的,是动态分配存储空间的。举函数形參为例。当调用该函数时。为形參分配存储空间,当函数调用结束时。就自己主动释放这些存储空间。对代码块中定义的变量(包括函数中定义的变量),当运行到变量声明语句时。系统为这些auto变量分配空间,当程序流程离开代码块时,这些变量被自己主动撤销,其占用的内存空间被释放。
3.堆变量
通过malloc()函数分配内存区域的变量被放在堆中。故称为堆变量。而且似乎这个“堆”和数据结构中的堆没有什么联系。仅仅是一种称呼而已。这样的变量须要手动释放内存区域:free(变量名),也就是说它从创建时起就一直存在直到使用free()释放为止。当然。即使最后忘了释放。现在的操作系统也会在程序结束后释放为它分配的内存。
只是仍然建议:谁创建,谁释放。
专栏文件夹:
娓娓道来c指针 (2)内存分配的更多相关文章
- 【VS开发】【编程开发】【C/C++开发】结构体中的数组与指针的内存分配情况说明
[VS开发][编程开发][C/C++开发]结构体中的数组与指针的内存分配情况说明 标签:[VS开发] [编程开发] 主要是疑惑在结构体定义的数组的内存空间与指针动态分配的内存空间,在地址上连续性.以及 ...
- 终于懂了:Delphi的函数名不是地址,取地址必须遵守Object Pascal的语法(Delphi和C的类比:指针、字符串、函数指针、内存分配等)good
这点是与C语言不一样的地方,以前我一直都没有明白这一点,所以总是不明白:函数地址再取地址算怎么回事? ------------------------------------------------- ...
- C和指针--动态内存分配
1.为什么需要使用动态内存分配 数组的元素存储于内存中连续的位置上,当一个数组被声明时,它所需要的内存在编译时就被分配.当你声明数组时,必须用一个编译时常量指定数组的长度.但是,数组的长度常常在运行时 ...
- 14深入理解C指针之---指针与内存分配
一.内存的含义 1.定义:物理内存是固定,逻辑内存是非常灵活的 2.特征: 1).逻辑内存最终必须映射到物理内存才能作用 2).逻辑内存每次映射可能到不同的物理内存 3).逻辑内存与物理内存的链接通过 ...
- golang学习之指针、内存分配
func pointer_test() { //空指针,输出为nil var p *int fmt.Printf("p: %v\n", p) //指向局部变量,变量值初始为0 va ...
- linux c二级指针的内存分配和使用
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <unistd.h> ...
- C/C++动态二维数组的内存分配和释放
C语言: 1 //二维数组动态数组分配和释放 //数组指针的内存分配和释放 //方法一 char (*a)[N];//指向数组的指针 a = (char (*)[N])malloc(sizeof(ch ...
- C++指针和动态内存分配
指针和动态内存分配 数组与指针 数组 数组名是一个指针常量. 数组名传递数据时,传递的是地址. 数组作为函数参数时不指定第一维大小. 对象数组 A a[2] = {A(1,2)}; 执行时先调用有参数 ...
- C和指针 第十一章 动态内存分配
声明数组时,必须指定数组长度,才可以编译,但是如果需要在运行时,指定数组的长度的话,那么就需要动态的分配内存. C函数库stdlib.h提供了两个函数,malloc和free,分别用于执行动态内存分配 ...
随机推荐
- 信号槽库:sigslot.h和sigc++使用
用qt的知道,qt有方便简单的信号槽机制,但需要专门的qt工具处理. 如果想直接使信号槽就可以使用sigslot库,或者sigc++库,或者boost中的signals,这里介绍sigslot和sig ...
- Servlet4.0 注解不生效解决
当我们创建好一个4.0的servlet 生成的注解大概是这样 name=xxxxx 默认的是不具有效果的 你可以有两种方式 1.去掉属性name,3.0就是这样子的 2.非要有name属性 请加上u ...
- 牛客练习赛16 C 任意点【并查集/DFS/建图模型】
链接:https://www.nowcoder.com/acm/contest/84/C 来源:牛客网 题目描述 平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可 ...
- 2018 CCPC 女生专场
可能是史上最弱的验题人—— Problem A (小)模拟. #include <bits/stdc++.h> using namespace std; int T; int main() ...
- codevs——1230 元素查找
时间限制: 1 s 空间限制: 128000 Ks 题目等级 : 钻石 Diamond 题解 查看运行结果 题目描述 Description 给出n个正整数,然后有m个询问,每个询问一个整数 ...
- Path Sum II (Find Path in Tree) -- LeetCode
Given a binary tree and a sum, find all root-to-leaf paths where each path's sum equals the given su ...
- 洛谷 P2183 [国家集训队]礼物
题目描述 一年一度的圣诞节快要来到了.每年的圣诞节小E都会收到许多礼物,当然他也会送出许多礼物.不同的人物在小E心目中的重要性不同,在小E心中分量越重的人,收到的礼物会越多.小E从商店中购买了n件礼物 ...
- devexpress XtraReport报表 ---主从报表
private void GetWqpWorkPrinter(List<ReelListMagt> list, string WorkDate, User user) { ReelList ...
- "library not found for - "解决办法
在我们编译的时候有时候会报这个错误 "library not found for - " 由于是我们在项目中使用了一些第三方的库,就比如我再使用百度的静态库文件的时候,报出的这个错 ...
- 快速创建一个的指定大小的内容全为0xFF的文件
比如需要创建一个大小为2KB,内容为全0xFF的文件 步骤只有两步: 第一步. dd if=/dev/zero of=./test.img bs=1 count=2048 第二步. 使用WinHex文 ...