内存学习

#include<stdio.h>
#include<stdlib.h>

void main()
{
	void *p1 = malloc(10);//p1,p2在栈上
	void *p2 = malloc(20);
	printf("%p,%p\n", &p1, &p2);//地址在栈上
	printf("%p,%p\n", p1, p2);//堆区
	getchar();
}


#include<stdio.h>

void gogogo()
{
	printf("AAAA\n\n\n\n");
}

void main1()
{
	printf("%p\n",gogogo);//函数名储存函数的地址
	gogogo();//直接调用
	void(*p)() = gogogo;//函数指针
	p();//间接调用

	getchar();
}
void main()
{
	char*p = "ABCDEFG";
	printf("%d,%d\n", sizeof(p), sizeof("ABCDEFG"));//4,8
	printf("%p\n",&p);//查看指针变量的地址
	printf("%p\n", p);//查看字符串的地址
	//*p = 'a';//访问冲突,常量字符串在代码区,代码区只能读

	getchar();
}



#include<stdio.h>
#include<stdlib.h>
#include<Windows.h>

int num = 100;
void add(int x);
void add(int x)
{
	num += x;
}
void msg()
{
	MessageBoxA(0, "1", "2", 0);
}
void main()
{
	printf("main=%p,msg=%p,add=%p\n", add,msg,add);//在dll文件里声明指针函数指向add
	while (1)
	{
		printf("%d\n",num);
		Sleep(5000);
	}
}

#include<stdio.h>
#include<stdlib.h>

_declspec(dllexport) void go()
{
	//int(*p1)(int a) = 00F6111D;//需要转换类型
	//int *p1;//把p去掉就是他的类型int *
	//int(*p1)(int a)的类型就是把p1去掉int(*)(int a)
	//函数指针类型必须一致,否则无法调用成功
	//间接调用的方式调用函数,根据地址来调用
	void(*p1)(int a) = (void(*)(int a))0x1C111D;
	p1(10);
	void(*p2)() = (void(*)())0x2c111d;
	p2();
}

第二部分

-------------const----------------------
#include<stdio.h>
#include<stdlib.h>

//定义常量的两种方法
#define N 10  //CPU产生,没有地址
//const是伪常量,限定编译器尽量不修改
const int num = 10;

void main1()
{
	//printf("%p\n",&N);//不能取地址
	printf("%p\n", &num);//可以取地址
	//N=3;//常量不可被再赋值
	//num=3;//常量不可被再赋值
	//int date[N];//可以
	//int date[num];//报错,表达式必须含有常量值
	getchar();
}

void main()
{
	const int number = 10;
	const int *p1 = &number;//创建指针,指向const int
	int *p2 = (int *)p1;//类型转换
	*p2 = 123;
	printf("%d\n",number);//123,const被修改
	//const避免直接赋值的修改,不能避免间接赋值的修改

	getchar();
}

------------全局变量和局部变量----------------------
#include<stdio.h>
#include<stdlib.h>

int a = 10;//全局变量,可以跨文件使用
void test()
{
	int b = 2;//在栈上,用完就回收了
	a = 3;//可以访问
}

void main1()
{
	//b = 3;//未定义b
	a = 4;//可以访问
}

//定义只能有一个,声明可以多个
int e = 10;
//int e = 10;//不可以,全局变量,声明+赋值=定义
int f;
int f;//没有问题,声明
int f = 10;//定义

void main()
{
	int c = 10;
	//int c = 10;//重复定义

	int d;
	//int d;//不可以,对于局部变量来说,无论是否赋值,都是定义
}

-----------跨文件全局变量-----------------
第一个文件move.c
int b = 562;

第二个文件main.c
#include<stdio.h>
#include<stdlib.h>

int a;
int a;
int a;//没有定义会把最后一个声明当做定义初始化为0,编译器的优化机制
int b;
//如果在另外一个文件里定义了b,这里也会按照定义的值,需要多个文件里通信的时候使用
//全局变量会一直存在于静态区,同样不可以重复定义

void main()
{
	printf("%d\n",a);//0
	printf("%d\n", b);//562

	getchar();
}

-------静态区和全局变量--------------------
#include<stdio.h>
#include<stdlib.h>

int num = 10;//静态区
//静态区与程序共存亡,静态区分配优先于main函数
//栈区反复回收,反复释放
void test()
{
	int date = 3;//栈区
	printf("%p,%p\n", &date, &num);

	num = 156;

	date = 256;

	printf("\n");
}

void main()
{
	test();
	printf("\n");

	test();
	printf("\n");
}

---------静态变量----------------

局部static

#include<stdio.h>

static int num = 100;//static限定只能在本c文件里使用

void main1()
{
	for (int i = 0; i < 10; i++)
	{
		int a = 10;//用完就回收
		static int b = 10;//与程序共存亡,静态区部变量,编译的时候就初始化了
		a += 1;
		b += 1;
		printf("%d,%d\n",a,b);
	}

	getchar();
}

//static作用:避免变量被意外污染
void main2()//意外修改
{
	int res = 0;
	for (int i = 1; i <= 100; i++)
	{
		res += i;	
	}
	res = 10;//可能的意外修改
	printf("%d\n", res);//得不到5050,

	getchar();
}
void main3()//不会被意外修改
{
	static int res = 0;//只会初始化一次
	for (int i = 1; i <= 100; i++)
	{		
		res += i;
	}
	//res = 10;//报错,不会被意外修改
	printf("%d\n", res);//5050

	getchar();
}


全局static

#include<stdio.h>

int num;
void main4()
{
	printf("%d\n",num);//在局部static.c里声明的static int num = 100,这里结果是0,而不是100

	getchar();
}

void main()
{
	int a = 4;
	printf("%d,%d",a,++a);//参数压栈的顺序是从右到左,++a,先自增再引用,所以打印结果是5,5

	getchar();
}








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值