前言:

    为啥叫C语言程序猿必会呢?因为特别重要,学习C语言不知道内存分区,对很多问题你很难解释,如经典的:传值传地址,前者不能改变实参,后者可以,知道为什么?还有经典面试题如下: 

#include <stdio.h>
#include <stdlib.h>
#include <stdlib.h>
void getmemory(char *p)
{
p=(char *) malloc();
}
int main( )
{
char *str=NULL;
getmemory(str);
strcpy(str,"hello world");
printf("%s/n",str);
free(str);
return ;
}

  这段代码执行了会怎么样?接下里我会解释这道面试题。

  一、内存布局

  可能网上有很多把内存分的很多、很细,但觉得很难记,并对于理解问题作用并不大。现在主要将内存分为四区如下:

  代码区:存放代码;运行期间不可修改

  全局区:全局变量、静态变量、常量字符串;程序运行时存在,退出时消失。

  栈区:自动变量、函数参数、函数返回值;作用域函数内(代码块内)

  堆区:动态分配内存,需手动释放

  用交换两个数的程序进行解释吧,如下: 

#include<stdio.h>

void swap(int a,int b)
{
int temp = a; //栈
a = b;
b =temp;
}
int main()
{
int a=,b=; //栈
printf("a:%d,b:%d\n",a,b);
swap(a,b);
printf("a:%d,b:%d\n",a,b); return ;
}

  画个图进行讲解,如下:  PS:依旧是全博客园最丑图,不接受反驳!

  

  说明:main函数把a,b的值给了temp函数,temp函数在内部交换了值,并没有影响main函数,并且temp结束,栈上的数据释放。传值不会改变实参。

  二、程序示例及面试题讲解

  1、传地址交换两个数  

  在拿传指针的例子来说明一下,如下:

#include<stdio.h>

void swap(int *a,int *b)
{
int temp = *a; //栈
*a = *b;
*b =temp;
}
int main()
{
int a=,b=; //栈
printf("a:%d,b:%d\n",a,b);
swap(&a,&b);
printf("a:%d,b:%d\n",a,b); return ;
}

  结果:成功交换了实参的值

  用图进行解释,如下:  PS:依旧是全博客园最丑图,不接受反驳!

  

  说明:实参把地址传给形参,形参*a、*b是取的实参在内存中的值,交换也就是交换实参的值了,所以成功交换了实参的值。

  2、解释面试题

  程序就是最开始的面试题那个,不再列出来了。

  结果:段错误

  然后画图进行说明,如下:  PS:依旧是全博客园最丑图,不接受反驳!

  

  说明:最重要一点实参是把值传给形参,而不是地址,要理解这一点!就是把实参的NULL给了形参,然后getmemory在堆上开辟空间,结束时p被释放了,但main函数中的str并没有指向堆上的内存,再给strcpy,当然会段错误。

  三、解决被调函数开辟空间

  可能有人就问了,我就想让被调函数开空间,怎么办呢?那就需要形参是二级指针了。

  给大家演示一下,代码如下:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void getmemory(char **p)
{
*p=(char *) malloc();
}
int main( )
{
char *str=NULL;
getmemory(&str);
strcpy(str,"hello world");
printf("%s/n",str);
free(str);
return ;
}

  结果:没有段错误了

  大家可以自己画下图,不懂欢迎随时留言。

  三、十月份计划

  十月份需求会很忙,但也要抽出时间把C++基础学完,然后深入学习数据结构和算法了

  

C语言程序猿必会的内存四区及经典面试题解析的更多相关文章

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

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

  2. 每一个程序猿必知之SEO

    似乎由于受这篇文章的影响 http://katemats.com/what-every-programmer-should-know-about-seo/ 于是我也觉得我应该写一个每一个程序猿必知之S ...

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

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

  4. 深入理解C语言-深入理解内存四区

    数组与指针 当数组做函数参数的时候,会退化为一个指针 此时在函数内是得不到数组大小的 因此,数组做函数参数的时候需要传递数组大小,也就是多传递一个参数 void func(int arr[], int ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. Chrome开发者工具面板

    Chrome开发者工具面板 面板上包含了Elements面板.Console面板.Sources面板.Network面板.Timeline面板.Profiles面板.Application面板.Sec ...

  2. history.back(-1) 和history.go(-1) 有什么区别?

    history.back(-1) 返回上一页,当前页面的数据都没有保存下来.就像当前也没有出现过一样. history.go(-1)    返回上一页,当前页的内容都保存下来了,包括session,等 ...

  3. python利用xlrd读取excel文件始终报错原因

    1.代码按照网上百度的格式进行书写如下: 但运行后,始终报错如下: 百度了xlrd网页: 分明支持xls和xlsx两种格式的文件,但运行始终报错. 最后找到原因是因为我所读取的文件虽然是以.xls命名 ...

  4. lnmp环境一些基本命令行

    使用service启动/停止/重启相关服务 启动/停止/重启 php服务 service php-fpm start/stop/restart 启动/停止/重启 mysql service mysql ...

  5. python 错误记录

    class Func: d = dict() def __setitem__(self, key, value): # xxx object does not support item assignm ...

  6. iOS逆向工程概述(转)

    逆向工程一词,对很多人来说可能很陌生,在android领域,我们经常会听到“反编译某个apk”,那么逆向工程从某种角度讲也包括反编译这项技术,这样一对比,可能我们就更容易理解逆向工程的定义了. 我们引 ...

  7. 多路分支----switch语句

    switch-case与if-else有相似的作用,都是表达分支的方式. 语法形式: switch(type){ case 常量1: do something; break; case 常量2: do ...

  8. codeforces 13 D

    给你500个红点和蓝点,让你找多少点红点构成的三角形里没有蓝点. 巧妙啊!我们考虑一个很远位置的点,不妨设这个为O,然后n^2枚举红点,考虑Oij里面蓝点的个数, 然后 对于 ijk这个三角形,我们可 ...

  9. Educational Codeforces Round 8

    开始填坑_(:з」∠)_ 628A - Tennis Tournament    20171124 小学数学题,\((x,y)=((n-1)\cdot(2b+1),np)\) #include< ...

  10. 用递归方法求n的阶乘

    代码: #include<iostream> using namespace std; int fact(int n); int main() { int n; loop: cin > ...