一、C语言初阶:指针

2023-11-10

1 指针

1.1 指针的算术运算

  • 指针移动
    int arr[] = {1,2,3,4,5};
    int* p = arr;
    int* q;
    // 移动指针顺序打印
    for(int i = 0;i < 5;++i){
        q = p+i;
        printf("%d ",*q);
    }
    printf("\n");
    // 移动指针倒序打印
    for(int i = 0;i < 5;++i){
        p = q-i;
        printf("%d ",*p);
    }
    printf("\n");
    printf("%d\n",q-p); //计算指针p和指针q的间距
  • 指针自增自减
    int arr[] = {1,2,3,4,5};
    int* p = arr;
    printf("%d\n",*p++);
    for(int i = 0;i < 5;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
    // 1
    // 1 2 3 4 5

    p = arr;
    printf("%d\n",*++p);
    for(int i = 0;i < 5;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
    // 2
    // 1 2 3 4 5

    p = arr;
    printf("%d\n",++*p);
    for(int i = 0;i < 5;++i){
        printf("%d ",arr[i]);
    }
    printf("\n");
    // 2
    // 2 2 3 4 5

1、前两种改变变量的值,后一种改变arr元素
2、++、- -和解引用*的结合顺序为自右向左

1.2 指针类型

  • 指针大小
    无论指向什么类型,所有指针的大小都是一样的,都是地址的大小
    char* c;
    int* a;
    long* p;
    printf("%d\t%d\t%d\n",sizeof(c),sizeof(a),sizeof(p));
    // 8  8  8
  • 类型转换
    指针类型转换没有改变指针内的地址,也没有改变指针指向的值,只是改变了移动的单位长度。
   char* str = "abcde";
    int*p = (int*)str;
    printf("%c\n",*++p);
    // e 
    // int型大小为4,所以从arr[0]移动至arr[4]
  • void*
    void*是一种很特别的指针,表示指向未知类型的指针,并不指定它是指向哪一种类型的数据,而是根据需要转换为所需数据类型。
    int a = 10;
    void* p = &a;
    printf("%d\n",*(int*)p);

    char c = 'a';
    p = &c;
    printf("%c\n",*(char*)p); // 强转后解引用
    // printf("%c\n",*p);

1.3 指针作用

1、函数需要多个返回值时,作为返回值参数。
2、传入数组后,对数组做操作。
3、较大数据结构体传入时做参数。
4、动态申请内存。
5、避免使用未初始化指针、空指针和野指针。

1.4 二维指针

  • 指针是变量,变量有地址,指针也有地址。(三段论)
	int n=10;
	int *p = &n; // *p是指向int变量的指针
	int* *pp = &p; // **p是指向int指针的指针
	printf("&p:%p p:%p *p:%d",&p,p,*p);
	printf("pp:%p *pp:%p **pp:%d",pp,*pp,**pp);

1.5 指针数组

存放指针的数组,指针数组是多个指针变量集合

    int a = 1;
    int b = 2;
    int c = 3;
    int* p[] = {&a,&b,&c};
    for(int i=0;i<3;++i){
        printf("%d\n",*p[i]);
    }
    for(int i=0;i<3;++i){
        printf("%d\n",**(p+i));
    }

1.6 二维指针 vs 二维数组 vs 指针数组

    int arr[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
    for(int i=0; i<3; ++i) {
        for(int j=0; j<4; ++j) {
            printf("%d ",arr[i][j]);
        }
        printf("\n");
    }
    int* parr[] = {arr[0],arr[1],arr[2]};
    for(int i=0; i<3; ++i) {
        for(int j=0; j<4; ++j) {
            printf("%d ",parr[i][j]);
        }
        printf("\n");
    }
    int** p = parr; // 指针数组可以赋值为维指针
    for(int i=0; i<3; ++i) {
        for(int j=0; j<4; ++j) {
            printf("%d ",p[i][j]);
        }
        printf("\n");
    }   
    // int** p2 = arr; //二维数组不可直接赋值给二维指针

1、指针数组与二维数组相同点:访问数组元素方式。
2、arr[0],arr[1],arr[2]是数组名,parr[0],parr[1],parr[2]是指针,所以只是形式上的一直,内存表示上是不同。(数组名是值,指针是变量)
3、指针数组数组名可以直接赋值给二维指针。
4、二维数组数组名不可以直接赋值给二维指针。
5、二维指针操作与指针数组可以认为完全一致;二维数组操作与指针数组部分一致(访问元素上一致;但是指针数组内存放地址可以修改,二维数组数组名表示地址不能修改);

1.7 常量指针 vs 指针常量 vs 常量指针常量

  • 常量指针 const int* p
    可以写作int const* p,p是int*类型,const修饰的是 * p,所以 * p是常量,表示p指向的地址里的值不可修改,也就是说,*p里的值不能再重新赋值了,但是可以修改p指向的地址。
  • 指针常量 int* const q
    q是int*类型,那么const修饰的是q,所以q是常量,表示q指向的地址不可修改,即q不能再指向别的地方了,但是可以修改p指向的这个地址里的值。
  • 常量指针常量 const int* const p
    p是int类型,两个const分别修饰了p和p, 所以p和*p都是常量,表示p指向的地址不可修改,同时p指向的地址里的值也不可修改。
    int a = 10;
    int b = 20;
    // 常量指针
    const int* p = &a;
    p = &b; // p指向的地址可以修改
    // *p = 100; //不可以改指向地址里的值
    printf("%d\n",*p);
    // 指针常量
    int* const q;
    // q = &b; // q指向的地址不能修改
    *q = 200; // 可以修改指向地址里的值
    printf("%d\n",*q);
    // 常量指针常量
    const int* const p1 = &a;
    // p1 = &b; //p1指向地址不能修改
    //*p1 = 100; //地址里的值不能修改

1.8 字符串数组 vs 字符串指针数组

  • 字符串数组
char arr[12][10] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
char arr[][10] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
  • 字符串指针数组
char* arr[12] ={"January","February","March","April","May","June","July","August","September","October","November","December"};
char* arr[] ={"January","February","March","April", "May","June","July","August","September","October","November","December"};
  • 二者的区别
  • 1、大小的区别
    char* arr2[12] = {"January","February","March","April","May","June","July","August","September","October","November","December"};
    printf("%d\n",sizeof(arr2[0]));
    printf("%d\t%d\n",sizeof(arr),sizeof(arr2));
    // 8
    // 120 96
  • 2、二维指针的区别
int main () {
    char arr1[][10] = {"January","February","March","April",
                 "May","June","July","August",
                 "September","October","November","December"};
    char* arr2[] = {"January","February","March","April",
               "May","June","July","August",
               "September","October","November","December"};
     /*
    char** p1 = arr1;
    for(int i=0;i<12;++i){
        printf("%s\n",p1[i]);
    }
    */
    char** p2 = arr2;
    for(int i=0;i<12;++i){
        printf("%s\n",p2[i]);
    }
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

一、C语言初阶:指针 的相关文章

随机推荐

  • nginx中间件漏洞复现

    nginx中间件漏洞复现 nginx介绍 Nginx engine x 是一个高性能的HTTP和反向代理web服务器 同时也提供了IMAP POP3 SMTP服务 Nginx是由伊戈尔 赛索耶夫为俄罗斯访问量第二的Rambler ru站点
  • VMware虚拟机中调用本机摄像头详解

    本机环境 虚拟机 VMware Workstation 16 Player 虚拟机内系统 Centos7 其它也ok的 本机 win10 任何系统都ok 调用本机摄像头 首先wins R输入services msc 打开本地服务列表 确保
  • Java图片透明度调整

    package com image import java awt AlphaComposite import java awt BorderLayout import java awt Graphics import java awt G
  • Java 实现 Base64 加密&解密方法

    1 Base64 加密算法 1 1 标准 Base64 算法 Base64 编码是程序开发中比较常用的一种编码算法 是常用来存储或传输一些二进制数据的方法 也是 MIME 多用途互联网邮件扩展 中的一种编码方法 Base64 可以实现将任何
  • Spring Boot - swagger2 整合

    swagger官网 https swagger io 一 引入依赖
  • 怎么用系统做固定资产管理

    企业如何高效地管理其固定资产已成为了一个不容忽视的问题 传统的资产管理方式往往依赖于人力和纸质记录 这种方式不仅效率低下 而且容易出错 因此 引入一个先进的固定资产管理系统显得尤为重要 本文将探讨如何使用系统进行固定资产管理 并提出一些创新
  • win7无法访问服务器共享文件夹解决办法

    方案 今天的工作本来安排的好好的 本来都已经在开始高效的做事情了 因为服务器要安装一个驱动程序 在安装好了之后结果发现自己的电脑再也没有办法连接到服务器的共享了 真是恼火 造理说我也是可什么设置都没有动过啊 我就只是用下网络的共享服务而已那
  • Eclipse配置

    一 eclipse安装时选择的专门开发java项目的Eclipse IDE for Java Developers 因此没有new Dynamic Web Project 属于JavaEE 选项 方法1 直接安装JavaEE版本eclips
  • 开源ehr系统_国家通过开源EHR节省数百万美元

    开源ehr系统 自从2009年成为 经济和临床健康卫生信息技术 HITECH 法案 的基石以来 电子健康记录 EHR 在美国卫生系统中已无处不在 EHR使医疗保健提供者可以跟踪患者的医疗数据 并与其他授权方共享 VistA是美国退伍军人事务
  • orz项目编译的要点

    Orz 0 4 0 AllInOne iso 的编译指导 其实也没有什么需要指导的 只是想说明 这个过程是很容易的 要有信心 下载到Orz 0 4 0 AllInOne iso之后 按照文档readme hta来操作 因为这是个很老的教材
  • 2008.06.02 读华为前执行副总裁李玉琢的《我与商业领袖的合作与冲突》有感(三)

    理解一下书中提到的几点管理思想 和大家一起分享 1 柳传志的 搭班子 定战略 带队伍 这里需要注意的是搭班子 定战略 带队伍顺序不可乱 为什么这样说 一个组织只有先存在核心 才可能确定明确的战略 不同的核心 定出来的战略就可能不一样 因此是
  • 力扣202.快乐数(java语言HashSet方法,类双指针方法)

    前言 此题被分类到散列表算法题目中 但乍一看此题实在想不到如何去使用散列表 直到看了官方给的答案 题目描述 编写一个算法来判断一个数 n 是不是快乐数 快乐数 定义为 对于一个正整数 每一次将该数替换为它每个位置上的数字的平方和 然后重复这
  • 2021年度

    践行开源共创的精神 FISCO BCOS开源社区致力打造开放多元的开源联盟链生态 目前 社区已汇聚了超70000名社区用户 大家聚集于此碰撞观点 交流技术 围绕FISCO BCOS开发各类实用的应用组件 持续优化项目 并自发输出技术解析 使
  • 使用Java写入Excel下拉选择框选项过多不显示问题

    1 问题描述 工作中遇到需要使用Java poi读写Excel文件的问题 因为需求中有要求在写文件时创建下拉选择框 按照传统的直接使用List集合保存下拉选择框的选项 再通过poi本身的方法将选择框的选项添加到下拉框中 一开始编写demo测
  • 【01】花卉识别-基于tensorflow2.3实现

    2021年6月18日重大更新 目前已经退出bug修复之后的tensorflow2 3物体分类代码 大家可以训练自己的数据集 快来试试吧 csdn教程链接 手把手教你用tensorflow2 3训练自己的分类数据集 CSDN博客 b站视频链接
  • APP自动化测试-4. App控件交互

    APP自动化测试 4 App控件交互 文章目录 APP自动化测试 4 App控件交互 前言 一 元素常用的操作方法 二 元素的常用属性 总结 前言 简单介绍元素的操作方法和元素的属性 一 元素常用的操作方法 click 元素点击 send
  • Mybatis使用in传入List的三种方法

    1 非xml方式 使用注解传in 要使用 Select
  • 全国计算机等级考试三级数据库技术(十一)

    第十一章 故障管理 考点分析 在考试中一般情况下会出现在选择题 填空题部分 常考知识点有 1 掌握故障类型及相应的解决方法 2 掌握数据转储与日志文件的相关内容 3 掌握RAID的冗余技术和服务器容错技术 4 熟悉数据库镜像与数据库容灾 1
  • Java 实战项目-- 家庭记账程序

    模拟实现一个基于文本界面的 家庭记账软件 该软件能够记录家庭的收入 支出 并能够打印收支明细表 项目采用分级菜单方式 主菜单如下 具体要求 查询收支明细 菜单1 时 将显示所有的收入 支出名细列表 每次登记收入 菜单2 后 收入的金额应累加
  • 一、C语言初阶:指针

    1 指针 1 1 指针的算术运算 指针移动 int arr 1 2 3 4 5 int p arr int q 移动指针顺序打印 for int i 0 i lt 5 i q p i printf d q printf n 移动指针倒序打印