C语言_指针2

指针三

一、内存区域划分

1.代码区:

存代码

2.常量区:

存常量:64,66,2,'a','s',"aafa",const修饰的

3.全局区(静态全局区)

1.静态变量(static修饰的)

2.全局变量

3.静态变量和全局变量有一个默认值为0

#include<stdio.h>
#include<iostream>
using namespace std;
​
int b;       //普通全局变量:项目内(项目作用域)
​
static int d;//静态全局变量:文件内(文件作用域),相当于只能在当前文件内使用,其他文件要使用,必须是当前文件提供了接口才行
​
            //项目作用域:其他文件中的普通全局变量
            //用extern声明之后可以继续使用
​
            //生存周期:程序开始到结束
​
​
extern int hp;
​
int main()
{
​
    int a=10;//普通局部变量  生存周期:当前语块
​
    static int c;//静态局部变量 生存周期:程序开始到结束
    //static起一个修饰作用
    //所以c是一个静态局部变量
​
    cout << "a=" << a << endl;
    cout << "b=" << b << endl;
    cout << "c=" << c << endl;
    cout << "d=" << d << endl;
    //输出结果都为0
​
    while (1);
    return 0;
}

静态全局区:从程序开始的时候,系统就会自动分配内存,在程序结束的时候系统自动回收内存

作用域与生存周期

普通局部变量 都是当前大括号

1.普通全局变量

2.静态全局变量

3.静态局部变量

4.栈区

存储:普通局部变量

栈区:从定义时开始系统自动分配内存,出了函数系统自动回收临时内存

5.堆区

由程序员手动申请手动释放

二、void*指针

空类型的指针

#include<stdio.h>
#include<iostream>
using namespace std;
​
int main()
{
    int* p1 = nullptr;
    int* p2 = p1 + 1;
    //同类型的指针可以给值
    void* p = nullptr;
    /*而void* p=nullptr;
    void* p1=p+1;是不能通过的*/
​
    while (1);
    return 0;
}

1.不能偏移

2.不能自增自减

3.可以接受其他类型的指针,而不需要强转

    void* p = nullptr;
    int num = 100;
    int* pn = &num;
    p = pn;
    //short* psh = pn;错误的操作,不用类型的指针不能相互指

三、动态申请内存

1.c语言

c语言中用函数申请内存过程

1.申请:

malloc(size_t Size) 参数;字节数

calloc(size_t Count,size_t Size) 参数;类型 个数

2.释放:

free(void* Block) 参数:地址

3.置空

    #include<stdio.h>
    #include<stdlib.h>

    //使用malloc()函数

    //申请一个int类型大小的内存空间
    malloc(4);
    //或者是
    malloc(sizeof(int));
​
    void* p=malloc(sizeof(int))
    /*因为只是申请到了4个字节的空间
    不知道是什么类型,系统默认是void类型
    所以要用void*去接收*/
    //或者强转成你想要的类型
    int* p=(int*)malloc(sizeof(int));
    
    //如果申请的内存没有释放,会造成内存泄漏
    free(p);
​
    
​
    //完整过程
    //1.申请内存
    int* p=(int*)malloc(sizeof(int)*10);
    //2.使用
     .....
    //3.释放
    free(p);
    //4.置空
    p=NULL;//不然会形成野指针
​ 

    //使用calloc()函数
    
    //申请十个int类型大小的内存(4 * 10 = 40字节)
    // 1 申请
    p = (int*)calloc(sizeof(int),10);
    // 2 使用
    // .....
    // 3 释放
    free(p);
    // 4 置空
    p = NULL;

C++

申请:

new new 类型 new[] new 类型[个数]

释放



    // 一 申请一个int类型大小的内存(4字节)
    // 1 申请
    int* p = new int;
    // 2 使用
    // ...
    // 3 释放
    delete p;
    // 4 置空
    p = nullptr;
​
    p = new int(100);
    delete p;
    p = nullptr;
​
    // 二 申请十个int类型大小的内存(4 * 10 = 40字节)
    int num;
    cin >> num;
    // 1 申请
    p = new int[num];
    // 2 使用
    // ...
    for (int i = 0; i < num; i++)
    {
        p[i] = i;
    }
    for (int i = 0; i < num; i++)
    {
        cout << "p[i] = " << p[i] << endl;
    }
    // 3 释放
    delete[] p;
    // 4 置空
    p = nullptr;

应用举例

    int** p = new int*[10];
    for (int i = 0; i < 10; i++)
    {
        p[i] = new int[10];
    }
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            p[i][j] = i * 10 + j;
        }
    }
    for (int i = 0; i < 10; i++)
    {
        for (int j = 0; j < 10; j++)
        {
            printf("%3d", p[i][j]);
        }
        printf("\n");
    }


int** p = (int**)calloc(sizeof(int), 10);
for (int i = 0; i < 10; i++)
{
    *(p + i) = (int*)calloc(sizeof(int), 10);
}
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        *(*(p+i)+j) = i * 10 + j;
    }
}
for (int i = 0; i < 10; i++)
{
    for (int j = 0; j < 10; j++)
    {
        printf("%3d", p[i][j]);
    }
    printf("\n");
}
​
for(int i=0;i<10;i++)
{
   free(p[i]); //先要将前面指的那十个内存区域释放
}
free(p);
p=NULL;

内存泄漏和野指针

内存泄漏:申请的内存,没有释放

野指针:指针指向了不该指向的地方,一般是指向未被使用的内存空间

如:int* pn;

引用

给变量取别名:引用对象与被引用对象共用一段内存

//类型& 引用名 = 变量名;
const //防止引用修改


int num = 10;
int& n = num;
cout << "num=" << num << endl;
cout << "n=" << n << endl;
n = 20;
cout << "num=" <<num << endl;
cout << "n=" << n << endl;
const int&m=num;
//m=65;是不行的
//用const修饰防止被引用的量被修改

指针和引用的区别

1.指针可以置空,引用不能置空

2.指针可以改变指向,引用不能改变被引用对象

3.指针可以不初始化,引用必须初始化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值