数据结构1
内存空间划分
一个进程启动后,系统会为该进程分配4G内存空间。
其中0-3G是用户空间,主要是程序员写代码的操作部分。
3-4G主要是内核空间,主要是底层驱动部分。
其中0-3G的用户空间又划分为栈区,堆区,静态区
静态区又划分为4个段:bss段,data段,ro段,txt段
所有进程共享3-4G的内核空间,每个进程会独立拥有0-3G的用户空间
应用层主要操作0-3G用户空间,底层主要操作3-4G的内核空间
栈区特点
计算机自动申请和释放空
栈区存放数据的特点:先进后出,后进先出(FILO --->first in last out)
先定义的变量后申请内存,后定义的变量先申请内存
例:
int a //最后给a申请变量
int b //再给b申请变量
int c //先给c申请变量
栈区对数据申请空间的先后顺序:从大到小
堆区特点
程序员手动申请和释放空
堆区存放数据的特点:先进先出,后进后出
先定义的变量先申请内存,后定义的变量后申请内存
例:
int *p1=(int *)malloc(sizeof(int)); //先对p1申请内存空间
int *p2=(int *)malloc(sizeof(int)); //后对p2申请内存空间
栈区对数据申请空间的先后顺序:从小到大
动态内存分配和回收(在堆区申请空间,释放空间)
在C语言中使用malloc函数申请堆区空间,使用free函数释放堆区空间
malloc函数
功能:申请堆区空间
格式:
void *malloc(size_t size);
*需要头文件: #include <stdlib.h>
函数返回值:void * ,使用时需要强制转换
函数名:malloc
参数:申请空间的字节大小,必须以字节为单位,可以借助于sizeof()运算符
例:
单个申请:int *p1=(int *)malloc(sizeof(int));--->int *p1=(int *)malloc(4);
连续申请:int *p2=(int *)malloc(sizeof(int)*3);
错误案例:
int *p1=(int *)malloc(int); //不能直接用int
free函数
功能:释放堆区空间
只申请空间但不释放内存会导致内存泄露
在合适的位置释放内存空间即可避免内存泄漏
格式:
free [options]
*需要头文件: #include <stdlib.h>
函数返回值:无viod
函数名:free
参数:要释放的指针(指针存储了堆区空间)
例:
单个释放:free(p1);
连续释放:free(p2);
经过free释放空间后,p1,p2会变为野指针(指向的空间被释放,指向不存在)
例:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(int argc, const char *argv[])
{
int* p1=(int *)malloc(sizeof(int)); //在堆区申请列四个字节大小的空间,并将首地址赋值给p1
printf("%d\n",*p1);
*p1=100;
printf("%d\n",*p1);
int* p2=(int *)malloc(sizeof(int)*5); //在堆区申请五个四字节大小的空间,并将首地址赋值给p2
for(int j=0;j<5;j++)
{
*(p2+j)=j*2;
}
for(int i=0;i<5;i++)
{
printf("%d",*(p2+i));
}
putchar(10);
free(p1);
free(p2);
//为了避免野指针,要将指针置空
p1=NULL;
p2=NULL;
return 0;
}
练习:
在堆区空间连续申请5个int类型大小空间,用来存放从终端输入的5个学生成绩,然后显示5个学生成绩,再将学生成绩升序排序,排序后,再次显示学生成绩。显示和排序分别用函数完成
要求:用malloc和free完成
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void fun(int* q)
{
printf("成绩展示\n");
for(int i=0;i<5;i++)
{
printf("%d ",*(q+i));
}
putchar(10);
}
void pai(int *o)
{
for(int i=1;i<5;i++)
{
for (int j=0;j<5-i;j++)
{
if (*(o+j)>*(o+j+1))
{
int t;
t=*(o+j);
*(o+j)=*(o+j+1);
*(o+j+1)=t;
}
}
}
printf("排序完展示\n");
for(int q=0;q<5;q++)
{
printf("%d ",*(o+q));
}
putchar(10);
}
int main(int argc, const char *argv[])
{
int num[5];
printf("输入成绩\n");
for(int I=0;I<5;I++)
{
scanf("%d",&num[I]);
}
int* p=(int *)malloc(sizeof(int)*5); //在堆区申请五个四字节大小的空间,并将地址赋值给p2
for(int j=0;j<5;j++)
{
*(p+j)=num[j];
}
fun(p);
pai(p);
free(p);
//为了避免野指针,要将指针置空
p=NULL;
return 0;
}
野指针:
- 未初始化的指针
- 释放内存后未置空的指
- 指向数组的指针,当越界访问时,该指针为野指针
- 指针指向函数的返回值(函数调用时,分配空间,函数结束时,释放地址)
值传递,地址传递,值返回,地址返回
左值:既可以放在等号左边,也可以放在等号右边,有地址空间(变量,堆区空间)
右值:只能放在等号右边,没有地址空间(常量,临时值,表达式的运算结果),右值不可改变
值传递:将实参传递给形参的过程,将实参的数据复制一份给形参,所以形参的改变,不影响实参
地址传递:将实参数据的地址传递给形参的过程,形参可以是指针也可以是数组进行接收,所以形参的改变,可以改变实参
值返回:将一个数据返回,该函数的返回值,只能作为右值(值不可改变)
地址返回:将一个数据的地址返回(保证数据的生命周期要足够长),该函数的返回值可以作为左值
const
功能:const修饰的变量为常变量(只读变量),变量值不可变
const修饰的全局变量在静态区的ro段,const修饰的局部变量在栈区
const必须在定义时初始化
const int a=10; ---> int const a=10;
int const*p=&a; //表示指针的指向可以改变,但对应的值不可以改变(指针常量)
int *const p=&a; //表示指针的指向不可改变,但对应的值可以改变(常量指针)
int const * const p=&a; //表示指针的指向及其对应的值均不可改变
错误示范:int *p=&a; //不能直接使用指针指向常变量
类型重定义typedef
功能:给已有的数据类型重新命名,可以使代码简单易懂
格式:
typedef 数据类型 新名; //用新名替换原来的变量名
typedef int A; //普通类型重定义格式
typedef int *D [5]; //构造类型重定义格式
宏定义define
普通宏的定义
- #define:固定,预处理命令
- 宏名:满足c语言命名规范(由数字,字母,下划线组成;不可以是关键字;不可以是数字开头;见名知意,区分大小写)
一般宏名大写:宏大写,变量小写,函数名驼峰/下划线
宏---MAX 变量---max 函数---Max
- 宏体:默认是字符串类型
- 宏:只替换不做计算,不做正确性检测
- 宏只发生在预处理阶段
带参宏的定义
#define MAX(x,y) x>y?x:y
练习
在堆区中申请两个长度为32的空间,实现两个字符串的比较(非函数实现)
定义函数,在堆区中申请空间,两个申请,主函数需要调用两次
定义函数,实现字符串的输入
void input(char *p)
调用函数实现字符串比较,在主函数中输出大小
int my_strcmp(const char *s1,const char *s2)
定义函数,释放空间
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
char *my_apply(int n)
{
char *p=(char *)malloc(n);
if(NULL==p)
return NULL;
else
return p;
}
void my_gets(char *p)
{
gets(p);
}
int my_strcmp(const char *s1,const char *s2)
{
int i=0;
while(*(s1+i)==*(s2+i))
{
if (0==*(s1+i))
break;
i++;
}
int sub=*(s1+i)-*(s2+i);
return sub;
}
void my_free(char *p)
{
free(p);
}
int main(int argc, const char *argv[])
{
char *p1=my_apply(32);
char *p2=my_apply(32);
my_gets(p1);
my_gets(p2);
int sub=my_strcmp(p1,p2);
if(sub>0)
printf("p1>p2\n");
else if(sub<0)
printf("p1<p2\n");
else if(0==sub)
{
printf("p1=p2\n");
}
my_free(p1);
my_free(p2);
return 0;
}
原文地址:https://blog.csdn.net/qq_57106106/article/details/140633867
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!