C/C++指针基础

78 阅读5分钟

指针说明

//定义地址* 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位)

image.png

数组

  • 设计初衷 为了连续的控件开辟
  • 与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的一类函数

image.png

    //指针 数组 数组内部只能放指针
    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);
}