C语言:作用域与内存

局部变量

概念:定义在函数内部的变量
作用域:从定义位置开始,到包裹该变量的第一个右大括号结束

全局变量

概念:定义在函数外部的变量
作用域:从定义位置开始,默认到文件结束位置,其他文件如果想使用,可以使用声明的方式将作用域导出

1.extern修饰的全局变量可以使用其他文件的定义
2.全局变量的默认值为0

//test15.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int a = 10;

int main15(void)
{
	printf("test15->a=%d\n", a);
	return 0;
}

//test15-extern.c
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

extern int a;

int main(void)
{
	printf("test15-extern->a=%d\n", a);
	return 0;
}
静态全局变量

static int a = 10;//定义在函数外
作用域:被限制在本文件内部,不允许其他文件通过extern导入

静态局部变量

static int a = 10;//定义在函数内
特性:静态局部变量只定义一次,函数调用结束后静态局部变量没有销毁,下一次调用函数时依旧可以使用
作用域:同局部变量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

static int a = 10;

void test1501() {
	static int b = 10;
	printf("b=%d\n", b++);
}

int main(void)
{
	//printf("test15->a=%d\n", a);
	for (int i = 0; i < 5; i++) {
		test1501();
	}
	return 0;
}
运行结果:
b=10
b=11
b=12
b=13
b=14
全局函数

定义语法:函数原型+函数体

static函数

定义语法:static+函数原型+函数体
作用域:只能在本文件内部使用,其他文件即使声明也无法使用

生命周期
  • 局部变量:从变量定义开始到函数调用完成结束
  • 全局变量:从代码加载到内存(程序启动)开始,到程序终止结束
  • static局部变量:同全局变量
  • static全局变量:同全局变量
  • 全局函数:同全局变量
  • 静态static函数:同全局变量
命名冲突就近原则
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
static int a = 10;

int main(void)
{
	int a = 20;
	printf("test15->a=%d\n", a);//输出20
	return 0;
}
内存
  • 程序运行时使用到的内存区域按如下4区划分
    代码段:text段,程序源代码(二进制形式)
    数据段:只读数据段.rodata段;初始化数据段.data段;未初始化数据段.bss段
    stack:栈,在栈上开辟栈帧
    heap:堆,给用户自定义数据提供空间
    linux内存模型
  • 堆空间申请和使用
  1. 开辟heap空间
    void* malloc(size_t size);
    功能:申请size大小的空间,返回实际申请到的内存空间首地址

  2. 释放heap空间
    void free(void *ptr);

1.malloc申请的空间是连续的,可以当做数组使用
2.free后的内存里数据会清空,但是指针没有失效,依旧指向申请到的内存空间首地址,所以通常free后可以手动将指针置为NULL
3.free的地址必须是malloc申请返回的地址,否则会出错
4.如果malloc之后的地址一定会变化,可以使用临时变量保存地址

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	//int arr[1000000] = { 10,20,40 };
	//申请堆内存,堆空间大于栈空间,可以使用的内存更多
	int *p = (int*)malloc(sizeof(int) * 1000000);
	if (p == NULL) {
		printf("malloc error\n");
		return -1;
	}
	for (size_t i = 0; i < 10; i++)
	{
		p[i] = i + 10;
	}
	for (size_t i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	putchar('\n');
	//释放申请的堆内存
	free(p);
	p=NULL;
	return 0;
}
  1. 二级malloc
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
	//申请空间
	int** p = malloc(sizeof(int*)*3);
	for (size_t i = 0; i < 3; i++)
	{
		p[i]=malloc(sizeof(int) * 5);
	}
	//写空间
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 5; j++)
		{
			p[i][j] = i+j;
		}
	}
	//读空间
	for (size_t i = 0; i < 3; i++)
	{
		for (size_t j = 0; j < 5; j++)
		{
			printf("%d ", *(*(p+i)+j));
		}
		printf("\n");
	}
	//释放空间
	for (size_t i = 0; i < 3; i++)
	{
		free(p[i]);
		p[i] = NULL;
	}
	free(p);
	p = NULL;
	return 0;
}
  • 内存操作函数

void* memset(void* buff,int c,size_t n)
函数作用:按字节重置内存数据

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void)
{
	char* p = (char*)malloc(sizeof(char) * 10);
	memset(p, 65, 10);
	for (size_t i = 0; i < 10; i++)
	{
		printf("%c ", p[i]);
	}
	printf("\n");
	free(p);
	return 0;
}

void* memcpy(void* dest,const void* src,size_t n);
函数作用:拷贝src的n个字节到dest

strcpy与memcpy的区别:
1.strcpy拷贝字符串,memcpy可以拷贝一块内存
2.拷贝结束标识不同,strcpy以’\0’结束,memcpy按字节数数拷贝

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	int* p = malloc(sizeof(int) * 10);
	memcpy(p, arr, 40);
	for (size_t i = 0; i < 10; i++)
	{
		printf("%d ", p[i]);
	}
	printf("\n");
	free(p);
	return 0;
}

void* memmove(void* dest,const void* src,size_t n);
函数功能:和memcpy一样,区别在于dest和src所指内存空间重叠时,memmove效率比memcpy低,memmove要使用额外空间存储重叠区域

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
	int arr[10] = {1,2,3,4,5,6,7,8,9,0};
	memmove(&arr[5], arr, 20);
	for (size_t i = 0; i < 10; i++)
	{
		printf("%d ", arr[i]);
	}
	return 0;
}

int memcmp(const void* buf1, const void* buf2,size_t n)
函数作用:比较buf1和buf2的前n个字节,前n个字节相等返回0,buf1>buf2返回1,buf1<buf2返回-1

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
	int arr1[10] = {1,2,3,4,5,6,7,8,9,0};
	int arr2[5] = {1,2,3,4,7};
	int val = memcmp(arr1, arr2,20);
	printf("%d", val);
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值