目录
存储类别说明符
自动变量(auto)
特征:自动存储期、块作用域、无链接。
块作用域、无链接:意味着只有在变量所在的块中,才能通过变量名访问块。
问题引入:块是什么?
1.在内层块中声明同名变量,内层块隐藏外层块定义。
#include<stdio.h>
int main()
{
auto int x = 30;
printf("1.x = %d %p\n", x, &x);
{
auto int x = 77;
printf("2.x = %d %p\n", x, &x);
}
printf("3.x = %d %p\n", x, &x);
while (x++ < 33)//递增的是原始的x(即x = 30)
{
int x = 100;
x++;
printf("4.x = %d %p\n", x, &x);
}
printf("5.x = %d %p\n", x, &x);
return 0;
}
//1.x = 30 000000969EAFF8C4
//2.x = 77 000000969EAFF8E4
//3.x = 30 000000969EAFF8C4
//4.x = 101 000000969EAFF904
//4.x = 101 000000969EAFF904
//4.x = 101 000000969EAFF904
//5.x = 34 000000969EAFF8C4
//-------------------------
//1.3.5的地址均为000000E8B059FCE4:说明原始的x没有消失。
//4.说明while每轮迭代结束,新x变量就会被销毁。
#include<stdio.h>
int main()
{
int key = 0;
int i = 0;
while (i < 3)
{
key = 0;
if (i == 2)
{
key = 1;
}
printf("%d\n", key);
i++;
}
printf("%d\n", key);
return 0;
}
//0 0 1 1
#include<stdio.h>
int main()
{
int key = 0;
int i = 0;
while (i < 3)
{
int key = 0;
if (i == 2)
{
key = 1;
}
printf("%d\n", key);
i++;
}
printf("%d\n", key);
return 0;
}
//0 0 1 0
寄存器变变量(register)
块作用域的静态变量(static)
定义:该变量在内存中原地不动,而非值不变。
特征:静态存储期、块作用域、无链接。
问题引入:静态变量和普通变量本质的区别是初始化的时点。
函数体内的fade变量:每次调用都会被初始化。
static 修饰的stay变量:只在编译整个程序时才被初始化一次。
#include<stdio.h>
void trystatic(void);
int main()
{
int count;
for (count = 1; count < 4; count++)
{
printf("count = %d ", count);
trystatic();
}
return 0;
}
void trystatic(void)
{
int fade = 1;
static int stay = 1;
printf("fade = %d stay = %d\n", fade++, stay++);
}
//count = 1 fade = 1 stay = 1
//count = 2 fade = 1 stay = 2
//count = 3 fade = 1 stay = 3
//-------------------------
//fade和static修饰的stay的值变化
扩展结论:静态变量和外部变量在程序被载入内存时已执行完毕。
外部链接的静态变量(external)
特征:静态存储期、文件作用域、外部链接。
global.c文件:
int global_a;//未初始化的外部变量:自动初始化为0。(和自动变量差异)
int global_b = 10;
int global_c = 3 + 8;
main.c文件:
#include<stdio.h>
extern int global_a;
extern int global_b;
extern int global_c;
int main()
{
printf("global_a = %d\n", global_a);
printf("global_b = %d\n", global_b);
printf("global_c = %d\n", global_c);
return 0;
}
//global_a = 0
//global_b = 10
//global_c = 11
内存分配
概念回顾
概念:所有程序都必须预留足够的内存来储存程序使用的数据。
回顾:静态数据在程序载入时分配内存,自动数据在程序执行块时分配内存。
自动分配的内存:
#include<stdio.h>
int main()
{
float a;
char place[] = "hello world";
char place2[100];
return 0;
}
动态分配内存
头文件:#include <stdlib.h>
重要特性:动态分配内存的存储期:从malloc()分配内存到free()释放内存为止。
问题引入:当fun函数执行完毕后,a的内存空间会被释放,p指向了一个不再有效的地址。
#include<stdio.h>
int* fun();
int main()
{
int* p = NULL;
p = fun();
printf("%d\n", *p);
return 0;
}
int* fun()
{
int a = 10;
return &a;
}
malloc函数
作用:找到合适的空闲内存块。
语法:void * malloc(<所需内存的字节数>);
返回:空闲内存块的首字节地址。
free函数
作用:释放malloc函数分配的内存。
语法:void free(<malloc返回的地址>);
回顾问题:
利用malloc和free的重要特性。
#include<stdio.h>
int* fun();
int main()
{
int* p = NULL;
p = fun();
printf("%d\n", *p);
free(p);
return 0;
}
int* fun()
{
int* p = NULL;
p = malloc(sizeof(int));
if (NULL == p)
{
printf("malloc failed!\n");
return NULL;
}
*p = 10;
return p;
}