c语言——指针
一、指针的概况
1.什么是指针?
- c语言访问内存的工具
2.明明CPU可以通过变量名(如 a)对内存(a的家)进行有名访问,为什么还要有指针?
为了解决无名访问问题(在没有a的情况下进入a家),把内存的本质暴漏给程序员(把a家的地址暴漏给小偷(bushi),这样程序员就可以直接操作内存。
3.C语言的目的就是为了操作计算机运行的本质。(c语言指导cpu和内存和谐生活)
4.C语言如何描述一个地址?学习指针吧
5.两大体系结构:
- 冯诺依曼结构:指令和数据放在同一个存储器。一个地址就可以访问。
- 哈佛结构:程序(即指令)和数据放在不同的储存器,分开管理。
二、如何表示地址这个类型?
1.如何描述一个有名空间?
- 这个空间叫什么?(名字)
- 这个空间多少字节?(容量)
2.如何描述一个地址?预留一个模子来圈地,能够存储地址
- 这个空间有多大?(数据类型的容量大小),比如int类型占4个字节。
- 对于这个地址指向的空间如何访问?(这个指针指向空间的操作行为),比如以1B 、2B或 4B来访问。
- 如果无法回答以上的两个问题,编译器就无法对这个变量进行定义)
3.指针:
- 指针本身的大小是固定的,它取决于系统的架构(32位系统通常是4字节,64位系统通常是8字节)。
- p+1:表示以p为首地址,加一个元素后的地址
4.c语言编译器内部的逻辑:以一个中心节点,先向右看,再向左看,确定变量行为。
- 例如:
int p1;
//编译器以p1为中心节点,向右看“;”,认识分号无解。向左看int,认识int,解为p1是int的空间变量
int p2[5];
//编译器以p2为中心节点,向右看认识[]和5,识别出p2[5]是5个元素的数组
//向左看int,认识int,识别p2是5个int类型元素的连续空间变量(即数组)
//5个元素,每个元素int大小
int p3[5][4]
//p3[5] 有5个元素,这5个元素中每个元素都有一个连续空间
//p3[5][4] 5个元素后又有4个元素,这4个元素中每个元素都有一个连续空间
//int p3[5][4]连续空间中每个空间的容量都是int大小
- 指针类型的:
-
int *p4; //第一步,向右,读取p4,不知道p4什么意思。 //第二步,继续向右,读取“;”,没用。 //第三步,向左,读取*,因为已经读取过p4了,所以整体为*p4,p4升级为一个可以保存地址数据的空间 //第四步,继续向左,读取int,得出每个元素的空间容量是int大小 //这个空间有多大?4B或8B( 由计算机本的寻址能力决定) //这个空间指向的位置如何访问p p+1 p+2的差距?int可以体现
5.指针的访问类型
-
一维数组:
-
void test03() { int* p5[6];//p5是连续空间的首地址标识,有6个元素,每个元素都是地址,以int访问 //6个箱子,每个箱子里都有1把钥匙,用int的方式来打开箱子 int(*p6)[6];//p6是一把钥匙(即指针),以6个连续空间的int形式来访问内存 //一把钥匙,可以用int的方式同时打开6个箱子 }
多维数组
-
//多维数组类型的访问 void test04() { int p1[6];//p1是数组的首地址 int p2[5][4];//p2是数组的首地址 int p3[5][4][3];//p3是数组的首地址 int* x1 = p1;//接收p1的地址 int(*x2)[4] = p2;//接收p2的地址 int(*x3)[4][3] = p3;//接收p3的地址 }
函数类型的:
-
//函数类型的访问 void test05() { int* p7(double a); //p7是一个函数名,输入一个double类型的参数a,p7函数返回一个int类型的地址 int (*p8)(double a); //p8是一个指针(地址),输入一个double类型的参数a,返回一个int类型的p8函数地址 int (*p9[8])(double a); //p9是一个连续空间首地址,输入一个double类型的参数a,返回一串有8个int类型的p9函数地址 }
例题:
-
#include<stdio.h>; void test01() { int* p1 = (int*)0x100;//p1是变量, char* p2 = (char*)0x100;//p2是变量 char p3[5];//p3是常量 char* p4[5];//p4是变量 char(*p5)[5]=(char(*)[5])0x100;//p5是变量 char p6[6][5];//p6是常量 printf("the p1:%p,p1+1:%p\n", p1, p1 + 1);//104 printf("the p2:%p,p2+1:%p\n", p2, p2 + 1);//101 printf("the p3:%p,p3+1:%p\n", p3, p3 + 1);//+1 printf("the p4:%p,p4+1:%p\n", p4, p4 + 1);//+8 printf("the p5:%p,p5+1:%p\n", p5, p5 + 1);//105 printf("the p6:%p,p6+1:%p\n", p6, p6 + 1);//+5 } int main() { test01(); }