什么是指针?
指针(pointer)是一个值为内存地址的变量(或数据对象)。
想要透彻搞懂它,就必须从计算即底层原理进行解释。
与指针紧密相连的就是内存:内存在物理上是由一组DRAM芯片组成,从功能讲,内存是一个数据仓库,程序在执行前要被载入到内存中才能被中央处理器(CPU)执行。作为程序员,我们无需了解内存的物理结构。操作系统将软件与硬件结合起来,给程序员提供了一种对物理内存空间的抽象(虚拟存储器)。内存是由按顺序编号的一系列存储单元组成的,在内存中,每个存储单元都由唯一的地址,通过地址可以方便地在内存单元中存储信息。
在计算机中,一切信息都是以二进制数据的形式体现的,每个内存单元的容量是1B,即8bit(8个0、1二进制位)
一个程序载入内存,代码数据都有地址,外挂就是调用函数,修改数据 而函数就是代码,变量就是数据。
可以把虚拟存储器想象成一个连续存放数据的小柜子,每个柜子存储的大小都是一个字节 (byte)
正因为那个内存单元有独立且唯一的编号,所以当程序载入内存运行时程序中的变量,常量,函数等才有了唯一的编号,这个编号就是数据的地址。而声明这个地址的类型变量就是指针。
指针的定义与使用:
指针也是一种数据类型,但不是基本数据类型(int ,float , double , char ,long 等 ),而是由其他基本数据类型派生而来的。所以要使用指针首先要声明指针变量。
与指针相关的运算符:
- 取地址运算符 :& ; &m即是变量m在内存中的实际地址
- 间接运算符:* ;它返回其操作数 (即一个指针)所指向的对象的值
示例:
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int num = 10;
int* pnum=NULL; //声明 int 类型指针 并初始化为 NULL
pnum = #//指向变量 num 的内存地址 int 类型指针
float f1 = 2.2;
float* pf1 = NULL;//声明 float 类型指针 并初始化为 NULL
pf1 = &f1; //指向变量 f1 的内存地址 float 类型指针
double d1 = 3.1415926;
double* pd1 = NULL;//声明 double 类型指针 并初始化为 NULL
pd1 = &d1;//指向变量 d1 的内存地址 double 类型指针
printf("num=%d ; f1=%.1f ; d1=%.7f\n", *pnum, *pf1, *pd1);
printf("使用指针改变变量的值:\n");
*pnum = 100; // * 取出指针地址对应的值
*pf1 = 19.9;
*pd1 = *pd1 * 2;
printf("num=%d ; f1=%.1f ; d1=%.7f\n", num, f1, d1);
printf("输出变量地址:\n num =%p ; f1=%p ; d1=%p\n", pnum, pf1, pd1);
printf("mina() 函数的地址:%p\n", &main);//函数名就是函数的首地址
printf("\n\n--------------------------------\n\n");
return 0;
}
小结:
1:指针变量在使用前必须初始化
int main(void)
{
int n = 10;
int* p;
*p = 12;
printf("p=%p ; *p=%d \n", p, *p);
return 0;
}
声明了一个指针变量 p,然后进行赋值操作。但是 p 究竟指向那个地址?我们声明了这个变量,但是未对其进行初始化,所以没有办法知道赋的值将存在那个地址,从这一点看,指针变量和其他变量并无区别,如果变量是静态的,它会被初始化为0;但是如果是自动的,它根本不会被初始化。无论哪种情况,声明一个指向整型的指针都不会 “创建” 用于存储整型值的内存空间。
一个更为严重的问题是:这个指针偶尔可能包含一个合法地址,接下来你就修改了那个地址存储的值。虽然你并不是要去修改它。这种类型的错误难以捕捉,因为引发错误的代码可能与原来操作那个值的代码完全不相干。所以,对指针进行访问时必须小心,确保指针已被初始化。
如果在指针变量声明之初确实不知道该将此指针指向何处,最简单的方式是将其置“0”,C语言中提供了关键字NULL
int *pNum=NULL; 值为NULL的指针称为空指针,这意味着,指针并不指向任何地址。 在头文件 stdio.h 中,NULL 定义为常量。
2:指针只是一个地址,大小是固定的,就是四个字节。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int* pint=NULL;
char* pch=NULL;
double* pd=NULL;
int n1 = sizeof(pint);
int n2 = sizeof(pch);
int n3 = sizeof(pd);
printf("指针大小:\n int 类型=%d ; char 类型=%d ; double 类型= %d \n",n1,n2,n3);
return 0;
}
3:指针和地址的区别:
- 一、指针是个量,对应着一块内存区域
- 指针存储的信息是某个内存单元的地址
比如: int num=10; int *p=# &num 是一个地址,是一个常量 而p是一个指针变量,可以存储一个地址
比如0xFF12500是一个地址:
int *p=(int *)0xFF12500 是一个指针,p存储的是地址,指针有类型,从哪里开始,长度是多少,从哪里结束,得知了类型以后,就知道这片内存数据是如何解析