指针说明
//定义地址* char*p;
//int a=10; 取地址& ==>p=&a
//取地址的值 *p;
char p=10;
int a=50;
char *p1 =&p;
int *a1=&a;
//4~7 因为char 一个字节,int四个字节
//cup 默认提是从高位提的 此处的32, char shi 1位 就到了0a处,
//cup 不支持减法,因此必须从高位提取 剑法是通过补码的形式处理的
//int a地址32 00 00 00 00 00 0a 06(char p) 内存对齐
//c语言特性指针
//取地址运算符、指针运算符和自增、自减等单目运算符的优先级相同;
//所有单目运算符的结合性为从右至左。
char c1 =p1-(char*) a1;
printf("c1 地址:%d\n",c1);
指针+1操作方案是根地址走的
int aar[10];
char *p =aar;
//因为是数组类型切为 int
p++;//每次 + 4
char *q=&aar;
表示类型是int[10]
q++;//每次+ 4 *10 =40
- 1、地址是从又往左读的,
- 2、char 暂用一个字节
- 3、int4个字节
- 4、char之后代码自动补全了
- 5、指针步长是跟数据类型走的 int=>4 int[4]=>4*4
- 6、数组传递到函数中 相当于传递的是指针(8位)
数组
- 设计初衷 为了连续的控件开辟
- 与malloc(20)区别:malloc 含义 是只分配控件
- 数组-- 分配空间+提取规则( 一次性提取几个)
- int arr[10] -- 代表在内存中分配10个空间 以4个单位为一个整体 分配40个单位。
- 目的:更规则的提取与保存数据
- 注意点:数组长度定义[num] num是以宏的方式定义,因此只接受常量
- 数组定义好了规则的地址空间就已经开辟好了,如果用变量不会给你开辟空间,只是默认给你提了一个地址
- 数组也是一种特殊的指针,只是可以根据类型规范的提地址,数组默认是数组首个元素的地址
//[] ,下表引用操作符。其实就是数组访问的操作符,也就是连续空间的操作符
//取地址,然后递增地址
int aar1[10]={0};
aar1[11]=100;
//此处不会数组越界,c中无数组越界,数组越界不是语言成面的而是业务层的逻辑,
//java中只是为了处理这种业务,业务层帮我们做了封装
printf("aar1[11]:%d\n",aar1[11]);//打印 100
二维数组
- 本质也是数组,开辟一串连续空间
int aar2[3][4]={0};//总共开辟连续的4*(3*4)=48 个字节的空间
char *p2 =aar1;//aar1 打印出来的是aa2[0] 的地址
p2=p2++;//每次递增 int 4*4=16位
//此处aar[] 等价于 int* aar
void info(int aar[]){
int s=(int )(&aar+1)-(int )(&aar);//s=8 * 步长为8
//
int q=(int )(aar+1)-(int )(&aar);//此处表示数组+1,
}
数组指针 指针数组 指针函数 函数指针
- 符号优先级()>[]>*
- intp[]==>int (p[]) int* 类型的 p[]
指针类型的数组 - int(*p)[]==>int[] (*p) int[] 类型的 *p
数组类型的指针 - 数组指针 数组类型的指针 表示指针指向数组
- 指针数组 指针类型的数组 表示数组里面存放的是指针
- 指针函数 指针类型的函数 表示指针指向函数 int * func(int a,int b);
int * func(int a,int b); 只是一个函数 返回值是int*
- 函数指针 函数类型的指针 表示 int (*func) (int a,int b) func代表函数一般用于定义变体
int (*func) (int a,int b)
func 代表参数(int a,int b)返回值int的一类函数
//指针 数组 数组内部只能放指针
int a[]={1,2,3,4};
int b[]={2,3,4,5};
int c[]={3,4,3,2};
int *p[]={a,b,c};
//数组 指针 指针类型的数组
int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};
//数组指针 步长依据的是类型 此处*p 的类型是int[4]步长为4*4=16 p的步长=8*4*4
int (*p)[4];//==>int[4] *p p是指针 指针类型为int[4]
p=a;//
```
int a[3][4]={0,1,2,3,
4,5,6,7,
8,9,10,11};
int(*p)[4];
p=a;
//p表示存储的是a的地址实际上就是二位数组a 的首地址 a[0] +1加一个a[]
printf("p的步长:%d",(int)(p+1)-(int)(p));//16
//*p 取p指针的值 实际上就是取的a数组的首地址a[0]的值 +1加一个步长
printf("*p的步长:%d",(int)(*p+1)-(int)(*p));//4
printf("*p的步长:%d",p);
int a[]==数组类型 开辟的存储空间=数据类型*长度
&a +1 == int *p =&a p++;
int*p =指针类型 固定长度8
eg:
&a+1运算,具体走多少个地址,根据数据类型空间来的
&a+1数据类型=数组+1 计算的是数组的开辟空间长度
&a+1数据类型=指针类型+1 计算的是指针类型+1=8 固定长度移动8位
int aar[]
aar+1 数组类型默认在计算的时候 步长=int类型 默认是4
//此处函数内部就没有数组概念了
//此处aar[] 等价于 int* aar
void info(int aar[]){
//因为aar就已经是地址了 此处aar=外部传进来的&aar
//aar+1=>aar+int的长度
//&aar 因为aar是外部传入的==外部&aar 内部&aar==外部&(&aar)
int a=(int )(aar+1)-(int )(&aar);//s=36
int b=(int )(&aar+1)-(int )(&aar);//s=8 * 步长为8
}
//此处 aar等价于int *aar[4]
//此处aar就是一个数组指针
void info1(int aar[][4]){
}
void main(){
int aar[10]={0};
//实际上函数传递的是aar的地址
info(aar);
}