首页 > 系统相关 >C语言 指针及动态内存分配

C语言 指针及动态内存分配

时间:2022-11-11 12:06:07浏览次数:58  
标签:变量 void C语言 地址 内存 动态内存 类型 指针


大一学《计算系统基础》的时候,没有讲这一块的内容,导致后面遇到指针就头疼,今天特来梳理一下这块的内容。

1.变量的类型

类型的语言,即要求定义变量的时候必须制定类型,然后编译器会根据类型来分配内存空间,只要定义就会分配。对于一个变量,本质上的两个要素是地址和类型。

    地址:这是变量名本身的含义,变量在内存中的首地址,即位置。底层的东西就是符号表了,编译器在编译时将每一个遇到的变量插入一条记录,《变量名,地址》这样的记                       录。

    类型:有了地址还不足以处理对变量的操作,因为不知道大小。现在要读取一个变量值,知道了地址,就知道了从哪里拿,但是拿多少呢?这就是一个问题,而解决拿多少的关                   键就是知道变量的类型。如果是int,那么就从首地址开始向后拿4个字节,char的话就拿一个字节。即,类型指明了变量的存储大小。当然这是对于char,int这样的基本                   数据类型而言。另外,对于复合类型的数据,比如strust,那么类型还指明了内存的分配方式。比如下面这个:

               

struct S{
int a;
char b;
};

               如果我们要读取一个S变量的内容,就得知道他的内存是怎么分配的,很显然是一个int类型,再跟一个char类型。如果我们要读取s.b,就得知道b变量的首地址,通过s的                  首地址加上4的字节的位移就可以得到了。

    总而言之,这里明白了变量的两个要素。地址和类型。

2.指针

    指针本身的类型是可以确定的,就是存放了一个地址,这个没什么好说的。但是指针所指向的内存所存放的数据的类型是很重要的,这个“类型”就是我们上面说的那个类型,指明了变量的大小和分配方式。所以我们认识指针也要从地址和类型开始。地址的话就是指针的值了,类型就是*号前面的内容。

    那么void *是什么意思?是说这个指针所指向的内存的类型不确定。也就是说我们只知道所指向变量的地址,其余的全部不知道。我们所能操作的也就是这个地址了。如果我们想通过*p的方式来读取内容,这样是不行的。引文我们并不知道类型,不知道要从这个地址开始,向后拿多少内存。所以对于* void,我们只能操作地址,地址所指向的内存内容无法得到。

   最后,这个void *有什么作用?它通常用来作为函数的参数或者返回值,因为它可以接受或返回任意类型的指针,在函数的内部,它就是一块内存,其余的什么都不知道,我们只能对这一整块内存进行整体的处理,如memcpy()函数进行拷贝,或者malloc()函数,进行内存空间的返回。

   所以对于void *,我们只知道地址为不知道具体的内容。

3.变量为止

    C语言中的变量会被分配到3个内存空间中:

    静态数据区:存放的是全局或者静态变量,在编译时候分配,当然这个区域还可以细细分。

    栈区:函数内部定义的局部变量,函数执行时分配,函数返回时回收,绝大部分的变量都在这里,因为程序就是函数构成的。

    堆区:动态分配的内存。在程序执行时才分配,大小可以动态决定。

4.动态分配方式

    主要有malloc(),alloc()和realloc()函数

三个函数的申明分别是:
        void* malloc(unsigned size);
        void* realloc(void* ptr, unsigned newsize);  
        void* calloc(size_t numElements, size_t sizeOfElement); 

    三个函数都会返回分配以后内存的首地址,如果失败返回NULL。所以我们最好是验证一下返回值,看是不是NULL;

      realloc是把prt指向的内存重新调整为newsize大小,如果扩大,原有内存的内容不会改变,如果缩小,则会丢失一部分数据。返回的新地址有可能会与ptr不同,但是这个不一定,要看内存块所剩余的空间是否还够用,这样的话,大一些的newsize通常会导致首地址不一样,同时也会导致内存的拷贝。

     calloc是分配numElements个大小为sizeOfElement的连续内存。

     返回的内存是void *的,因此无法对内存的内容操作,我们通常会用另一个非void *的指针来接受void *的值,但是必须强制转型,这样就可以执行*p这样的操作了。

标签:变量,void,C语言,地址,内存,动态内存,类型,指针
From: https://blog.51cto.com/u_15873544/5844098

相关文章

  • C语言基础知识应用·
    一开始由算法开始,毕竟你以前学的算法和c有所不同然后开始学程序流程控制接着学内存处理机制提高深入编程然后与其他软件如sqlweb联系起来学习后面的看你自己需要......
  • C语言常用的代码
    C语言经常需要发明各种轮子,为方便以后能够把精力放在应用逻辑上而不在发明轮子上,把一些常用的代码片段列于此。首先是字符串处理方面的,strcpy 函数容易越界,习惯使用 strn......
  • VS2019 error C4703: 使用了可能未初始化的本地指针变量 错误
    目录​​一、异常错误​​​​二、原因​​​​三、解决方法​​​​1.关闭安全开发生命周期(SDL)检查​​​​2.或者将指针变量初始化为nullptr​​一、异常错误errorC470......
  • 818E - Card Game Again 双指针+分解质因数
    题意:有多少种xy的选择方法,使得对于长度为n的a数组,取 a[x+1],a[x+2]...a[y-2],a[y-1]的乘积是k的倍数 思路:对于所有的x,当选择x=x+1时y=y......
  • C语言学习笔记---sizeof关键字和strlen函数
    sizeof和strlen在C语言中常用来计算字符大小和长度,在应用中却有着本质的区别。 sizeof是C语言中的关键字,其作用是返回一个对象或类型所占的内存字节数。使用方式为:int......
  • 初识指针
    指针intmain(){ inta=10;//a在内存中要分配空间的—4个字节 printf("%p\n",&a);//%p专门用来打印地址的 int*pa=&a;//pa是用来存放地址的,在C语言中pa叫指针......
  • C语言 函数02 自定义函数的参数
    实际参数(实参):真实传给函数的参数,叫实参。实参可以是:常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参。形......
  • C语言 函数01 函数的定义与分类
    函数定义:维基百科对函数的定义:是一个大型程序中的某部分代码,由一个或多个语句块组成。它负责完成某项特定任务,而且相较于其他代码,具备相对的独立性。一般会有输入参数并有返......
  • C语言实现扫雷(标记/取消标记雷、自动展开)
    前言扫雷的设计和三子棋大同小异。这次我在之前的扫雷基础上加入了标记/取消标记雷和显示雷的数量的功能。希望对大家能有帮助。这里以9*9的棋盘为例。先附上游戏的最终效果......
  • C语言函数指针示例
      1#include<stdio.h>23doubleadd(doublea,doubleb)4{5returna+b;6}78doublesub(doublea,doubleb)9{10returna-......