C语言知识点小结 | 指针 数组 结构体 堆栈 内存分配

不掌握指针就是没有掌握C的精华

地址指向该变量单元,地址即指针

在C/C++语言中定义一个指针,就是在栈区开辟一个内存空间用来存放它指向的内存地址,然后给指针赋值,就是把地址值赋值给刚才开辟的内存空间,然后通过访问该内存中的地址值来间接访问该地址下存放的数据。

指针可以有指针吗?

有。指针可以指向一份普通类型的数据,例如 int、double、char 等,也可以指向一份指针类型的数据,例如 int *、double *、char * 等。

如果一个指针指向的是另外一个指针,我们就称它为二级指针,或者指向指针的指针。

数组和指针的联系

通过指针可以引用数组,
指针可以看作快捷方式,数组可以看做是存有数据的文件夹。访问指针将会通过地址带领你找到并操作真实的文件夹,访问数组时则是直接找到并操作文件夹。

数组只是定义在栈区的一个连续变量,它的首地址就是一个指针。

C语言把内存划分成四个区,它把一般的变量和数组等存在于内存中的栈区,所以数组在C语言的定义中只是一组同类型的普通变量,即使这个变量有可能是指针。所以他的作用比指针小的很多,而指针可以指向任何区的任何数据,所以就会觉得指针和数组名很像,但是必须要注意的是,数组名只是指针中的一种,它是指针中只指向栈区的且指针的移动范围是有限的,即数组长度。而且数组在定义之初就已经有了自己的内存,一般的指针如果未指向某一个内存块时,它是没有自己的内存的,即所谓的野指针。

C与C++的区别

C++面向对象的语言,C是面向过程的结构化编程语言

C++具有 封装、继承、多态的特性

C++增加许多类型安全的功能,如强制类型转换

C++支持范式编程,如模板类、函数模块等

面向对象VS面向过程

面向过程是一种以事件为中心的编程思想,编程的时候把解决问题的步骤分析出来,然后用函数把这些步骤实现,在一步一步的具体步骤中再按顺序调用函数。

面向对象是把要解决的问题分解成各个对象,建立对象的目的不是为了完成一个步骤,而是为了描叙某个对象在整个解决问题的步骤中的属性和行为。面向对象是以功能来划分问题,而不是以步骤解决。

优缺点比较

面向过程

优点:

  • 流程化使得编程任务明确,在开发之前基本考虑了实现方式和最终结果,具体步骤清楚,便于节点分析。
  • 效率高,面向过程强调代码的短小精悍,善于结合数据结构来开发高效率的程序。

缺点:

  • 需要深入的思考,耗费精力,代码重用性低,扩展能力差,后期维护难度比较大。

面向对象

优点:

  • 结构清晰,程序是模块化和结构化,更加符合人类的思维方式;
  • 易扩展,代码重用率高,可继承,可覆盖,可以设计出低耦合的系统;
  • 易维护,系统低耦合的特点有利于减少程序的后期维护工作量。

缺点:

  • 开销大,当要修改对象内部时,对象的属性不允许外部直接存取,所以要增加许多没有其他意义、只负责读或写的行为。这会为编程工作增加负担,增加运行开销,并且使程序显得臃肿。
  • 性能低,由于面向更高的逻辑抽象层,使得面向对象在实现的时候,不得不做出性能上面的牺牲,计算时间和空间存储大小都开销很大。

结构体

数组具有只能存放同一类型的数据的局限性,为了在解决复杂问题时需要多种不同类型数据,就引入结构体的概念。
结构体(Struct)从本质上讲是一种自定义的数据类型,只不过这种数据类型比较复杂,是由 int、char、float 等基本类型组成的。你可以认为结构体是一种聚合类型。
在实际开发中,我们可以将一组类型不同的、且用来描述同一件事物的变量放到结构体中。例如,在校学生有姓名、年龄、身高、成绩等属性,学了结构体后,我们就不需要再定义多个变量了,将它们都放到结构体中即可。

结构体中能放函数吗?

C语言中结构体只能储存数据。但在C++中,引入了类的概念,类中既可以声明变量,也可以定义函数。

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
}; #注意大括号后面的分号;不能少,这是一条完整的语句。

结构体指针

C语言结构体指针的定义形式一般为:

struct 结构体名 *变量名;

下面是一个定义结构体指针的实例:

//结构体
struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在小组
    float score;  //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 };
//结构体指针
struct stu *pstu = &stu1;

内存分配

1,内存分配的类型:

在C/C++中内存分为5个区,分别为栈区、堆区、全局/静态存储区、常量存储区、代码区。

静态内存分配:编译时分配。包括:全局、静态全局、静态局部三种变量。

动态内存分配:运行时分配。包括:栈(stack): 局部变量。堆(heap): c语言中用到的变量被动态的分配在内存中。(malloc或calloc、realloc、free函数)

2.变量的内存分配:

栈区(stack):指那些由编译器在需要的时候分配,不需要时自动清除的变量所在的储存区,如函数执行时,函数的形参以及函数内的局部变量分配在栈区,函数运行结束后,形参和局部变量去栈(自动释放)。栈内存分配运算内置与处理器的指令集中,效率高但是分配的内存空间有限。

堆区(heap):指哪些由程序员手动分配释放的储存区,如果程序员不释放这块内存,内存将一直被占用,直到程序运行结束由系统自动收回,c语言中使用malloc,free申请和释放空间。

静态储存区(static):全局变量和静态变量的储存是放在一块的,其中初始化的全局变量和静态变量在一个区域,这块空间当程序运行结束后由系统释放。

常量储存区(const):常量字符串就是储存在这里的,如“ABC”字符串就储存在常量区,储存在常量区的只读不可写。const修饰的全局变量也储存在常量区,const修饰的局部变量依然在栈上。

程序代码区:存放源程序的二进制代码。

堆栈(Heap& Stack)

堆和栈都是动态分配内存,两者空间大小都是可变的。

Stack: 栈,存放Automatic Variables,在数据结构中,栈是一种可以实现**“先进后出”的存储结构。按内存地址由高到低**方向生长,其最大大小由编译时确定,速度快,但自由性差,最大空间不大。
在实际编程中,可以通过两种方式来实现:
使用数组的形式来实现栈,称为静态栈;
使用链表的形式来实现栈,称为动态栈。

Heap: 堆,相对于栈的“先进后出”特性,堆则是一种经过排序的树形数据结构,常用来实现优先队列等。是自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。
动态分配的内存在调用 malloc() 或者相关函数产生,在调用 free() 时释放, realloc() 可用于重新分配空间大小。

\
申请方式系统自动分配管理手动分配管理
效率速度快,不会有内存碎片速度较慢,可能由于操作不当产生内存碎片
扩展方向从高地址向低地址由低地址向高地址
\局部变量;函数调用时会进行形参和返回值的压栈出栈new/malloc动态申请的内存

注意:

如果malloc(calloc、realloc) 比 free 多, 会造成内存泄漏;

如果malloc(calloc、realloc) 比 free 少,会造成二次删除, 破坏内存,导致程序崩溃。


---------------------
作者:冰箱上的笑话
来源:CSDN
原文:https://blog.csdn.net/qq_41361526/article/details/115709501
版权声明:本文为作者原创文章,转载请附上博文链接!
内容解析By:CSDN,CNBLOG博客文章一键转载插件

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C 语言中,指针是一种数据类型,它存储着一个变量的地址。通过指针,我们可以直接访问存储在该地址上的值,而不是访问变量本身。指针数组结构中有广泛的应用。 在数组中,数组名本身就是一个指向数组第一个元素的指针。我们可以通过指针来遍历数组中的元素,也可以通过指针来进行数组元素的赋值和访问。例如,下面的代码创建了一个整型数组及其指针,并通过指针访问了数组中的元素: ``` int array[5] = {1, 2, 3, 4, 5}; int *p = array; // p 指向数组第一个元素 for (int i = 0; i < 5; i++) { printf("%d ", *(p + i)); // 通过指针访问数组元素 } ``` 在结构中,指针可以用来访问结构成员和动态分配内存。例如,下面的代码创建了一个包含两个成员(整型和字符指针)的结构,并通过指针访问了结构成员: ``` struct mystruct { int num; char *string; }; struct mystruct data = {10, "hello world"}; struct mystruct *p = &data; // p 指向结构变量 data printf("%d %s\n", p->num, p->string); // 通过指针访问结构成员 ``` 指针还可以用来动态分配内存。例如,下面的代码使用指针动态分配了一个整型数组: ``` int *p = malloc(5 * sizeof(int)); // 动态分配 5 个整型空间 p[0] = 1; // 访问第一个元素 free(p); // 释放动态分配内存 ``` 总之,指针是 C 语言中非常重要的概念,掌握指针的使用对于编写高效、灵活的代码非常有帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值