像学生宿舍一样,被分成许多个房间,每个房间都有自己的房号,每个房间能住8个学生
内存被分成许多个单元(小为1Byte),每个单元都有自己的编号,每个单元里能住8个小比特(bite)
c语言中,指针就是该单元内存的编号也就是地址,我们可以通过指针快速找到我们要访问的内存
计算机中的内存编址,是通过硬件设计来完成的,也就是说他被做出来的时候各个内存单元的地址就已经确定了。
计算机中硬件之间数据的传递依赖3条“线”:
数据总线:用来传输数据
控制总线:控制数据的读(read)和写(write)
地址总线:提供需要传输的数据的内存地址
32位的计算机有32根地址总线,一根总线可以表示2个含义(有脉冲:1和无脉冲0)
32根则能表示2的32次方个含义,每一个含义表示一种地址。
2.1取地址操作符(&)
&取出的是较小的字节地址
比如创建一个整型变量a,&a取的是该整型所占据的4个字节中位最低的那个字节内存地址
取出最小字节地址后,我们顺藤摸瓜也能访问到整个a所占据的内存数据。
指针变量也是变量,用来存地址,被存到指针变量的值都会被理解为地址。
#include
int main()
{
int a = 10;
int * pa = &a;//取出a的地址并存储到指针变量pa中
return 0;
}
pa的类型是int*,怎么理解?
* 说明pa是指针变量,int说明指针指向的是整型类的对象
以此类推,char类型的变量需要放在什么类型的指针变量中呢
#include
int main()
{
int a = 100;
int* pa = &a;
*pa = 0;
return 0;
}
这里*pa其实就是a变量了,(通过解pa中存放的地址,找到指向的空间)
在这里,这一步看似多余,但是当代码复杂起来之后,解指针的运用可以使代码更加灵活
由上文知,32位机器由32个地址总线,我们把每一根转化成数字信号0或者1之后,32个总线组成的一个二进制序列看做一个地址,那么一个地址就是32个比特位,需要4个字节才能储存。
64位同理,需要8个字节。
那么我们就可以知道在同一个平台,指针变量的大小相同。
代码1
#include
int main()
{
int n = 0x11223344;
int *pi = &n;
*pi = 0;
return;
}
代码2
#include
int main()
{
int n = 0x11223344;
char *pc = (char *)&n;
*pc = 0;
return 0;
}
#include
int main()
{
int n = 10;
char *pc = (char*)&n;
int *pi = &n;
printf("%p\n", &n);
printf("%p\n", pc);
printf("%p\n", pc+1);
printf("%p\n", pi);
printf("%p\n", pi+1);
return 0;
}
结论:指针的类型决定了指针向前或向后走一步有多大 ,如这边char*类型的指针一次走1个字节单位,而int*类型一次走4个字节。
即无具体类型的指针,这种指针可以接受任意类型地址,但是不能直接进行加减整数和解引用的运算。
以数组来举例,数组名就是首地址
#include
//指针+- 整数
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];//数组名就是首地址,这里&arr[0]可以改成arr
int i = 0;
int sz = sizeof(arr)/sizeof(arr[0]);
for(i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//p+i 这⾥就是指针+整数
}
return 0;
}
该代码可以实现依次打印数组元素
前提:两个指针指向同一空间—>每一次跳的距离相同
//指针-指针
#include
int my_strlen(char *s)
{
char *p = s;
while(*p != '\0' )//\0的Ascll码值是0,括号里可以写成*p
p++;
return p-s;
}
int main()
{
printf("%d\n", my_strlen("abc"));
return 0;
}
打印的结果时3,指针-指针得到的是两个地址间的元素个数
4.3指针关系运算
#include
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int *p = &arr[0];
int sz = sizeof(arr)/sizeof(arr[0]);
while(p < arr + sz) //指针的⼤⼩⽐较
{
printf("%d ", *p);
p++;
}
return 0;
}