#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();
}