文章目录

  • 一级指针
    • 指针基本概念
    • 指针使用示例
    • 代码说明
  • 二、二级指针
    • 二级指针重点解析

一级指针

C语言中的指针是一个非常重要的概念,它存储了变量的内存地址。指针的使用可以使程序更加高效,尤其在处理数组、字符串和动态内存分配时。

指针基本概念

  • 指针变量:用于存储内存地址的变量
  • 取地址符 &:获取变量的内存地址
  • 解引用符 *:访问指针所指向地址的内容

指针使用示例

下面是一些常见的指针使用示例:
可以运行

#include <stdio.h>// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p;       // 声明一个int类型的指针p = &num;     // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20;      // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr;  // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!";  // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++;  // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();return 0;
}

代码说明

  1. 基本指针操作:展示了如何声明指针、获取变量地址、通过指针访问和修改变量值
  2. 指针作为函数参数:通过指针在函数内部修改外部变量的值,实现了两个数的交换
  3. 指针与数组:数组名本质上是指向第一个元素的指针,演示了如何通过指针访问数组元素
  4. 指针与字符串:字符串可以用指针表示,演示了如何通过指针遍历字符串
  5. 指针数组:数组中的每个元素都是指针,这里用指针数组存储多个字符串

指针的使用需要特别注意避免空指针、野指针等问题,这些可能会导致程序崩溃或不可预期的行为。正确使用指针可以使C程序更加灵活和高效。

二、二级指针

在C语言中,二级指针是指向指针的指针,它存储的是另一个指针变量的地址。二级指针在处理指针数组、动态二维数组以及需要修改指针本身的场景中非常有用。

下面在原有代码基础上添加二级指针的使用示例:

#include <stdio.h>
#include <stdlib.h> // 用于动态内存分配// 1. 基本指针操作
void basicPointerExample() {int num = 10;int *p;       // 声明一个int类型的指针p = &num;     // 将num的地址赋值给指针pprintf("num的值: %d\n", num);printf("num的地址: %p\n", &num);printf("指针p存储的地址: %p\n", p);printf("指针p指向的值: %d\n", *p);*p = 20;      // 通过指针修改num的值printf("修改后num的值: %d\n", num);
}// 2. 指针作为函数参数(实现值的交换)
void swap(int *a, int *b) {int temp = *a;*a = *b;*b = temp;
}// 3. 指针与数组
void pointerAndArray() {int arr[] = {1, 2, 3, 4, 5};int *p = arr;  // 数组名本身就是第一个元素的地址printf("\n数组元素: ");for(int i = 0; i < 5; i++) {// 以下两种方式等价printf("%d ", *(p + i));// printf("%d ", arr[i]);}printf("\n");
}// 4. 指针与字符串
void pointerAndString() {char *str = "Hello, World!";  // 字符串指针printf("\n字符串内容: ");// 使用指针遍历字符串while(*str != '\0') {printf("%c", *str);str++;  // 指针自增,指向 next 字符}printf("\n");
}// 5. 指针数组
void pointerArray() {char *names[] = {"Alice", "Bob", "Charlie", "David"};printf("\n指针数组中的字符串: ");for(int i = 0; i < 4; i++) {printf("%s ", names[i]);}printf("\n");
}// 6. 二级指针使用示例
void doublePointerExample() {int num = 100;int *p = &num;    // 一级指针,指向numint **pp = &p;    // 二级指针,指向指针pprintf("\n=== 二级指针基本操作 ===\n");printf("num的值: %d\n", num);printf("p指向的值: %d\n", *p);printf("pp指向的指针所指向的值: %d\n", **pp);printf("num的地址: %p\n", &num);printf("p存储的地址: %p\n", p);printf("pp存储的地址: %p\n", pp);printf("p本身的地址: %p\n", &p);
}// 7. 二级指针与指针数组
void doublePointerAndPointerArray() {char *languages[] = {"C", "Python", "Java", "JavaScript"};char **pp;  // 二级指针,用于指向指针数组元素printf("\n=== 二级指针访问指针数组 ===\n");// 二级指针遍历指针数组pp = languages;  // 指向数组首元素for(int i = 0; i < 4; i++) {printf("语言: %s, 地址: %p\n", *pp, pp);pp++;  // 移动到下一个指针元素}
}// 8. 二级指针作为函数参数(修改指针本身)
void allocateMemory(int **ptr, int size) {// 为指针分配内存,需要二级指针才能修改外部指针*ptr = (int*)malloc(size * sizeof(int));if(*ptr == NULL) {printf("\n内存分配失败!\n");return;}// 初始化分配的内存for(int i = 0; i < size; i++) {*(*ptr + i) = i * 10;}
}int main() {basicPointerExample();int x = 100, y = 200;printf("\n交换前: x = %d, y = %d\n", x, y);swap(&x, &y);printf("交换后: x = %d, y = %d\n", x, y);pointerAndArray();pointerAndString();pointerArray();// 演示二级指针doublePointerExample();doublePointerAndPointerArray();// 二级指针作为函数参数示例int *arr = NULL;allocateMemory(&arr, 5);  // 传递指针的地址if(arr != NULL) {printf("\n通过二级指针分配的数组: ");for(int i = 0; i < 5; i++) {printf("%d ", arr[i]);}printf("\n");free(arr);  // 释放内存}return 0;
}

二级指针重点解析

  1. 二级指针的定义与初始化

    int num = 100;
    int *p = &num;    // 一级指针
    int **pp = &p;    // 二级指针,指向指针p
    

    这里pp就是二级指针,它存储的是一级指针p的地址。

  2. 二级指针的解引用

    • *pp:得到一级指针p的值(即num的地址)
    • **pp:通过两次解引用,得到最终变量num的值
  3. 二级指针的主要用途

    • 访问指针数组:如示例中遍历存储字符串的指针数组
    • 作为函数参数修改指针本身:当需要在函数内部为指针分配内存或修改指针指向时
    • 处理动态二维数组:二级指针常用来表示动态分配的二维数组
  4. 使用注意事项

    • 二级指针也可能出现空指针问题,使用前需检查
    • 多级指针会增加代码复杂度,应避免过度使用
    • 动态分配内存后需记得释放,防止内存泄漏

通过二级指针,我们可以更灵活地操作指针本身,这在处理复杂数据结构和动态内存分配时特别有用。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

界面布局智能建议生成:从功能需求到专业UI的AI加速之路

内容简介: 传统界面设计让产品经理陷入"不懂设计、等设计师"的困境&#xff0c;效率低下还容易被挑刺。本文深度解析DeepSeek驱动的界面布局智能生成技术&#xff0c;通过DESIGN框架提示词模板&#xff0c;让产品经理在30分钟内生成3种专业级界面方案&#xff0c;实现…

【BLE系列-第三篇】数据链路层(LL):广播/连接/扫描流程详解

目录 引言 一、广播及连接建立 1.1 广播类型 1.2 扫描/连接请求与响应 1.2.1 广播流程说明 1.2.1.1 广播流程示例图 1.2.1.2 广播信息设置 1.2.1.3 信道广播 1.2.1.4 信道切换 1.2.1.5 广播间隔 1.2.1.6 接收窗口与理论最小传输时间 1.2.2 扫描/连接流程说明 1.2.…

JMeter 测试 WebSocket 接口的详细教程

1. 安装 WebSocket 插件 方法一&#xff1a;通过 Plugins Manager 下载并安装 JMeter Plugins Manager在 JMeter 中&#xff1a;Options → Plugins Manager搜索 WebSocket 并安装 方法二&#xff1a;手动安装 下载 jmeter-websocket-samplers 插件将 jar 文件放到 JMeter/…

飞算JavaAI智慧教育场景实践:从个性化学习到教学管理的全链路技术革新

目录一、智慧教育核心场景的技术突破1.1 个性化学习路径推荐系统1.1.1 学习者能力建模与评估1.2 智能教学管理系统1.2.1 自动化作业批改与学情分析1.3 教育资源智能管理系统1.3.1 教育资源智能标签与推荐二、智慧教育系统效能升级实践2.1 教育数据中台构建2.1.1 教育数据整合与…

Java面试场景题大全精简版

1.分布式系统下如何实现服务限流核心算法&#xff1a;固定窗口&#xff1a;将时间划分为固定窗口&#xff08;如 1 秒&#xff09;&#xff0c;统计窗口内请求数&#xff0c;超过阈值则限流。实现简单但存在临界值突发流量问题。滑动窗口&#xff1a;将固定窗口拆分为多个小窗口…

红帽 AI 推理服务 (vLLM) - 入门篇

《教程汇总》 RedHat AI Inference Server 和 vLLM vLLM (Virtual Large Language Model) 是一款专为大语言模型推理加速而设计的框架。它是由加州大学伯克利分校 (UC Berkeley) 的研究团队于 2023 年开源的项目&#xff0c;目前 UC Berkeley 和 RedHat 分别是 vLLM 开源社区…

Sql server 命令行和控制台使用二三事

近来遇到了几件关于sql server的事情。 第一&#xff1a;低版本sqlserver备份竟然无法还原到高版本 奇怪&#xff01;从来未碰到过。过程如下&#xff1a; 1.在低版本上中备份好了数据库 2.通过共享将文件拷贝到新服务器上 3.打开控制台&#xff0c;还原数据库&#xff0c;结果…

vue excel转json功能 xlsx

需求&#xff1a; 完成excel表格内容转json&#xff0c;excel表格内可能存在多个表格&#xff0c;要求全部解析出来。完成表格内合服功能&#xff0c;即&#xff1a;提取表格内老服务器与新服务器数据&#xff0c;多台老服务器对应合并到一台新服务器上 3.最终输出结果为:[{‘1…

Qwen-OCR:开源OCR技术的演进与全面分析

目录 一、Qwen-OCR的历史与发展 1.1 起源与早期发展(2018-2020) 1.2 技术突破期(2020-2022) 1.3 开源与生态建设(2022至今) 二、技术竞品分析 2.1 国际主流OCR解决方案对比 2.2 国内竞品分析 三、部署需求与技术规格 3.1 硬件需求 3.2 软件依赖 3.3 云部署方案 四、…

可视化+自动化:招聘管理看板软件的核心技术架构解析

引言&#xff1a;现代招聘的挑战与转型随着全球化和科技的迅速发展&#xff0c;企业的人力资源管理面临着前所未有的挑战。尤其是在招聘环节&#xff0c;随着人才市场的竞争日益激烈&#xff0c;企业必须在确保招聘质量的同时&#xff0c;提升招聘效率。这不仅要求招聘人员具备…

【数据结构】——栈(Stack)的原理与实现

目录一. 栈的认识1. 栈的基本概念2.栈的基本操作二. 栈的核心优势1. 高效的时间复杂度2. 简洁的逻辑设计3. 内存管理优化三. 栈的代码实现1.栈的结构定义2. 栈的初始化3. 入栈 &#xff08;动态扩容&#xff09;4. 出栈5. 取栈顶数据6. 判断栈是否为空7. 获取栈的数据个数8.销毁…

使用TexLive与VScode排版论文

前言 中文稿目前已经完成了&#xff0c;现在要转用latex排版&#xff0c;但我对这方面没有接触过&#xff0c;这里做一个记录。 网页版Overleaf&#xff1a;Overleaf, 在线LaTeX编辑器。 TeXWorks&#xff1a;论文神器teXWorks安装与使用记录。 这里我还是决定采用Vscode作…

每日一题:2的幂数组中查询范围内的乘积;快速幂算法

题目选自2438. 二的幂数组中查询范围内的乘积 还是一样的&#xff0c;先讲解思路&#xff0c;然后再说代码。 题目有一定难度&#xff0c;所以我要争取使所有人都能看懂&#xff0c;用的方法会用最常规的思想。关于语言&#xff0c;都是互通的&#xff0c;只要你懂了一门语言…

Ceph数据副本机制详解

Ceph 数据副本机制详解 Ceph 的数据副本机制是其保证数据可靠性和高可用性的核心设计&#xff0c;主要通过多副本&#xff08;Replication&#xff09; 和 纠删码&#xff08;Erasure Coding&#xff0c;EC&#xff09; 两种方式实现。以下是对 Ceph 数据副本机制的全面解析&am…

【八股】Mysql中小厂八股

MySQL 基础 数据库三大范式&#xff08;中&#xff09; 第一范式: 要求数据库表的每一列都是不可分割的原子数据项 如详细地址可以分割为省市区等. 第二范式: 非主键属性必须完全依赖于主键, 不能部分依赖 第二范式要确保数据库表中的每一列都和主键相关, 而不能只与主键的某一…

怎么使用python查看网页源代码

使用python查看网页源代码的方法&#xff1a;1、使用“import”命令导入requests包import requests2、使用该包的get()方法&#xff0c;将要查看的网页链接传递进去&#xff0c;结果赋给变量xx requests.get(urlhttp://www.hao123.com)3、用“print (x.text)”语句把网页的内容…

C# 多线程:并发编程的原理与实践

深入探讨 C# 多线程&#xff1a;并发编程的原理与实践引言在现代应用开发中&#xff0c;性能和响应速度往往决定了用户体验的优劣。尤其在计算密集型或者IO密集型任务中&#xff0c;传统的单线程模型可能无法有效利用多核CPU的优势。因此&#xff0c;多线程技术成为了解决这些问…

react 常用组件库

1. Ant Design&#xff08;蚂蚁设计&#xff09;特点&#xff1a;国内最流行的企业级 UI 组件库之一&#xff0c;基于「中后台设计体系」&#xff0c;组件丰富&#xff08;表单、表格、弹窗、导航等&#xff09;、设计规范统一&#xff0c;支持主题定制和国际化。适用场景&…

Python 爬虫获取淘宝商品信息、价格及主图的实战指南

在电商数据分析、竞品调研或商品信息采集等场景中&#xff0c;获取淘宝商品的详细信息&#xff08;如价格、主图等&#xff09;是常见的需求。虽然淘宝开放平台提供了官方的 API 接口&#xff0c;但使用这些接口需要一定的开发和配置工作。本文将通过 Python 爬虫的方式&#x…

Ruby面向对象编程中类与方法的基础学习例子解析

代码示例&#xff1a; Ruby面向对象编程中类与方法的基础学习详细例子 1. 引言 在面向对象编程&#xff08;OOP&#xff09;中&#xff0c;类是定义对象结构和行为的蓝图。Ruby是一种纯面向对象的编程语言&#xff0c;它将一切视为对象&#xff0c;包括基本数据类型。本文将…