指针
内存
RAM是随机储存
ROM是只读存储器
- 内存的使用就和现实生活中空间的使用非常相似
例如:河南省郑州市郑州科技学院北苑17号楼121宿舍(这就是一个地址)
再把每个房间编号,通过地址找寻房间。
例
把内存划分为好几个格子,对每个格子进行编号。
下面两个问题
1.内存是怎么编号的?
2.一个这样的内存单元是多大?
正常电脑有
32位 - 32根地址线 - 物理线 - 通电 - 1/0(正电是1,负电是0)
64位
1.内存是怎么编号的?
- 电信号转换成数字信号:1和0组成的二进制系列
00000000000000000000000000000000 -一个编号
……
01111111111111111111111111111111(+1)
10000000000000000000000000000000(再+1)
……
11111111111111111111111111111111(再+1)
一个地址线是32位
,32个地址线
就是2^32个二进制序列
,都可以作为内存的编号(内存单元的地址)
2.一个这样的内存单元是多大?
32位电脑可以管理2^32个内存单元,那么一个内存单元是多大?
计算方式:
1 0000 0000 0000 0000 0000 0000 0000 0000
↓ ↓
2^32 = 4,294,967,296 Bit(十进制) 2^0
4,294,967,296 / 8 = 536,870,912 Byte(十进制Byte)
536,870,912 / 1024 = 524,288 Kb
524,288 / 1024 = 512 MB
514 / 1024 = 0.5 G
假设一个bit位给一个地址
char 1字节 = 8 bit -8个地址,分配地址太多,浪费了。
所以我们经过筛选,决定以一个字节为一个地址来编号。
例:对下面代码的a取内存地址
#include <stdio.h>
int main()
{
int a = 10; //a在内存中要分配空间的 - 4个字节
return 0;
}
//按3此F10
0a则是变量a的第一个地址,记作16进制:3C(0x0053FB3C)
0a 00 00 00
3C 3D 3E 3F //以此类推
对照16进制表来推
3.用代码取地址以及创造指针变量(地址会变化)
#include <stdio.h>
int main()
{
int a = 10;//a在内存中要分配的空间 4个字节
printf("%p\n",&a); //%p专门用来打印地址的
//创建指针变量
int * pa = &a; //pa是用来存放地址的,在c语言中pa叫指针变量
//* 说明pa是指针变量
//int 说明pa执行的对象是int类型的
char b ='w';
char * pb = &b; //其中pb就是指针变量
}
指针初始化的一般形式
第一种:数据类型标识符 *指针变量名 = 初始地址值;
int a; //or int a = 1;
int *pa = &a
第二种指针初始的一般形式: 数据类型标识符 *指针变量名
指针变量名 = 初始地址值
int *pa;
pa = &a;
*pa表示一个值,根据指针存放的地址找到空间中的值
int a =1
int *pa = &a
pa = b;//根据指针存放的地址找寻pa的值,然后把b的值赋予,pa代表一个值
//第二种书写方式
printf("%p\t",pa);
printf("%p\n",&pa);
//两种打印地址的方式
*pa = &m 此处是错误的 因为此时pa是一个值,不能等于m的地址
4.当指针变量的地址改变时,值不改变,但解引用之后对其值改变,那么打印的值也会改变。
#include <stdio.h>
void f(int* p, int* q)
{
p = p + 1;
*q = *q + 1;
}
int main()
{
int m = 1;
int n = 2;
int *r = &m;
f(r, &n);
printf("%d,%d", m, n);
}
result
1,3
过程:
①首先定义两个整型变量m
,n
,
②然后定义一个指针变量r
,把m
的地址赋到指针变量r
中。
③执行f(r,&n)
,把数值带入到外函数的运算中,其中指针变量r
对应p
,n
的地址对应q
。
④指针p
对应的是r
(指针r的值是m的地址
),p+1
则改变了r
的地址(也就是改变了m的地址
),!!!注意,虽然改变了m
的地址,但是m
的值不变。
⑤执行外部函数语句的第二句,*q
解引用,则对n的地址解引用找到其中的值,再对值进行计算,最后输出值。