C语言第九回合:作用域和存储类型
来源:互联网 发布:手机免费记账软件 编辑:程序博客网 时间:2024/05/16 05:37
C语言第九回合:作用域和存储类型
【学习目标】
1. 局部变量
2. 全局变量
3. 存储类型
4. 内存
A: 局部变量
局部变量也称为内部变量。局部变量是在函数内定义说明。
作用域:仅在声明的函数或复合语句内内,有效区也在函数或复合语句内。
B: 全局变量
全局变量也称为外部变量,是在函数外定义的变量。
作用域:整个与程序文件
PS: 局部变量和全局变量是按照作用域来划分的。
#include <stdio.h> int numuber; //全局变量 //作用范围为整个本文件 //定义print函数.无参数,也无返回值void print( void ){ float score; //局部变量 //作用范围为print函数内 return ; //作为print的结束标志}int main( void ){ //局部变量score可以同名 float score; //局部变量 //作用范围为main函数内 print(); return 0; }
C: auto的使用
在函数或复合语句内部,如不声明变量为static存储类型,则就称该变量为auto变量
PS:C 语言规定,关键字auto可以省略(默认条件下都是auto)。
D: static的使用
(1)修饰变量(存在内存的静态区)
(a) 静态局部变量:是用static修饰的局部变量。
PS:静态局部变量保存在静态数据区,生命周期和程序相同。特别注意,静态局部变量只能在被定义的函数内使用,保存的只一直存在!
(b) 静态全局变量:是用static修饰的全局变量。
PS:静态全局变量只能作用域声明的文件中,不能被其他文件引用。
( 2)修饰函数(静态函数,又称内部函数)
在函数前加上static,就成为静态函数。这里的’static’意思不是指存储方式,而是指对函数的作用仅局限于本文件
//功能:观察静态局部变量#include <stdio.h> //静态函数定义//定义静态的print函数,作用范围只能在本文本中//返回值为void,参数也为voidstatic void print( void ){ static intnum= 0; //静态局部变量的定义 num++; //num=num+ 1; printf("%d\n", num ); return; //返回类型为void,所以不返回什么。这样写可以提高可读性} int main( void ){ //auto变量的定义 floatscore= 99.0; //等同于 autofloat score= 99.0; //第一次调用print函数 printf("第一次调用后,num的值: " ); print(); //第二次调用print函数 printf("第二次调用后, num的值: " ); print(); return 0; }
运行结果:
我们会发现,num的值是在前一次调用后的值基础上自加的。
E: register变量(寄存器变量)
用register修饰的变量,就是register变量。register:这个关键字请求编译器尽可能的将变量存在CPU内部寄存器中而不是通过内存寻址访问以提高效率。(是尽可能,但不是绝对,因为CPU的寄存器个数有限!!)
PS: 虽然寄存器的速度非常快,但是使用register修饰符也有些限制的:register变量必须是能被CPU寄存器所接受的类型。意味着register变量必须是一个单个的值,并且其长度应小于或等于整型的长度。而且 register变量可能不存放在内存中,所以不能用取址运算符“&”来获取register变量的地址。
F: extern的使用
关键字extern可以置于变量或者函数前,以标示变量或者函数的定义在别的文件中
【扩展知识】
在看下面程序时,先看看这点知识。这是在自定义头文件中经常使用的
//(整体作用)防止头文件被重复引用 #ifndef TEXTC_H #define TEXTC_H //内容。。。 #endif
testc.h文件中【注意:这是自定义的头文件】
//textc.h文件//extern的使用 #ifndef TEXTC_H //(整体作用)防止头文件被重复引用 #define TEXTC_H int number= 100;float score= 99.9;char ch= 'A'; #endif
main.c文件
#include <stdio.h>#include "textc.h" //自定义的头文件。打“”的意思是先在当前文件目录下查找头文件 int main( void ){ extern int number; //声明number已定义。下同。 extern float score; extern char ch; printf("number= %d\n", number ); printf( " score= %.1f\n", score ); printf( " ch= %c\n", ch ); return0;}
main.c必须与testc.h一起!
运行结果:
G:内存
内存可以分为三个部分:堆、栈和静态区【堆就是堆,栈就是栈】
- 堆:由malloc系列函数分配的内存。其生命周期由free或delete决定。 特点:使用灵活,空间比较大,但容易出错。
- 栈:保存局部变量。栈上的内容只在函数内存在,当函数运行结束,就会自行销毁。 特点:效率高,但使用大小有限。
- 静态区:保存自动全局变量和static变量。静态区的内容在整个程序的生命周期内都存在。
//堆、栈和静态区的程序解释#include <stdio.h>#include <stdlib.h> //for函数malloc()和exit()提供原函数 //定义内存分配函数Malloc,无参数也无返回值void Malloc( void ){ intnum= 100; //局部变量,存储在栈中,函数一结束就销毁内存 char*str; //定义一个char类型的指针变量 //malloc函数的使用,分配100个字节空间 str=( void* )malloc( num* sizeof( char ) ); //强制类型的转换 if(str== NULL ) { printf("内存分配失败\n" ); exit(1 ); //程序退出 } //str动态内存分配成功,存储在堆中。 return ;} //定义静态全局函数static int number= 1 ; //存储在静态区,只有当程序结束时才会被销毁 int main( void ){ floatscore= 99.9; //局部变量,存储在栈中 return 0; }
H:内存分配函数
【扩展知识】在使用这些函数前必须”科普”一下
1. size_t就是unsignedint 的别名,因为大小不允许为负数。
2. void *(空类型指针)可以强制换为任何类型指针,但不允许逆操作!
3. sizeof()是求字节大小,但不可以求动态分配的内存。
4. void perror ( const char * str);打印错误信息
( 1 ) malloc的使用
原型:void* malloc (size_t size);
分配size大小的字节内存,并返回指向内存开始的指针
//malloc使用例子#include <stdio.h>#include <stdlib.h> //malloc,free.exit int main( void ){ unsignedint num; //定义无符号int型变量 char*str; //定义char类型指针变量str num=100; //赋值语句,把100赋值给num //为str分配100个字节 str=( char* )malloc( num* sizeof( char ) ); if(str== NULL ) // 检测是否分配成功 { perror( "内存分配失败\n"); exit( 1 ); //退出程序 } else { printf("内存分配成功\n" ); } free(str );//释放分配的内存 str=NULL; //把NULL赋值给str,防止成为野指针 return 0; }
(2 ) calloc的使用
原型:void* calloc (size_t num, size_t size); //size为类型大小,num为个数
分配num* size大小的内存空间,并初始化为0,再返回指向内存开始的指针
//calloc的使用#include <stdio.h>#include <stdlib.h> int main( void ){ unsignedint num; inti; int*array; //定义int型指针 num=10 ; //分配num*sizeof( int )大小的内存,并全初始化为0 array=( int * )calloc( num, sizeof( int ) ); if(array== NULL ) { perror("内存分配失败\n" ); exit(1 ); //退出程序 } else { printf("内存分配成功\n" ); for(i= 0; i< num; i++ ) { printf("%d ", array[ i ] ); //可以同过数组的访问方式范围元素 } } //释放内存 free(array ); array=NULL; return 0; }
运行结果:
内存分配成功
0 0 0 0 0 0 0 0 0 0
(3 ) realloc的使用
原型:void* realloc (void* ptr, size_t size);
改变指针ptr的内存大小
//realloc的使用#include <stdio.h>#include <stdlib.h> // malloc realloc,free,exit int main( void ){ unsignedint num= 5; inti= 0; int*array= NULL; int*more_array= NULL; array=( int * )calloc( num, sizeof( int ) ); if(array== NULL ) { perror("内存分配失败\n" ); exit(1 ); } printf("calloc:内存分配成功\n"); //给数组array赋值 for( i= 0; i< num; i++ ) { array[i ]= i; } printf("再次分配内存前: " ); for(i= 0; i< num; i++ ) { printf("%d ", array[ i ] ); } //realloc从新分配内存 num=10; more_array=realloc( array, num* sizeof( int ) ); if(array== NULL ) { perror("内存分配失败\n" ); exit(1 ); } printf("\n\nrealloc:内存分配成功\n" ); //给数组more_array赋值 for(i= 0; i< num; i++ ) { array[i ]= i; } printf("再次分配内存后: " ); for(i= 0; i< num; i++ ) { printf("%d ", array[ i ] ); } free(array ); array=NULL; return0;}
运行结果:
calloc:内存分配成功
再次分配内存前:0 1 2 3 4
realloc:内存分配成功
再次分配内存后:0 1 2 3 4 5 6 7 8 9
(4 ) free的使用
原型: void free (void* ptr);
【指尖的微笑】错误在所难免,希望得到大家的指正^-^
本文章皆有半个读书人(http://www.bangedushuren.cn/)的技术部LearnCoding(http://it.bangedushuren.cn/)原创,转载请注明
- C语言第九回合:作用域和存储类型
- 【C语言的学习】第九回合:作用域和存储类型大集合
- C语言提高之——C语言中的作用域、链接属性和存储类型
- C语言常量以及变量类型,存储类型和作用域
- C语言作用域、存储类型、链接类型、static关键字
- C语言入门教程 (十二) 变量的作用域和存储类型
- C语言入门(十四)变量的作用域和存储类型
- C语言中变量的作用域与存储类型
- C/C+++的中变量作用域和存储类型
- C作用域、链接属性、存储类型和初始化
- C++Primer Plus 第九章-存储持续性、作用域和链接性
- C语言中变量存储和作用域
- C语言变量作用域、连接和存储时期
- C语言变量类型和存储分配
- C语言学习笔记——数据的类型、存储、作用域,运算符,表达式
- C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型(上)
- C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型(下)
- C语言中标识符的作用域、命名空间、链接属性、生命周期、存储类型(上)
- 多项求和
- 外壳编程常用知识点
- google加速hosts,不能翻墙
- Budgie Desktop v8 发布,改进菜单和面板
- js-jQuery对象与dom对象相互转换(一)
- C语言第九回合:作用域和存储类型
- 核函数
- cheap wholesale nfl nike jerseys
- 流程中穿透租户启动流程模型业务应用
- 设计模式之问题集锦(一)
- 使用“万能数据库查询分析器”的Windows 7、Windows 8、Windows 10的用户须知
- 各种布局跑马灯按钮控件
- iOS不允许设备休眠
- 漫谈程序员系列:让程序员蛋疼的那些事儿