指针三
一、内存区域划分
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 = #
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.指针可以不初始化,引用必须初始化