C语言-基础语法学习-3 二级指针

news2024/11/16 1:33:35

目录

    • 二级指针
    • 二级指针的定义和声明
    • 二级指针的初始化
    • 二级指针的使用
    • 二级指针和函数参数
    • 二级指针和动态内存分配
    • 数组指针
      • 二维数组
        • 二维数组的初始化
        • 二维数组与指针
        • 二维数组的遍历

二级指针

当涉及到多级指针时,C语言的灵活性和强大的指针功能可以得到充分的发挥。二级指针是指指向指针的指针,也被称为指向指针的引用。

使用二级指针可以实现以下功能:

  1. 动态内存分配:通过二级指针可以动态地分配内存块,并将其地址传递给其他函数或模块进行操作。这对于动态数据结构如链表、树等非常有用。
  2. 函数参数传递:二级指针可以用作函数的参数,通过传递指向指针的指针,函数可以修改原始指针的值,实现对指针本身的修改,而不仅仅是对指针所指向的数据的修改。
  3. 多维数组:在处理多维数组时,二级指针可以用于动态创建和操作二维及更高维的数组结构。
  4. 字符串处理:通过二级指针可以实现字符串的动态分配和修改,以及指针数组的管理。

二级指针的使用要注意以下几点:

  1. 内存管理:使用二级指针进行动态内存分配时,需要手动管理内存的分配和释放,确保在不需要使用时及时释放内存,避免内存泄漏。
  2. 空指针检查:在使用二级指针之前,务必进行空指针检查,避免对空指针进行操作导致程序崩溃或出现未定义行为。
  3. 间接访问:二级指针需要通过多次间接访问才能获得最终的数据,因此需要小心处理指针的层级关系,确保每一级指针的有效性和正确性。

总之,二级指针是C语言中一个强大且灵活的工具,它提供了对指针本身的操作和控制,使得程序可以更加高效地管理内存、处理复杂的数据结构以及实现更灵活的函数参数传递。但同时,使用二级指针也需要小心处理指针的有效性和内存管理,以确保程序的正确性和稳定性。

二级指针(double pointer)是指指针的指针,它可以用于在函数中传递和修改指针的值,或者动态管理内存。

定义

int data = 100;
int *p = &data;
int **pp = &p;   
//可以定义int *pp = &p, 但是在取内容时只能向上取一级,即*pp 为 p的地址
printf("%d", **pp);

举例

#include <stdio.h>
//二维数组表示一共3个人,每个人有4科成绩,调用函数传入二级指针,将一个人的4科成绩地址放入二级指针指向的地址
void getPosPerson(int pos, int (*pstu)[4], int **ppos)
{
    *ppos = (int *)(pstu + pos);
}

int main()
{
    int scores[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
    int *ppos;
    int pos;
    scanf("%d", &pos);
    getPosPerson(pos, scores, &ppos);
    for (int i = 0; i < 4; i++)
        printf("%d ", *ppos++);
    return 0;
}

C语言中的二级指针(指向指针的指针)在处理多级指针或者动态内存分配等情况下非常有用。下面是关于C语言二级指针的一些重要知识点:

二级指针的定义和声明

二级指针是指向指针的指针,使用两个星号(**)表示。例如:

int** ptr;

二级指针的初始化

二级指针需要进行两级的内存分配。首先,分配一个指针变量的内存,然后为该指针变量分配指向的内存。示例:

int* p;
int** ptr = &p;

二级指针的使用

通过二级指针可以访问和修改指针指向的内存。例如,通过二级指针可以间接修改一级指针所指向的变量的值。示例:

int x = 10;
int* p = &x;
int** ptr = &p;

**ptr = 20; // 修改p指向的变量的值为20

二级指针和函数参数

二级指针常用于函数参数,可以通过传递指针的指针来修改原始指针的值。这在需要修改指针本身的情况下非常有用。示例:

void updatePointer(int** ptr) {
    int* newPtr = malloc(sizeof(int));
    *newPtr = 100;
    *ptr = newPtr;
}

int main() {
    int* p = NULL;
    updatePointer(&p);
    // 现在p指向了动态分配的内存
    // 可以通过*p访问该内存的值
    return 0;
}

二级指针和动态内存分配

二级指针可以用于动态分配内存。通过二级指针,可以分配指针数组或多维数组的内存。示例:

int numRows = 3;
int numCols = 4;
int** matrix = malloc(numRows * sizeof(int*));
for (int i = 0; i < numRows; i++) {
    matrix[i] = malloc(numCols * sizeof(int));
}
// 现在可以通过matrix[i][j]访问二维数组的元素

以上是关于C语言二级指针的一些基本知识点和用法。二级指针在处理多级指针、动态内存分配和函数参数传递等场景下非常有用,可以灵活地管理和操作指针的指针。

数组指针

二级指针和二维数组注意:

不能直接用二级指针指向二维数组,int **p = scores后虽然指向的地址相同,但是含义类型并不相同,错误,应该用数组指针指向二维数组。

int scores[3][4] = {
        {1, 2, 3, 4},
        {5, 6, 7, 8},
        {9, 10, 11, 12}
    };
int **p;
//p = scores;  错误 
int (*p2)[4] = scores; //数组指针,定义一个指针,指向一个数组,数组指针才是真正等同于二维数组名
p = &p2;  //可以用二级指针指向数组指针的地址
**p = 100; //修改的是scores[0][0]的值

二维数组

二维数组的初始化

  1. 按行列初始化

在这里插入图片描述

  1. 没明确行列,类似一维数组

在这里插入图片描述

  1. 部分赋初值

在这里插入图片描述
2.
在这里插入图片描述

在这里插入图片描述

4.在这里插入图片描述

二维数组与指针

C语言规定数组名代表数组首元素地址

int a[3][3];

a[0],a[1],a[2] 是一维数组名,则
a[0] 代表一维数组a[0]中第0列元素的地址,即

a[0] = &a[0][0]
a[1] = &a[1][0]
a[2] = &a[2][0]
------------------------
a = &a[0]
*a = a[0]
**a = a[0][0]
a + 1 = &a[1]
*(a + 1) = a[1]
a[0] + 1 = &a[0][1] = *(a + 0) + 1   
------------------------------

参考

在这里插入图片描述

在这里插入图片描述

总结

在这里插入图片描述

二维数组的遍历

操作数组名

int array[3][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 ", array[i][j]);
        printf("%d ", *(array[i] + j));
        printf("%d ", *(*(array + i) + j));
    }

操作指针

int array[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};

int *p1 = &array[0][0];
int (*p2)[4] = array;  //数组指针,定义一个指针,指向一个数组,数组指针才是真正等同于二维数组名

for (int i = 0; i < 3; i++)
    for (int j = 0; j < 4; j++) {
        printf("%d ", *p1++);
        printf("%d ", *(*(p2 + i) + j));
    }

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

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

相关文章

Xshell弹窗:需要Xmanager软件来处理X11转发请求(解决办法:关闭X11转发)

文章目录 问题背景问题分析什么是X11转发&#xff1f;分析原因&#xff08;没分析出来&#xff09; 解决办法&#xff08;关闭X11转发&#xff09;参考文章 问题背景 今天我在ubuntu服务器上用python flask框架做了个http服务程序&#xff0c;我用xshell连接服务器并执行该服务…

对话 | 中国团队首次完成“赫兹速率”的城域量子隐形传态

光子盒研究院 近日&#xff0c;电子科技大学郭光灿院士团队周强研究组与中科院上海微系统所尤立星团队合作&#xff0c;在电子科技大学“银杏一号”城域量子互联网方面取得了重大进展。 “银杏一号”城域量子互联网建设场地鸟瞰图和设计概念图。展示了一个量子隐形传态系统&…

神策(Android)- 在曝光采集基础上学习项目架构

开篇的时候我就在想这篇blog到底有没有意义&#xff1f;因为本身使用的就是神策提供的功能&#xff0c;同时神策也提供了很完善的文档&#xff0c;而唯一要我们做的也仅仅是将它正确的集成到项目内&#xff0c;并且随着版本升级&#xff0c;文档肯定也会有一定变更… 不过&…

STM32微控制器:现状与竞争力的评估

STM32是意法半导体&#xff08;STMicroelectronics&#xff09;开发的一系列32位ARM Cortex-M微控制器。它们被广泛用于嵌入式系统开发&#xff0c;并在许多应用领域中得到了广泛应用&#xff0c;包括消费电子、工业自动化、汽车行业和物联网等。 尽管我无法提供最新的市场趋势…

(4)深度学习学习笔记-Softmax

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、来源 前言 softmax和cross-entorpy 一、 # softmax import torch from torch import nn from d2l import torch as d2lbatch_size64 train_iter,test_ite…

记录STM32使用udp通信的一个大坑

TOCfreeRTOSlwip实现udp通信 问题说明 在使用MCU和其他终端udp通信时遇见这样的一个大坑&#xff0c;整个通信过程如下图所示 问题出在mcu与其他设备通过udp交互&#xff0c;但在调试的过程中发现MCU给其他设备发消息的时候&#xff0c;虽然看起来成功了&#xff0c;但实际上…

尚硅谷Docker实战教程-笔记03【Docker常用命令】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【理念简介、官网介绍、平台入门图解、平台架构图解】尚硅谷Docker实战教程-笔…

Vue+G6搭建力导向图

1 效果 初始化时节点向中间聚拢 拖动后&#xff0c;随引力作用缓缓向中间聚拢 点击节点&#xff0c;节点放大&#xff0c;并展示标签文字 2 代码分析 2.1 数据 2.1.1 节点数据 nodes: [{id: 0,label: 0,value: 10,cluster: a,description: this is node 0, \nand the value…

帆软数据填报——多字段联合校验数据是否重复

功能&#xff1a;同一张表中&#xff0c;在填报时&#xff0c;设定多个字段联合维度下&#xff0c;记录不允许出现2条及以上 EG&#xff1a;同个项目同个时间维度不允许存在2条及以上的记录 效果&#xff1a; 说明&#xff1a;如果设定“管理项目编码”和“统计截止日期”字段…

【树莓派】解密树莓派Python项目中神秘的导入错误

文章目录 问题导入python文件目录分析解决方案 问题导入 小编在使用树莓派编写python项目时出现了以下两种错误&#xff1a; ModuleNotFoundError : No module named Motor from ..hardware.motor import Motor portError: attempted relative import with no known parent p…

【C语言】手把手带你解决青蛙跳台阶问题

君兮_的个人主页 勤时当勉励 岁月不待人 C/C 游戏开发 Hello,这里是君兮_&#xff0c;今天更新的是经典递归问题——青蛙跳台阶&#xff0c;在所有有关递归的问题中&#xff0c;青蛙跳台阶是最广为人知的问题之一&#xff0c;可以说&#xff0c;如果你能真正弄懂青蛙跳台阶问…

javaweb学习2

p标签使用 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <!--p标签定义段落 p元素自动在其前后创建一段空白--> hello&#xff0c;world &l…

电脑鼠标怎么改变形状

电脑鼠标怎么改变形状? 首先你要下载一个鼠标指针包&#xff0c;网上有很多这样的资源&#xff0c;选择你喜欢的那一个指针包。 点击开始菜单&#xff0c;找到控制面板&#xff0c;打开控制面板。 从控制面板里点击“硬件和声音”&#xff0c;在设备和打印机里面点击“鼠标”。…

1-Eureka服务注册与发现以及Eureka集群搭建(实操型)

1-Eureka服务注册与发现以及Eureka集群搭建&#xff08;实操型&#xff09; 1. 简单搭建微服务框架1.1 idea创建maven多模块项目1.2 项目结构1.3 项目依赖与配置1.3.1 父工程&#xff1a;dog-cloud-parent1.3.2 管理实体项目&#xff1a;dog-po1.3.3 服务提供者&#xff1a;dog…

HBase(9):过滤器

1 简介 在HBase中,如果要对海量的数据来进行查询,此时基本的操作是比较无力的。此时,需要借助HBase中的高级语法——Filter来进行查询。Filter可以根据列簇、列、版本等条件来对数据进行过滤查询。因为在HBase中,主键、列、版本都是有序存储的,所以借助Filter,可以高效地…

主流开源深度学习框架简介

主流开源深度学习框架简介 本文目录&#xff1a; 一、TensorFlow深度学习框架 二、PyTorch深度学习框架 三、Keras深度学习框架 四、Caffe深度学习框架 五、中国深度学习开源框架状况 六、几种框架的对比 七、其他统计数据 当下&#xff0c;有许多主流的开源深度学习框架…

mysql 模糊查询的字段 支持不区分大小写功能

1. 直接修改字段对应的校对规则即可 ​​​​​​ 2. 校对规则说明 ​ utf8_bin 将字符串中的每一个字符用二进制数据存储&#xff0c;区分大小写。 utf8_genera_ci 不区分大小写&#xff0c;ci为case insensitive的缩写&#xff0c;即大小写不敏感。utf8_general_cs 区分…

香蕉派BPI-R4 Wifi7路由器采用联发科MT7988A (Filogic 880)设计

香蕉派BPI-R4路由器板采用联发科MT7988A (Filogic 880)四核ARM Corex-A73方案设计&#xff0c;板载4GB DDR4内存,8GB eMMC存储,128MB SPI-NAND闪存&#xff0c;还具有2个10Gbe SFP光电口, 4x Gbe千兆网口&#xff0c;带USB3.2端口&#xff0c;M.2接口支持4G/5G/NVME SSD.2x min…

海外版“咸鱼”Carousell是什么?

做跨境的都知道&#xff0c;一定不能只在一颗树上吊死&#xff0c;潮流总是把你推着向前的&#xff0c;现在跨境电商平台一样层出不穷。今天就来跟大家分享最近发现比价好做的外贸电商平台APP——Carousell。号称海外版“咸鱼”&#xff0c;它的功能也与咸鱼是差不多的&#xf…

群晖ssh登录并开启root用户登录功能

说明 群辉默认不允许SSH使用ROOT远程登陆&#xff0c;只能用手动创建的账户登陆&#xff0c;需要拷贝破解文件的时候会提示权限不足&#xff0c;这个时候肯定需要通过root用户去登录靠北 启动ssh登录功能 双击控制面板 点击终端和SNMP 启用ssh和telnet 点击应用 finalshel…