`
iwebcode
  • 浏览: 2045029 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

局部变量、全局变量、静态局部变量、静态全局变量的异同

 
阅读更多

转载:http://hi.baidu.com/shanghaocool/blog/item/e15f8797021cf81a7bf480b2.html


完成内容:

1.收获备忘;

2.局部变量、全局变量、静态局部变量、静态全局变量的异同;

3.设计函数atoi()(字符串转int型)

4.含参数的宏与函数的优缺点;

一.收获备忘

1.数组名指向的是一块内存块,内存的地址与大小在生命期内不可改变,只有内存块中的内容可以改变;指针可以随时指向任意类型的内存块;

2.strcpy()函数的原型:char *strcpy(char *strDestination, const char *strSource);

malloc()函数的原型:void *malloc(size_t size);

free()函数的原型:void free(void *memblock);

3.指针在free()delete后,需重新指向NULL,或指向合法的内存;

4.申请动态内存后,应该马上判断是否申请成功(mallocnew申请动态内存不成功返回NULL),若申请不成功,则用exit(1)强制退出程序;

5.内存分配的三种方式:

(1).从静态存储区域分配:变量在编译时已经分配好,在整个程序运行期间都存在,例如:全局变量,静态全局变量;

(2).从“栈”上分配:函数内的局部变量,在使用时自动从栈上创建内存区域,函数结束时自动释放。由于栈上内存的分配运算内置于处理器的指令集中,使用效率很高,但容量有限;

(3).从“堆”上分配:即动态内存分配,程序员可使用malloc ()/new申请任意大小的动态内存空间,同时由程序员决定何时使用free ()/delete去释放已申请的内存。使用起来十分灵活,但最容易出问题;

6.指针参数传递内存的方法及常见错误P47-P49

二.局部变量,全局变量,静态局部变量,静态全局变量的异同

虽然之前在编程时对这四个“变量”就有不少困惑,但一直没去细究,前两天在联想的笔试题中看到了这样一道题,貌似知道它们的区别却又不能说出其中的原理,今天决定将其弄清楚。

局部变量:在一个函数中或复合语句中定义的变量,在动态存储区分配存储单元,在调用时动态分配,在函数或复合语句结束时自动释放;

静态局部变量:在一个函数中定义局部变量时,若加上static声明,则此变量为静态局部变量,在静态存储区分配存储单元,在程序运行期间都不释放;静态局部变量只能在该函数中使用;静态局部变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));静态局部变量在函数调用结束后不自动释放,保留函数调用结束后的值;

全局变量:在函数外定义的变量称为全局变量;全局变量在静态存储区分配存储单元,在程序运行期间都不释放,在文件中的函数均可调用该全局变量,其他文件内的函数调用全局变量,需加extern声明;

静态全局变量:在函数外定义变量时,若加上static声明,则此变量为静态全局变量;静态全局变量在静态存储区分配存储单元,在程序运行期间都不释放,静态全局变量在编译时赋值(若在定义时未进行赋值处理,则默认赋值为0(对数值型变量)或空字符(对字符型变量));只能在当前文件中使用;

参考谭浩强的《C程序设计第二版》P180,可从三个方面对以上四种变量进行区分:

1.从作用域角度分,有局部变量和全局变量:

局部变量

自动变量(auto变量,函数结束后释放)

静态局部变量(函数结束后值保留)

全局变量

静态外部变量(只限本文件中使用)

外部变量(允许其他文件引用)

2.从变量的生存期分,有动态存储和静态存储两种,动态存储即在调用函数时临时分配单元,静态存储则是程序整个运行时间内都存在。

动态存储

形式参数(本函数内有效)

auto自动变量(本函数内有效)

register寄存器变量(本函数有效)

静态存储

静态局部变量(本函数内有效)

静态外部变量(本文件中有效)

外部变量(允许其他文件引用)

3.从变量的储存位置分

内存中静态存储区

静态局部变量

静态外部变量

外部变量

内存中动态存储区

auto自动变量和形式参数

CPU中的寄存器

寄存器变量

三.设计函数int *atoi(const char *str);

在联想的笔试题中看到这个题目,特意拿来练练手;

程序代码如下:

#include <stdio.h>

#include <assert.h>//使用断言

#include <ctype.h>//使用isspace()isdigit()函数的头文件

#include <math.h>

#define INT_MAX (int)((pow(2, sizeof(int) * 8)) / 2.0 - 1)

#include <stdio.h>

#include <assert.h>//使用断言

#include <ctype.h>//使用isspace()isdigit()函数的头文件

#include <math.h>

#define INT_MAX (int)((pow(2, sizeof(int) * 8)) / 2.0 - 1)

int myatoi(const char *string)

{

int flag = 1;

int result = 0;

assert(string != NULL);//string指向NULL,则判断非法调用myatoi()函数

//若字符串有空格或制表符,则跳过;

while (isspace(*string))

{

string++;

}

//获取字符串的'+','-'符号位;

if (*string=='+' || *string=='-')

{

flag = (*string == '-') ? -1 : 1;

string++;

}

//程序到这里,已经没有空格和'+','-'号了,若接下来的字符是数字,

//则计算出数字的大小,若不是数字,则不计算,result依旧为0;

while (*string!='\0' && isdigit(*string))

{

result = 10 * result + (*string++ - '0');

}

//判断最后结果是否溢出,若溢出则退出程序

if ((unsigned)result > INT_MAX)

{

printf("The Number Input is larger than INT_MAX%d\n", INT_MAX);

printf("exit!\n");

exit(1);

}

return (result * flag);

}

int main(void)

{

printf("%d\n", myatoi("+1234"));

printf("%d\n", myatoi("-2147483647"));

printf("%d\n", myatoi("1234"));

printf("%d\n", myatoi("adf 1234"));

}

此函数中

1.首先通过断言assert判断对myatoi()的调用是否合法;

2.判断字符串开头是否有空格或制表符(TAB),有则跳过;

3.若字符串第一个有效字符为’-‘,则flag-1,若为’+’,则flag1,若为其他字符,则判断此字符串为非数字字符串,result的最终值为0

4.将字符类型的数字转换成int类型的数字,

5.判断result是否越界,若越界,跳出程序,否则返回result*flag的值;

这道题主要考的是程序员的编程风格,虽说这个函数看上去很简单,但如果要考虑到程序的健壮性,正确定,可靠性,效率,易用性,可扩展性,可移植性等属性的话,程序编写起来就不简单了;

四.含参数的宏与函数的优缺点

无参的宏就用得多了,但带参数的宏呢?见过很多,但真正自己去编的几乎没有,今天,顺带把这个问题也搞清楚。

含参数的宏优点:

省去了函数调用的开销,运行效率高.

含参数的缺点:

由于宏本质上是字符串的替换,所有可能会由于一些参数的副作用导致得出

错误的结果.

:

#define max(a, b)( ((a) > (b)) ? (a) : (b) )

如果程序中出现这样的调用: max(a++, b);

将导致a被计算2,从而可能得到错误的结果,而函数调用不会出现这种问题.

另外,如果程序中有多次宏替换的话,可能导致代码体积变大.

函数调用的优点:

没有带参数宏可能导致的副作用,计算的正确性较宏更有保证.

函数调用的缺点:

函数调用需要一些参数,返回地址等入栈,出栈的开销,效率没有带参数的宏高.



分享到:
评论

相关推荐

    全局 局部变量以及static 变量区别

    - 当设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需考虑重入问题。 - 为了创建可重入的函数,应避免在函数中使用`static`变量。 - **特殊用途**: - 当函数返回值为指针类型时,通常使用...

    C++笔试题-面试

    - **全局变量**:存储在静态数据区,即使函数调用结束,其值仍然保留。 - **局部变量**:存储在栈中,随着函数调用的开始而创建,函数调用结束时自动销毁。 ### 平衡二叉树的概念 平衡二叉树是一种特殊的二叉搜索...

    20170615_第二阶段1,2,3宣讲会问题记录_杨力 包新泽1

    未解决的问题包括全局变量的内存分配时间、静态变量和全局变量的区别、内存对齐的原理、浮点数的存储和运算、`lea`指令的作用、`tlink`的工作过程、`double`类型的具体存储方式、结构体的传递和返回机制,以及空指针...

    Android面试常见问题

    2. 局部变量、静态变量、全局变量: - 局部变量:在方法内部定义,随着方法调用结束而释放。 - 静态变量:属于类级别,生命周期与类相同,不随对象创建和销毁而改变。 - 全局变量:在类的外部定义,随着程序运行...

    c++和操作系统面试题

    2. 全局变量和局部变量的区别:全局变量储存在静态数据区,局部变量在堆栈。 3. 平衡二叉树:平衡二叉树是一种特殊的二叉树,左右子树都是平衡二叉树且左右子树的深度差值的绝对值不大于 1。 4. 堆栈溢出:堆栈溢出...

    c++基础概念.doc

    1. 静态库和动态库的异同 静态库(Static Library)和动态库(Dynamic Library)是两种不同的库类型。静态库是在编译时将库文件编译成目标文件,然后链接到可执行文件中。动态库是在运行时加载到内存中的。静态库的...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar

    8.8 局部变量和全局变量 112 8.8.1 局部变量 113 8.8.2 全局变量 119 8.9 变量的存储类别 120 78.9.1 动态存储方式与静态动态存储方式 120 8.9.2 auto变量 120 8.9.3 用static 声明局部变量 121 8.9.4 register 变量...

    谭浩强C语言程序设计,C++程序设计,严蔚敏数据结构,高一凡数据结构算法分析与实现.rar )

    8.8 局部变量和全局变量 112 8.8.1 局部变量 113 8.8.2 全局变量 119 8.9 变量的存储类别 120 78.9.1 动态存储方式与静态动态存储方式 120 8.9.2 auto变量 120 8.9.3 用static 声明局部变量 121 8.9.4 register 变量...

    C++指针与内存管理.doc

    1. 静态存储区域分配:这部分内存主要包含全局变量和静态变量,它们在程序开始执行时分配,并在整个程序运行期间持续存在。 2. 栈上创建:函数内部的局部变量通常在栈上分配,当函数执行完毕,这些变量的内存会被...

    PHP内核探索:变量概述

    然而,由于`$bar`在函数内部被声明为局部变量,其改变不会影响到全局的`$bar`,这就是变量作用域的概念。 在PHP中,变量的作用域决定了变量在代码的哪些部分是可见的。通常有四种作用域: 1. 全局(global):在...

    信盈达c++培训资料

    资料中涵盖了函数的定义和使用、参数传递、返回值以及局部变量和全局变量的区分。 数据类型: C++的数据类型比C语言更为丰富,提供了布尔型变量、双字节宽字符类型wchar_t等。资料详细解释了基本数据类型的扩充、...

    c程序设计语言第二版 The C Programming Language secondedition

    - 讨论静态局部变量和静态外部变量的特性和用法。 - 解释静态存储期的概念。 7. **寄存器变量(4.7)** - 介绍寄存器变量的特点。 - 探讨其在提高程序性能方面的作用。 8. **块结构(4.8)** - 说明复合...

    谭浩强C++程序设计复习提纲.docx

    - 讨论变量的作用域,如局部变量和全局变量,以及静态变量的特性。 - 了解内联函数、默认参数函数和函数模板的概念。 5. **数组** - 熟悉一维数组和二维数组的声明、初始化以及数组元素的访问。 - 理解数组名...

    the C programming language

    - **静态变量**:解释静态局部变量与静态外部变量的特性。 - **寄存器变量**:探讨寄存器变量的概念及其使用限制。 - **块结构**:说明函数体与复合语句之间的关系。 - **初始化**:介绍变量与数组的不同初始化...

    范磊C++入门到精通全集下载.pdf

    9. **函数**:深入讲解函数的使用,包括函数的声明、定义、参数传递、返回值、局部变量和全局变量的概念。 10. **数据类型**:详细介绍C++中的各种数据类型,如布尔型(bool)、字符型(char)、双字节型(wchar_t...

    java的基础学习PPT

    此外,JavaScript的变量作用域和内存管理也有其独特之处,比如全局变量和局部变量的区别,以及垃圾回收机制。理解这些概念对于编写高效且无错的JavaScript代码至关重要。虽然这个PPT可能更适合初学者,但深入学习...

    Java面试测试题目2018张大成总结

    ### Java面试测试题目知识点...- Java中使用静态变量来模拟全局变量的行为,避免全局变量可能导致的问题。 #### 57. 如何将String类型转化成Number类型 - 使用`Integer.parseInt()`、`Double.parseDouble()`等方法。

    线程安全详解及相关实用技巧(附源码)

    纯代码函数不包含任何副作用,如修改全局变量或调用其他可能改变状态的函数,因此它们是可重入的。 (二) 使用了局部静态变量的函数,是不可重入的 局部静态变量在函数调用结束后不会被销毁,因此如果多个线程同时...

Global site tag (gtag.js) - Google Analytics