【重拾C语言】七、指针(一)指针与变量、指针操作、指向指针的指针

news2024/11/26 21:49:51

目录

前言

七、指针

7.1 指针与变量

7.1.1 指针类型和指针变量

7.1.2 指针所指变量

7.1.3 空指针、无效指针

7.2 指针操作

7.2.1 指针的算术运算

7.2.2 指针的比较

7.2.3 指针的递增和递减

7.3 指向指针的指针


前言

  • 指针是C语言中一个重要的概念
  • 正确灵活运用指针
    • 可有效地表示和使用复杂的数据结构
    • 可动态分配内存空间,节省程序运行空间,提高运行效率
  • 不正确理解和使用指针,指针将是程序中最危险的成分,由此带来的后果可能是无法估量的

七、指针

7.1 指针与变量

7.1.1 指针类型和指针变量

        指针类型指定了指针所指向的变量的数据类型。例如,int*是指向整数(int)类型的指针。指针变量是一个存储了内存地址值的变量,可以使用指针变量来存储、操作和访问内存中的数据。

#include <stdio.h>

int main() {
    int num = 10; // 定义一个整数变量
    int* ptr; // 定义一个指向整数的指针变量

    ptr = &num; // 将指针指向num变量的地址

    printf("num 的值:%d\n", num);
    printf("指针所指向的变量的值:%d\n", *ptr);

    return 0;
}

  • C语言中的指针定义符是*,它用于声明一个指针变量。指针变量用来存储内存地址,可以指向其他变量或数据结构。例如,int *ptr;声明了一个指向整数的指针变量。
  • 间接引用运算符也称为解引用运算符,用于访问指针所指向的变量或数据。在C语言中,间接引用运算符使用*符号。通过将间接引用运算符应用于指针变量,可以获取该指针指向的实际值。例如,如果ptr是一个指向整数的指针变量,那么*ptr将给出该指针指向的整数的值。

7.1.2 指针所指变量

        通过指针,我们可以访问指针所指向的变量。使用解引用运算符(*)可以获取指针所指向的变量的值。

#include <stdio.h>

int main() {
  int num = 10;
  int* ptr = &num;

  printf("通过指针访问变量的值:%d\n", *ptr);

  *ptr = 20; // 修改指针所指向的变量的值

  printf("修改后的变量的值:%d\n", num);

  return 0;
}

7.1.3 空指针、无效指针

        空指针是指未指向任何有效地址的指针。在C语言中,可以使用NULL宏来表示空指针。

#include <stdio.h>

int main() {
  int* ptr = NULL; // 声明一个空指针

  if (ptr == NULL) {
    printf("指针是空指针\n");
  } else {
    printf("指针不是空指针\n");
  }

  return 0;
}

  •  有时可能不小心生成无效指针 (Invalid  Pointer)
    • 无效指针是指一个指针变量无值,它既没有指向确定的变量或函数,也不是NULL。
    • 程序中存在无效指针,不是好的程序设计风格
    • 产生无效指针的原因很多,例如
      • 说明指针变量后还没有给它赋值
      • 指针被定义后,必须将指针和一个特定的变量进行关联后,才可以使用指针,即必须先赋值再使用
      • 把整型变量转换成指针;
      • 回收为指针所指对象分配存储空间;
        • float *p; 
          p=(float *)malloc(sizeof(float));
          ……
          free(p);

      • 指针运算超出数组范围。
  • NULL是C指针类型的一个特殊值,在系统文件stdio.h中定义,其值为0,称为“空”
  • 表示指针变量的值为空,不指向任何变量或函数
  • NULL值属于所有指针类型。判断指针变量iptr的值是否为空可以使用
    • iptr != NULL或iptr == NULL
      iptr != 0
  • 保证指针在没有指向有效对象时,取值为NULL是一种良好的编程风格

7.2 指针操作

        指针操作是指对指针进行一些特定的运算或操作,用于操作指针所指向的内存位置。在C语言中,指针操作包括指针的算术运算、指针的比较和指针的递增/递减等。

7.2.1 指针的算术运算

  • 指针的加法运算:可以将指针与一个整数相加,结果是指针指向的内存地址增加了若干个字节。这对于遍历数组或访问连续内存块非常有用。
  • 指针的减法运算:可以将一个指针减去另一个指针,结果是两个指针之间的距离(以字节为单位)。
#include <stdio.h>

int main() {
  int arr[] = {1, 2, 3, 4, 5};
  int* ptr = arr;

  printf("第一个元素:%d\n", *ptr);

  // 指针加法运算
  ptr = ptr + 1;
  printf("第二个元素:%d\n", *ptr);

  // 指针减法运算
  ptr = ptr - 1;
  printf("回到第一个元素:%d\n", *ptr);

  return 0;
}

7.2.2 指针的比较

        可以对两个指针进行比较运算,包括相等比较(==)、不等比较(!=)、大于比较(>)、小于比较(<)、大于等于比较(>=)和小于等于比较(<=)。

#include <stdio.h>

int main() {
  int arr[] = {1, 2, 3, 4, 5};
  int* ptr1 = &arr[0];
  int* ptr2 = &arr[2];

  if (ptr1 == ptr2) {
    printf("指针相等\n");
  } else {
    printf("指针不相等\n");
  }

  if (ptr1 < ptr2) {
    printf("ptr1 指向的元素在 ptr2 指向的元素之前\n");
  } else {
    printf("ptr1 指向的元素在 ptr2 指向的元素之后\n");
  }

  return 0;
}

7.2.3 指针的递增和递减

        指针可以通过递增(++)和递减(--)运算符来移动到下一个或上一个内存位置,移动的距离取决于指针所指向的数据类型。

#include <stdio.h>

int main() {
  int arr[] = {1, 2, 3, 4, 5};
  int* ptr = arr;

  printf("第一个元素:%d\n", *ptr);

  // 指针递增
  ptr++;
  printf("下一个元素:%d\n", *ptr);

  // 指针递减
  ptr--;
  printf("回到第一个元素:%d\n", *ptr);

  return 0;
}

7.3 指向指针的指针

        C语言支持指向指针的指针,也称为多级指针。指向指针的指针存储了一个指向指针变量的地址,通过多级指针可以访问多级间接引用的内存。

#include <stdio.h>

int main() {

  int num = 10;
  int* ptr = &num;
  int** ptr2 = &ptr;

  printf("num 的值:%d\n", num);
  printf("指针所指向的变量的值:%d\n", *ptr);
  printf("指向指针的指针所指向的变量的值:%d\n", **ptr2);

  return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1070564.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

单元测试该怎么写

单元测试对于开发人员来说很熟悉&#xff0c;各种语言都提供了单元测试的框架&#xff0c;用于自动化执行单元测试并生成测试报告。它通常提供了一组API和工具&#xff0c;使开发人员能够编写和运行测试用例&#xff0c;比较预期行为和实际行为之间的差异&#xff0c;并准确地识…

Android Studio新建项目缓慢解决方案

关于Android Studio2022新建项目时下载依赖慢的解决方案 起因解决方案gradle下载慢解决方案kotlin依赖下载慢解决方案 结尾 起因 新建Android Studio项目时&#xff0c;常会因为网络问题导致部分依赖下载缓慢&#xff0c;其中gradle和kotlin最拖慢进度。 解决方案 gradle下载…

Spring源码解析——IOC属性填充

正文 doCreateBean() 主要用于完成 bean 的创建和初始化工作&#xff0c;我们可以将其分为四个过程&#xff1a; 最全面的Java面试网站 createBeanInstance() 实例化 beanpopulateBean() 属性填充循环依赖的处理initializeBean() 初始化 bean 第一个过程实例化 bean在前面一篇…

四位十进制数字频率计VHDL,仿真视频、代码

名称&#xff1a;四位十进制数字频率计VHDL&#xff0c;quartus仿真 软件&#xff1a;Quartus 语言&#xff1a;VHDL 代码功能&#xff1a; 使用直接测频法测量信号频率&#xff0c;测频范围为1~9999Hz&#xff0c;具有超量程报警功能 演示视频&#xff1a;四位十进制数字频…

5分钟理解什么是卷积的特征提取

大家好啊&#xff0c;我是董董灿。 卷积算法之所以重要&#xff0c;关键在于其提取特征的能力。 5分钟入门卷积算法中提到&#xff0c;卷积模仿的就是人眼识图的过程&#xff0c;以“感受野”的视角去扫描图片&#xff0c;从而获取不同区域的图片信息。 在这一过程中&#x…

Scratch3.0下载

通俗易懂&#xff0c;直接上链接 链接&#xff1a;https://pan.baidu.com/s/1n-QFEQWT8im8BHQu1wIjtg?pwd1016 提取码&#xff1a;1016

高级IO(Linux)

高级IO 五种IO模型高级IO重要概念同步通信 vs 异步通信阻塞 vs 非阻塞 非阻塞IOfcntl实现函数SetNoBlock轮询方式读取标准输入 I/O多路转接之select初识selectselect函数原型参数解释参数timeout取值关于fd_set结构关于timeval结构函数返回值三级目录 理解select执行过程socket…

多功能频率计周期/脉宽/占空比/频率测量verilog,视频/代码

名称&#xff1a;多功能频率计周期、脉宽、占空比、频率测量verilog 软件&#xff1a;Quartus 语言&#xff1a;Verilog 代码功能&#xff1a; 多功能频率计&#xff0c;可测量信号的周期、脉冲宽度、占空比、频率&#xff0c;语言为verilog&#xff0c;quartus软件设计仿真…

B (1089) : DS单链表--合并

Description 假定两个单链表是递增有序&#xff0c;定义并实现以下函数&#xff0c;完成两个单链表的合并&#xff0c;继续保持递增有序 int LL_merge(ListNode *La, ListNode *Lb) Input 第1行先输入n表示有n个数据&#xff0c;接着输入n个数据 第2行先输入m表示有M个数据…

扭线机控制

扭线机属于线缆加工设备&#xff0c;线缆加工设备种类非常多。有用于网线绞合的单绞&#xff0c;双绞机等&#xff0c;有关单绞机相关算法介绍&#xff0c;大家可以查看专栏相关文章&#xff0c;有详细介绍&#xff0c;常用链接如下&#xff1a; 线缆行业单绞机控制算法&#…

MySQL命令行中文乱码问题

MySQL命令行中文乱码问题&#xff1a; 命令行界面默认字符集是gbk&#xff0c;若字符集不匹配会中文乱码或无法插入中文。 解决办法&#xff1a;执行set names gbk; 验证&#xff1a; 执行命令show variables like ‘char%’;查看默认字符集。 创建数据库设置字符集utf8&…

Nginx详细学习记录

1. Nginx概述 Nginx是一个轻量级的高性能HTTP反向代理服务器&#xff0c;同时它也是一个通用类型的代理服务器&#xff0c;支持绝大部分协议&#xff0c;如TCP、UDP、SMTP、HTTPS等。 1.1 Nginx基础架构 Nginx默认采用多进程工作方式&#xff0c;Nginx启动后&#xff0c;会运行…

多线程锁-synchronized字节码分析

从字节码角度分析synchronized实现 javap -c(v附加信息) ***.class 文件反编译 synchronized同步代码块 >>>实现使用的是monitorenter和monitorexit指令 synchronized普通同步方法 >>>调用指令将会检查方法的ACC_SYNCHRONIZED访问标志是否被设置&#xf…

HTTPS工作过程,国家为什么让http为什么要换成https,Tomcat在MAC M1电脑如何安装,Tomcat的详细介绍

目录 引言 一、HTTPS工作过程 二、Tomcat 在访达中找到下载好的Tomcat文件夹&#xff08;这个要求按顺序&#xff09; zsh: permission denied TOMCAT的各部分含义&#xff1a; 引言 在密码中一般是&#xff1a;明文密钥->密文&#xff08;加密&#xff09; &#xff…

ubuntu 安装postgresql,增加VECTOR向量数据库插件 踏坑详细流程

PGSQL安装&#xff0c;删除&#xff0c;运行&#xff0c;修改密码流程 Ubuntu18.04安装与配置postgresql含远程连接教程&#xff08;含踩坑记录&#xff09;_sudo apt-get install postgresql-CSDN博客 详细安装流程以上博客&#xff0c;自己也记录下 安装vector扩展连接 声明…

微服务学习(十):安装Maven

微服务学习&#xff08;十&#xff09;&#xff1a;安装Maven 1、下载Maven 官网下载 2、将下载后的资源包上传到服务器 3、解压资源包并安装 tar -zxvf apache-maven-3.9.5-bin.tar.gz4、配置环境变量 vi /etc/profileexport MAVEN_HOME/home/maven/apache-maven-3.9.5 …

如何部署一个高可用高并发的电商平台

假设我们已经有了一个特别大的电商平台&#xff0c;这个平台应该部署在哪里呢&#xff1f;假设我们用公有云&#xff0c;一般公有云会有多个位置&#xff0c;比如在华东、华北、华南都有。毕竟咱们的电商是要服务全国的&#xff0c;当然到处都要部署了。我们把主站点放在华东。…

汇编语言是怎么一回事?

汇编语言基础 汇编指令和机器码的区别 数据的表示 各类汇编指令 数据传送和算法运算 位运算 条件分支指令 函数调用 字符串处理 流水线和指令调度 流水线实现指令级并行 编译器指令调度 CPU乱序与投机执行 汇编器将汇编语言翻译成 CPU 可以执行的机器码&#xff0c…

【软考】9.1 顺序表/链表/栈和队列

《线性结构》 顺序存储和链表存储 每个元素最多只有一个出度和一个入度&#xff0c;表现为一条线状链表存储结构&#xff1a;每个节点有两个域&#xff0c;即数据&#xff0c;指针域&#xff08;指向下一个逻辑上相邻的节点&#xff09; 时间复杂度&#xff1a;与其数量级成正…

OpenCV防抖实践及代码解析笔记

视频防抖是指用于减少摄像机运动对最终视频的影响的一系列方法。摄像机的运动可以是平移&#xff08;比如沿着x、y、z方向上的运动&#xff09;或旋转&#xff08;偏航、俯仰、翻滚&#xff09;。 正如你在上面的图片中看到的&#xff0c;在欧几里得运动模型中&#xff0c;图像…