C语言二级指针

C 指针 | 菜鸟教程

1 概念

内存默认以   byte   排序。(可以理解为一维字节数组)

汽油以升(byte)为单位,你加一次油是50升,老板加一次油是88升

因为汽车类型有大小,(这里称 元素种子 大小)。

所以,每次加油(指针每次加1),跨过的 byte 字节数量,等于 元素种子的大小

//有些人称此为: 步长

2 指针用法

    & 取对象的地址                  以对象的值【Value】做地址

u16  A = 10 ; // 内存地址段上取 16bit ,别名 A 
u32  B = 11 ; // 内存地址段上取 32bit ,取名字叫 B
int  *p;   // 分2步理解: 1 整个内存切割成int块,取出一个可用的int块,取名字叫 *P
                         2 把*p拆开,p保存的是int块的编号。【总内存分割int块后的编号】
                         3 p的计数类型是int
【就相当于你有1000元,换成2元一张的钞票,能换多少张,钞票的张数编号就是地址编号】
【           1000元,换成5毛一张的钞票,能换多少张,钞票的张数编号就是地址编号】

p = &A;   // 取出 A地址编号 给 p对象的Value

*p = 22 ; // 这样 A的值是22 
          // 【*p】对象p的Value做地址,找到这个地址后,在地址上赋值22,实际就是A=22
u16  A = 10 ; // 内存地址段上取 16bit ,别名 A 
u32  B = 11 ; // 内存地址段上取 32bit ,取名字叫 B
Byte  *p;   // 分2步理解: 1 整个内存切割成Byte块,取出一个可用的Byte块,取名字叫 *P
                         2 把*p拆开,p保存的是Byte块的编号。【总内存分割Byte块后的编号】
                         3 p的计数类型是int
【就相当于你有1000元,换成5元一张的钞票,能换多少张,钞票的张数编号就是地址编号】
【           1000元,换成20元一张的钞票,能换多少张,钞票的张数编号就是地址编号】

p = &A;   // 取出 A地址编号 给 p对象的Value

*p = 22 ; // 这样 A的值是22 
          // 【*p】对象p的Value做地址,找到这个地址后,在地址上赋值22,实际就是A=22


注:思考下【p的计数类型是int】 ++P后,地址偏移8bit长度。

 这相当于:【零件盒子装钥匙】和【集装箱装钥匙】,集装箱地址加1偏移的bit就大。而钥匙始终

是CPU的int计数类型。

type *var_name;

type 是指针的基类型,它有 int,double,float。。。。等等

int  *ptr = NULL;
int    *ip;    /* 一个整型的指针 */
double *dp;    /* 一个 double 型的指针 */
float  *fp;    /* 一个浮点型的指针 */
char   *ch;    /* 一个字符型的指针 */

是把总的内存切割成 type块,然后再去找第type块的偏移位置

 p也是个对象,它存储的值做地址使用,【*p】定位到对象p的值【Value】的地址上

可以理解成,p存储的是指针值。

【*p】定位到指定的地址上,等待操作

   *( volatile int * ) 0x80 = 0x81;

// 方向从右向左
// *取地址
// 系统总内存切割成【volatile int】长度的块,然后找到编号第0x80的块
//  int* 0x80  总内存切割成 int块,偏移到 0x80的位置  //相当于【int长度乘以0x80】 
//  
//  最左边的*是取地址: 【int *】只是int被省略了,
                                 *0x80地址的值 num
                                 *num地址的位置上,再赋值0x81;

//  最左边的*是取地址: 取出对象【*0x80】的值add,然后取对象【*add】给它赋值 0x81

 3 二级指针:【从右到左】先获取地址,再对参考类型偏移

语法  int **P = NULL;    // 实际完全体是【int*  int* P】

*(*P)  // 从右向左

分析:
      先 *P   //【int *】这里int可以略写, 得到了地址编号 ,
      再 *    //在编号地址上开垦 int类型的长度,等待被赋值。

*P  这个P也是个对象,它的类型type,把总内存切割成tpye块,P的值,就是第n个type块地址,
有了这个地址后,再对他操作。

*  左边也有类型int,就是把总内存切割成int块,第n个【int块】的地址上,再对它操作。


参考:
  const int *  const int *  P = NULL;
  byte *  type_对象类型 * P = NULL;

byte *  byte * P = NULL;

4函数指针:

函数指针变量可以作为某个函数的参数来使用的
typedef int (*fun_ptr)(int,int); // 声明一个指向同样参数、返回值的函数指针类型

int max(int x, int y)
{
    return x > y ? x : y;
}
 
int main(void)
{
    /* p 是函数指针 */
    int (* p)(int, int) = & max; // &可以省略
    int a, b, c, d;
 
    printf("请输入三个数字:");
    scanf("%d %d %d", & a, & b, & c);
 
    /* 与直接调用函数等价,d = max(max(a, b), c) */
    d = p(p(a, b), c); 
 
    printf("最大的数字是: %d\n", d);
 
    return 0;
}
typedef unsigned char u8;
地址从0开始自增;地址类型就是cpu类型,且不能被改变。比如32位的cpu地址只能到4g
用*取址符,可以在地址上存放用户类型的数据。比如char或者student

绝对地址每次加1,间隔一个字节;(如果类型+1,就要看这个类型占多少个字节)
*地址     //解释为找到该地址;(取值)或者说:取址符,取出地址上的值
&            这个符号是取地址。
数组的名字就是首地址。    *数组名(就是数组【0】下标0存储的值)

char *地址  //解释为,找到该地址后,取出 char类型的左值;
int *地址  //解释为,找到该地址后,取值 int类型;


int *app  //app为变量,它有自己的地址,可以用&app取出地址。
int *app  //app为变量,可以赋值。 app=(int *)0xfff2018

 函数名 delay()   等效于  #define delay    *APP

地址可用长度由设备决定。32位机器最大4GB。

const1    int*    const2    *APP

 *(int[]){1,2}=99;      //匿名数组int【2】,第一个下标值【0】改为99
int *ppp(int X,int Y);
&main();


地址指针*(volatile int*)0x40020010=data;//方向,从右到左

第1*号是 取地址,第2*号是左值类型值(强制类型转换)。0x40020010是地址,data是给左值赋值用的,在地址0x40020010上赋值。
先将0x40020010转为地址类型,再*取址符,取出这个寄存器上的值,再把data的值放到这个寄存器上。


指针*(int*)0x80=0x8f;int *p=(int*)0x80;取地址int *p=&i;*p为房间号*p=NULL;//0给*p这个房间static静态typedef extern continue sizeof const





4级指针:

以下是2级指针、3级指针和4级指针的C语言Demo:

2级指针:

```
#include <stdio.h>

int main() {
    int a = 10;
    int *p1 = &a;
    int **p2 = &p1;
    printf("a的值为:%d\n", a);
    printf("p1指向的值为:%d\n", *p1);
    printf("p2指向的值为:%d\n", **p2);
    return 0;
}
```

3级指针:

```
#include <stdio.h>

int main() {
    int a = 10;
    int *p1 = &a;
    int **p2 = &p1;
    int ***p3 = &p2;    printf("a的值为:%d\n", a);
    printf("p1指向的值为:%d\n", *p1);
    printf("p2指向的值为:%d\n", **p2);
    printf("p3指向的值为:%d\n", ***p3);
    return 0;
}
```

4级指针:

```
#include <stdio.h>
int main() {
    int a = 10;
    int *p1 = &a;
    int **p2 = &p1;
    int ***p3 = &p2;
    int ****p4 = &p3;
    printf("a的值为:%d\n", a);
    printf("p1指向的值为:%d\n", *p1);
    printf("p2指向的值为:%d\n", **p2);
    printf("p3指向的值为:%d\n", ***p3);
    printf("p4指向的值为:%d\n", ****p4);
    return 0;
}
```

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值