#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void fun01(int a)//此处的int a不同于主函数的int a,这个是属于fun01函数的
{
int b = a;
}
int main()
{
//变量的作用范围:从创建到所在函数结束
int a = 10;
//system("pause");
return EXIT_SUCCESS;
}
关于变量在函数中的创建先后:
void fun01(int a, int b, int c)
//创建的变量是在栈中创建的 存储顺序是从上到下存储的
{
printf("%p\n", &c);
printf("%p\n", &b);
printf("%p\n", &a);
//虽然地址时a的地址<b的地址<c的地址给人一种错觉
//实际上时先创建c在创建b最后在创建a
//全局变量 注意:和函数的先后有着关系,必须要放在使用变量函数的后面
作用在函数内
作用在整个项目中,前提实在使用的文件中进行声明
声明不会分配内存空间,定义会分配内存空间
在函数内部就是局部变量
在函数外部就是全局变量
int a = 100;
void fun01(int a,int b,int c)
{
a += 10;//20 来自主函数中a的值传递
printf("%d\n", a);
}
int main()
{
printf("%d\n", a);//打印的是全局变量
//变量的作用范围:从创建到所在函数结束
int a = 10;
fun01(a, a, a);
printf("%d\n", a);//打印主函数中a的值
//system("pause");
return EXIT_SUCCESS;
}
在创建另一个源文件时在另一个源文件只写上变量
必须声明(extern)在能使在主函数第一行上打印出值
前提是主函数先写上打印
声明变量就是可以使用这个变量
堆区内存分配和释放:
malloc()
#include <stdlib.h>
void * malloc(size_t size);
功能:在内存的动态储存区(堆区)中分配一块长度为size字节的连续区域,
用来存放类型说明符指定的类型,分配的内存空间内容不确定,一般使用
memset初始化
参数:
size:需要分配内存大小(单位:字节)
返回值:
成功:分配空间的初始地址
失败:NULL
静态(static)局部变量:只能被初始化一次,但可以被多次赋值
在加static之后的全局变量只能作用在它本身所在的这一个文件中
在函数声明时如果函数在主函数之上,则不用写声明,程序会自动声明;
当函数在主函数之下,则需要在主函数之上写下声明。
在使用vs时,可以把声明变量添加到头文件(h)中,头文件命名时,文件加上.h后缀
再在主函数上面添加#include "头文件名"//头文件名必须加上后缀.h
在头文件文件中加入:#pragma once
为了避免同一个文件被include多次,C/C++中有两种方式,一种是#ifndef方式,一种是#pragma once方式。
注意:static修饰后的函数仅仅作用与当前文件
不加static 函数函数可以作用于整个项目文件中
类型: 作用域: 生命周期:
局部变量int a=10; 从变量定义到函数结束 局部变量创建到函数的结束
全局变量int a=10; 整个项目文件中 程序创建到程序结束
static 局部变量 int a=10; 从变量定义到函数结束 程序创建到程序结束
static 全局变量 int a=10; 当前文件中 程序创建到程序结束
static void test() 当前文件中 程序创建到程序结束
void test () 整个项目文件中 程序创建到程序结束
内存四区模型:
代码区: 数据区:(静态区 全局区)
程序指令 初始化数据:
1.初始化的全局变量
2.初始化的静态全局变量
3.初始化的静态局部变量
未初始化数据:
1.未初始化的静态局部变量 默认初始值为0
2.未初始化的全局变量默认初始值为0
3.未初始化的静态全局变量默认初始值为0
字符串常量
define定义的常量存在于数据区
栈区: 堆区:
局部变量 音频文件
数组 视频文件
结构体 图像文件
指针 文本文件
枚举
函数形参
常量
在程序中创建大的数据应该放在堆区
栈区大小:
在不同的操作系统中系统分配
给每一个程序的栈区空间大小
不同
一般windows是1-8m不等
一般linux是1-16m不等
数据存储范围和内存存储范围
内存低地址
内存 代码区(部分公用)
从上到下 数据区(部分公用)//当同时访问多个数值是访问同一个内存
逐渐 //相当是减少内存
变高
( 堆大小和 堆区(堆区的大小是减去其他三部分的大小)
物理内存有关)
内存高地址 栈区(不是公用,可以被访问)
//栈区向上增长
堆空间的冒泡排序:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#define MAX 10
int main()
{
srand((unsigned int)time(NULL));//随机数种子
int *p = malloc(sizeof(int)* 10);
for (int i = 0; i <MAX; i++)
{
/**(p + i) = rand() % 50;*/
p[i] = rand() % 50;
}
printf("排序前打印\n");
for (int i = 0; i < MAX; i++)
{
printf("%d\n", p[i]);
}
for (int i = 0; i < MAX-1; i++)
{
for (int j = 0; j < MAX - i - 1; j++)
{
if (p[j]>p[j + 1])
{
int temp = p[j];
p[j] = p[j+1];
p[j + 1] = temp;
}
}
}
printf("排序后打印\n");
for (int i = 0; i < MAX; i++)
{
printf("%d\n", p[i]);
}
free(p);
system("pause");
return EXIT_SUCCESS;
}
内存操作函数:
memset(变量名,重置值,重置大小);
参数:目标,值,字节大小
memcpy(目标,源,字节大小);
//源就是要拷贝的内容,目标是要拷贝到哪里
注意:拷贝目标地址与源地址不仅能重叠,否则会发生错误
边读边写容易出错
strcpy是拷贝\0之前的内容
char arr[]={'h','e','l','l','o'}中没有\0,也可能乱码中有\0,但是\0
之前的内容hello还有乱码都会拷贝
memcpy和strcpy的区别:
1.函数参数不同
2.strcpy拷贝字符串 memcpy拷贝一块内存
3.拷贝结束标志不同,strcpy以\0结尾
memcpy以个数为结尾
求出三名学生 三门功课成绩 并排序 通过堆空间来实现
int main()
{
int **p=(int **)malloc(sizeof(int *)*3);
p[0]=(int *)malloc(sizeof(int)*3);
p[1]=(int *)malloc(sizeof(int)*3);
p[2]=(int *)malloc(sizeof(int)*3);
p[0][0]=90;
p[0][1]=80;
p[0][2]=70;
free(p[0]);
free(p[1]);
free(p[2]);
free(p);
return 0;
}