自学内容网 自学内容网

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();
    
    }


原文地址:https://blog.csdn.net/m0_73669390/article/details/143660877

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!