c语言:13、指针与内存

  • 1、计算机中数据表示方式
    • 进制
  • 2、内存管理
    • 操作系统的内存管理
  • 3、变量和指针的本质
  • 4、程序在内存中的debug
    • 4.1、编写main.c
    • 4.2、编译代码
    • 4.3、gdb调试程序
      • 分析
    • 4.4、函数的内存
    • 4.5、变量的内存大小
    • 4.6、指针变量的内存大小
  • 5、函数栈是怎么工作的
  • 6、指针自加的调试
    • 6.1、调试
    • 6.2 指针本质上也是一种数组
  • 7、字符数组

下方代码调试均在centos64位系统下进行

1、计算机中数据表示方式

进制

计算机中使用2进制、8进制、16进制表示数据;
计算机用二进制处理数据,计算机计算结果显示给人看就用十进制,编程要表示二进制数据时,因为内容过长,因此使用十六进制

2、内存管理

计算机中不管插几块内存条都会被计算机当做一个整体来计算内存大小;

 32位系统即使插再多的内存也只能使用4G内存,因为32位硬件平台上cpu地址总线只有32位,也就是操作系统寻址空间只有32位。32位指的是给内存编号只能编到32个二进制位,因此最终只能操作4G的内存空间。详细的感兴趣的朋友可以自行搜索。64位的操作系统因为寻址空间有2^64,因此理论上足够我们目前的使用了。

操作系统的内存管理

内存由操作系统统一管理;除了能给内存做编号外,还可以给内存做一定的规划,比如在64位操作系统中,用户程序使用的内存只要有前面的48位就可以了。

操作系统将用户内存和操作系统内存进行了隔离,前48位由用户使用,称为用户内存,后面的由操作系统使用。

隔离开后,即使用户内存使用不合理爆满,也不会影响操作系统内存,还是可以使用操作系统关闭不合理的内存占用进程。使得内存更安全。

C语言的语法是不允许我们直接操作代码段内存的;

标准C语言语法中是不支持直接对某一个内存地址进行操作的,操作系统会认定为非法操作。因为有可能会操作到操作系统的内存或其他应用程序的内存,这是不合理的,只有操作系统分配给应用程序的内存才是合理的操作。

操作系统对内存的划分:

代码段的内存地址是从下往上分配,数据段也是,栈内存是从上往下分配的。
因此代码段和数据段中的变量内存地址是越先分配的内存地址越小,栈内存中的变量则是越先分配的地址越大。

3、变量和指针的本质

变量的本质:
变量名只是一个代号,变量的本质就是内存。
写程序的时候,计算机处理的全是二进制数据,程序运行时二进制数据加载到内存中CPU才能取出来。
CPU要从内存中取数据,那么CPU就必须要知道从哪个内存单元中取,而变量就是起到一个标识作用,告诉CPU要到什么地方去取数据,或者要把数据写到什么地方去。这就是变量的本质。

指针的本质:
指针保存的是内存地址,因此指针本质上就是地址。

内存连续的证明:
下方调试例子证明了内存连续:

#include <stdio.h>
int main()
{int a = 3;int b = 2;int array[3];array[0] = 1;array[1] = 10;array[2] = 100;int *p = &a;int i;for(i=0; i<6; i++){printf("*p=%d\n",*p);p++;}printf("------------------------------\n");p=&a;for(i=0; i<6; i++){printf("p[%d]=%d\n", i, p[i]);}return 0;
}

4、程序在内存中的debug

4.1、编写main.c

#include <stdio.h>
int global = 0;int rect(int a, int b)
{static int count =0;count++;global++;int s=a*b;return s;
}int quadrate(int a)
{static int count=0;count++;global++;int s=rect(a,a);return s;
}

4.2、编译代码

gcc -g main.c

4.3、gdb调试程序

分析

由上图可知,源代码被加载到内存(内存代码段中)之后,能够借助gdb等调试工具进行调试,所以程序在运行的过程中,程序除了在代码段中以外,下方信息记录在了内存中:

  1. 当前调用哪个函数
  2. 当前调用的函数运行到多少行,并且这个函数中有哪些变量,这些变量的值是什么

内存栈中分配了内存给当前运行的函数,且内存栈中把函数执行过程中的所有状态全部记录了下来(就像拍了一个照片一样),比如上图中就记录下了当前代码运行到了27行

内存栈中一个函数可以被多次调用,多次调用时,每次调用都是一个独立的栈。

4.4、函数的内存

在代码段中内存地址是由低地址向高地址转移的,先声明的函数地址小,后声明的函数地址大。

4.5、变量的内存大小

4.6、指针变量的内存大小

5、函数栈是怎么工作的

继续调试第4步中的代码

栈的特点:先进后出
栈内存中最先分配的栈地址最大

6、指针自加的调试

6.1、调试

#include <stdio.h>
int main()
{int a = 3;int b = 2;int array[3];array[0] = 1;array[1] = 10;array[2] = 100;int *p = &a[0];int i;for(i=0; i<6; i++){printf("*p=%d\n",*p);p++;}return 0;
}

#include <stdio.h>
int main()
{int a = 3;int b = 2;int array[3];array[0] = 1;array[1] = 10;array[2] = 100;int *p = &array[0];p += 3;*p = 101;/*p += 3; *p = 101;与p[4]=101;等价,指针也可以使用数组的方式来访问  */p = &array[0];int i;for(i=0; i<6; i++){printf("*p=%d\n",*p);p++;}return 0;
}

运行上方代码,结果如下

6.2 指针本质上也是一种数组

如下方两个指针偏移量的操作,指针可以使用数组的方式来操作,
可以理解为:从本质上指针类型是数组变量、数组数据类型像是数组常量;

int a = 2;
int *p = &a;
p += 3;
*p = 101
//上方两行代码与下方一行代码等价
p[4] = 101;

字符数组类型和指针类型也是可以混用的

#include <stdio.h>
int main()
{char str[] = "hello";char *str2 = "world";char str3[10];printf("input the value \n");//字符数组类型和指针类型也是可以混用的,下方str3是一个字符数组scanf("%s", str3); printf("str is %s\n", str);printf("str2 is %s\n", str2);printf("str3 is %s\n", str3);
}

调试上方代码结果如下:

7、字符数组

#include <stdio.h>
int main()
{char str[] = "hello";char *str2 = "world";char str3[10];printf("input the value \n");scanf("%s", str3);printf("str is %s\n", str);printf("str2 is %s\n", str2);printf("str3 is %s\n", str3);return 0;
}

c语言:13、指针与内存相关推荐

  1. c语言中指针往内存写值,C语言编程常见问题解答之指针和内存分配

    指针为C语言编程提供了强大的支持--如果你能正确而灵活地利用指针,你就可以直接切入问题的核心,或者将程序分割成一个个片断.一个很好地利用了指针的程序会非常高效.简洁和精致. 利用指针你可以将数据写入内 ...

  2. C语言中指针占据内存空间问题

    以前一直有个疑问,指向不同类型的指针到底占用的内存空间是多大呢? 这个问题我多次问过老师,老师的答案是"指向不同类型的指针占据的内存空间大小不同",我一直很之一这个答案,今天我就做 ...

  3. c语言字符指针分配内存,内存分配函数及使用注意事项,C语言内存分配函数完全攻略...

    C 语言主要提供 malloc.realloc.calloc.alloca 与 aligned_alloc 等内存分配函数来实现对内存的分配功能. 1)malloc 函数原型如下: void * ma ...

  4. C语言_指针动态内存分布

    传 统 数 组 的 缺 点 . 1. 数 组 长 度 必 须 事 先 制 定 , 且 只 能 是 常 整 数 , 不 能 是 变 量 例 子 : int a[5] ;/ / 0K int len = ...

  5. c语言 乘号 指针 避免,C语言指针篇(一)指针与指针变量

    指针 1. 什么是指针? 2. 指针可不可怕? 3. 指针好不好玩? 4. 怎么学好指针? C语言是跟内存打交道的语言,指针就是内存地址.指针无处不在,指针并不可怕,相反,等你学到一定程度后,会有一种 ...

  6. 在c语言中定义了一个指针变量后,C语言的指针变量

    C语言的指针变量 在C语言中,变量是固定范围的存储空间,它存储的是赋给他的值, 比如: int a = ; /* 这里是定义一个整型变量a,并把12这个值存储在a的地址空间上 这个地址空间是系统随机分 ...

  7. C语言中的指针和内存泄漏

    对于任何使用 C 语言的人,如果问他们 C 语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但 ...

  8. C语言二级指针内存模型建立

    C语言二级指针内存模型建立 代码 解析 代码 void main() {int i = 0;//指针数组char * p1[] = {"123", "456"

  9. C语言重点——指针篇(一文让你完全搞懂指针)| 从内存理解指针 | 指针完全解析

    有干货.更有故事,微信搜索[编程指北]关注这个不一样的程序员,等你来撩~ 注:这篇文章好好看完一定会让你掌握好指针的本质 C语言最核心的知识就是指针,所以,这一篇的文章主题是「指针与内存模型」 说到指 ...

最新文章

  1. java 自然语言处理_Java自然语言处理
  2. 数控机床编程用c语言,基于C语言数控机床智能后置处理程序的制作-(1).pdf
  3. 网线传输速度测试_高效的以太网测试仪应该具备哪些功能?
  4. Buffer Pool--内存总结2
  5. SQL Try Catch
  6. Tableau必知必会之学做 饼图 和 折线图 的组合图表
  7. 2.4 矩阵乘以矩阵定义
  8. NLP《词汇表示方法(三)word2vec》
  9. 8Python全栈之路系列之Django Cookie 与Sessi
  10. java list 树_java list转换为树形
  11. 【node】---记忆内容
  12. macOS Big Sur的小部件使用技巧
  13. 使用Excel2016对数据进行线性回归分析
  14. C语言辅助学习系统(asp.net开发)
  15. 蓝桥杯练习题JAVA 圆的面积
  16. 研究了一堆英语学习软件,发现了一个美国宝藏口语App,国内也能用!
  17. MySql基础篇---004 其它数据库对象篇:视图,存储过程与函数,变量、流程控制与游标 ,触发器
  18. 易语言取php网页数据,易语言爬取网页内容方法
  19. 工程光学第一、二、六章学习总结
  20. CCF CSP 历年试题题解

热门文章

  1. android 抓包 修改数据,微信跳一跳怎么用抓包修改分数_改数据
  2. [回顾]windows安装mujoco200
  3. JAVA--Socket【“套接字”】
  4. 数据库 完整性约束定义
  5. 使用tcpdf合成PDF文件
  6. 电脑如何进入bios设置?
  7. Spring系列之依赖注入的三种方式
  8. Spring RMI反序列化漏洞分析
  9. Fortran和C/C++混合编程学习笔记(一):编译链接
  10. STM32F410xx与STM32F411xE时钟修改(标准库)