数组与指针

当数组做函数参数的时候,会退化为一个指针

此时在函数内是得不到数组大小的

因此,数组做函数参数的时候需要传递数组大小,也就是多传递一个参数

void func(int arr[], int num)
{
···
}

若存在以上函数,c/c++编译器在编译的时候,会将数组优化为一个指针,指向数组的首地址,因此无法通过sizeof获得数组大小

以下可看作是c/c++编译器的优化过程

int a[10] => int a[] => int *p

void func(int *p, int num)
{
···
}

实参与形参

在函数调用的时候,实参的值机械的传递给形参

形参:

  • 写在函数里面和函数上边,对C/C++编译器没有区别
  • 写在函数上边多了对外属性
  • 入栈时候从右至左入栈

数据类型的本质



按照上图,数据类型又可分为简单数据类型和复杂数据类型

简单数据类型和复杂数据类型的处理方式不一样

在处理复杂数据类型的时候,不能按照简单数据类型的处理方式去处理

例如,存在 int a[10] 数组,那么 &a 的值和 a 的值相同,但是 &a + 1a + 1 的值却不相同,原因是前者代表的是一个数组地址,后者代表的是一个元素地址,前者加一,指出数组,而后者加一则是相当于指向下一个元素的地址,前者移动 sizeof(a) 字节,后者移动 sizeof(int) 字节

C语言规定数组名代表数组首元素地址,&a代表整个数组

数据类型的本质就是告诉编译器开辟内存的大小,就是一个指明开辟内存大小的说明性标签,也就是创建变量的模具,是固定内存大小的别名

数据类型的大小和别名

在C语言中,专门有一个操作符sizeof用来得到数据类型的大小,其大小在编译时候便已经确定

由于数据类型只是一个标识,故可以使用typedef定义别名

变量的本质

既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量

变量本质:(一段连续)内存空间的别名,标号

  • 程序通过变量来申请和命名内存空间
  • 通过变量名访问内存空间

    由于变量的本质就是内存空间的别名,故要修改变量的值,无外乎就两种方式
  • 直接:通过变量名,也就是别名修改
  • 间接:内存有地址编号,拿到地址编号也可以修改内存
  • 引用修改(C++)

    变量三要素(名称、大小、作用域)
  1. 对内存可读可写
  2. 通过变量向内存中读写数据,而不是像变量读写数据
  3. 向变量代表的数据空间读写数据

数据类型和变量的关系

C语言规定:通过数据类型,定义变量

内存四区



流程说明

  1. 操作系统把物理硬盘代码load到内存
  2. 操作系统把c代码分成四个区
  3. 操作系统找到main函数入口执行
区块 作用
栈区(stack) 由编译器自动分配释放,存放函数的参数值,局部变量的值等
堆区(heap) 一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收
全局区(静态区)(static) 全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放
常量区 字符串常量和其他常量的存储位置,程序结束后由操作系统释放
程序代码区 存放函数体的二进制代码

函数调用模型

main()调用fa(),fa()调用fb()



主调函数分配的内存,可以在被调函数中使用(指针做函数参数)

在fa(),fb()中分配的内存,如果实在栈区,不可在main()中调用,如果在堆区,全局区,可以在main()中调用,注意内存的释放问题

在被调用的函数中malloc的内存,首地址传递给调用函数有两种方法

  1. return
  2. 指针做函数参数

内存四区和函数调用变量传递

一个单进程主程序有n个函数组成,C++编译器只会分配一个堆区,一个栈区

堆栈属性说明

栈(stack):向下生长

堆(heap):向上生长

Heap、stack生长方向和内存存放方向是两个不同概念

深入理解C语言-深入理解内存四区的更多相关文章

  1. C++ 内存四区 理解总结

    内存模型图(4G) 整体简单说明 32位CPU可寻址4G线性空间,每个进程都有各自独立的4G逻辑地址,其中 03G是用户空间**,**34G是内核空间即3G用户空间和1G内核空间,不同进程相同的逻辑地 ...

  2. 深入理解C语言-深入理解指针

    关于指针,其是C语言的重点,C语言学的好坏,其实就是指针学的好坏.其实指针并不复杂,学习指针,要正确的理解指针. 指针是一种数据类型 指针也是一种变量,占有内存空间,用来保存内存地址 指针就是告诉编译 ...

  3. C语言的内存四区模型和函数调用模型

    首先是操作系统将代码程序加载到内存中 然后将内存分为4个区 栈区,程序的局部变量区,函数传递的参数,由编译器自动进行内存资源的释放. 堆区,动态内存申请,如果不手动释放内存,则这块内存不会进行析构. ...

  4. C语言内存四区的学习总结(一)---- 静态区

    最近重新学习C语言相关知识,重新提到内存四区的概念,那么在之前的学习的基础上,在这儿做一个简单的总结与分享. 一.内存四区建立的流程 可以简单直观的查看下面的这个图片,直接的说明我们的程序在内存中是如 ...

  5. C语言提高 (1) 第一天 数据类型本质与内存四区

    (物联网的分层的概念 b/s c/s 结构 习惯: 在C语言 0 函数执行成功 <0是错误 >1做一些返回值处理 3 课前准备 工作经验,记录 4 数据类型的本质 数据类型的本质是固定大小 ...

  6. C语言内存四区的学习总结(三)---- 栈区

    接上篇内存四区的堆区的总结,下面做一些栈区的相关总结. 一.栈区的分析: 就下面测试程序 #include "stdio.h" #include "string.h&qu ...

  7. C语言内存四区的学习总结(二)---- 堆区

    接上篇,内存四区的分析-静态区,下面来说明一下堆区总结. 堆区分析: 堆区(heap):一般由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回 就下面的程序: #inc ...

  8. C语言进阶之路(一)----C语言的内存四区模型

    内存四区模型:操作系统给C/C++编写的程序分配内存,通常将分配的内存划分为以下四个区域:1.栈区:存放局部变量,用完由操作系统自动释放2.堆区:动态分配给程序的内存区域,由程序员手动释放3.数据区: ...

  9. C语言之内存四区模型和函数调用模型

      内存四区模型 流程说明1.操作系统把物理硬盘代码load到内存2.操作系统把c代码分成四个区3.操作系统找到main函数入口执行 1.内存四区: 一个由c/C++编译的程序占用的内存分为以下几个部 ...

随机推荐

  1. vue初级尝试

    为了跟上前端后台化的潮流,本少不得不开始关注vue,下列上机代码是针对App.vue进行的更改 数据渲染----一般键值对,数组,对象和对象数组 <template> <div id ...

  2. Luogu P1903 [国家集训队]数颜色 or 维护队列

    标准的带修莫队...咕到了现在$qwq$ 莫队是对询问排序来优化复杂度的(不带修就是对询问区间$[l,r]$排序).. 那么现在带修了,我们再可以维护一个时间维度$tm$:对于每个询问,每次回答前先检 ...

  3. 计算(calc.cpp) 这题我搞了2晚上qwq

    终于会了!可喜可贺!可喜可贺!   计算(calc.cpp) [问题描述] 小明在你的帮助下,破密了Ferrari设的密码门,正要往前走,突然又出现了一个密码门,门上有一个算式,其中只有“(”,“)” ...

  4. luogu3629

    P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...

  5. MySQL认识索引

    什么是索引? 索引在MySQL中也叫是一种“键”,是存储引擎用于快速找到记录的一种数据结构.索引对于良好的性能非常关键,尤其是当表中的数据量越来越大时,索引对于性能的影响愈发重要.索引优化应该是对查询 ...

  6. pycharm同一目录下无法import其他文件

    如图:会出现带有红色波浪线,但是确实有random_walk文件 解决方法: 在当前文件下,右键找到mark  Directory as 然后选择source root,完工ok 再如图: 版权声明: ...

  7. ARTS打卡计划第十六周

    Algorithms: https://leetcode-cn.com/problems/min-stack/submissions// Review: https://www.infoq.cn/ar ...

  8. python能用来做什么?这3大主要用途你一定要知道!(实用)

    导读:如果你想学Python,或者你刚开始学习Python,那么你可能会问:“我能用Python做什么?” 这个问题不好回答,因为Python有很多用途. 但是随着时间,我发现有Python主要有以下 ...

  9. 预处理、const、static、sizeof-说明内联函数使用的场合

    1:首先使用inline函数可以完全取代表达式形式的宏定义. 内联函数在C++类中的应用最广的应该是用来定义存取函数.我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们 ...

  10. 发布mybatis-generator-core 1.3.5的中文注释版

    源码剖析介绍:基于mybatis-generator-core 1.3.5项目的修订版以及源码剖析 目前,我把该项目,发布到了Maven中央仓库中,可直接使用: 使用方式 在项目.pom中,添加以下部 ...