1.变量的地址
变量对应内存中的一段存储空间,该段存储空间占用一定的字节数,可能是 1个字节,也可能是 4 或是 8 个字节,用这段存储空间的第一个字节的地址表示变量的地址,即低位字节的地址。
变量的地址,可以通过 Reference (&) 引用运算符取得,在此可以称为取地址运算符。
例子如下:
#include <stdio.h>
int main(void)
{
int a; int b;
printf("&a = %p\n",&a);
printf("&b = %p\n",&b);
return 0;
}
2.地址的大小
#include <stdio.h>
int main(void)
{
char a ; short b; int c; long d;
float e; double f;
// 是一种 32 位 16 进制的整数
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
printf("&d = %p\n", &d);
printf("&e = %p\n", &e);
printf("&f = %p\n", &f);
//类型不同,大小相同,均为 4 字节
printf("sizeof(&a) = %d\n", sizeof(&a));
printf("sizeof(&b) = %d\n", sizeof(&b));
printf("sizeof(&c) = %d\n", sizeof(&c));
printf("sizeof(&d) = %d\n", sizeof(&d));
printf("sizeof(&e) = %d\n", sizeof(&e));
printf("sizeof(&f) = %d\n", sizeof(&f));
return 0;
}
通过运算的方式,我们可以求得变量的地址。 32 位机的情况下,无论是什么类型,变量的地址大小均是 4。而 64 位机大小均是 8。这是由当前机型的地址总线决定的。
3.间接访问内存
dereference (*) 解引用运算符,在此处我们可以称为,取内容运算符。用法如下:
int main(void)
{
char a = 1 ; short b=2; int c=3;
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
printf("a = %d\n", *(&a));
printf("b = %d\n", *(&b));
printf("c = %d\n", *(&c));
return 0;
}
4.指针常量
指针是有类型地址常量
#include<stdio.h>
int main(void)
{
char a = 1 ; short b=2; int c=3;
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
printf("a = %d\n", *((char*)0x0060FEAF));
printf("b = %d\n", *((short*)0x0060FEAC));
printf("c = %d\n", *((int*)0x0060FEA8));
return 0;
}
#include<stdio.h>
int main()
{
int data = 0x12345678;
printf("%p\n",&data);
printf("%x\n",*(&data));
printf("%x\n",*((int*)0x0060FEAC)); //这是本人电脑data所在的地址复制下来的,结果相同
printf("%x\n",*((char*)0x0060FEAC));//结果为:78
printf("%x\n",*((short*)0x0060FEAC));//结果为:5678
return 0;
}
通过上面这个例子可以知道,指针的本质是一个有类型的地址,类型决定了,从这个地址开始的寻址能力。
(由于我们PC遵从小端序,所以我们的寻址能力就是看包含多少个字节,从78开始寻址)
5.指针变量
一个指针是一个有类型地址,是一个有类型的常量。用以存放指针的量,我们叫作,指针变量。一个指针变量却可以被赋予不同的指针值,可以能过指针变量改变指向和间接操作。
指针变量的定义:
type * variable;
* 表示该变量是一个指针变量
type 表示该变量的内存放的地址的寻址能力
6.指针运算
#include<stdio.h>
int main()
{
int a = 0x0001;
printf("a = %#x a+1 = %#x\n",a,a+1); //这里是int的运算,直接加1
int *p = (int*)0x0001;
printf("p= %#x p+1 = %#x\n",p,p+1);//这里是 int * 的运算,加的是步长,所以加4
int aa = 0x0008;
printf("aa = %#x aa-1 = %#x\n",aa,aa-1);//这里是int的运算,直接减1
int *q = (int*)0x0008;
printf("p= %#x p-1 = %#x\n", q, q-1);// int * 的运算,所以减4
int arr[10];
int * pHead = &arr[0]; int* pTail = &arr[9];
printf("%d\n",pTail-pHead); //结果为9,有9个跨度
//arr[0]+8 = arr[9] ,即 arr[0]+8*sizeof(int) = arr[9]
int ppHead = (int)&arr[0]; int ppTail = (int)&arr[9];
printf("%d\n",ppTail-ppHead); //结果为36
return 0;
}