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

目录

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

二级指针

当涉及到多级指针时,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.hqwc.cn/news/1770.html

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

相关文章

原生HTML+CSS+JS制作自己的导航主页

如果你想使用原生HTML、CSS和JS制作自己的导航主页&#xff0c;你可以按照以下步骤进行操作&#xff1a; 先看效果图&#xff1a; 创建HTML文件&#xff1a;首先&#xff0c;创建一个新的HTML文件&#xff0c;并在文件中添加基本的HTML结构。你可以使用<!DOCTYPE html>…

R语言复现一篇6分的孟德尔随机化文章

上一期我们对孟德尔随机化做了一个简单的介绍&#xff0c;今天我们来复现一篇6分左右的使用了孟德尔随机化方法的文章&#xff0c;文章的题目是&#xff1a;Mendelian randomization analysis does not reveal a causal influence of mental diseases on osteoporosis&#xff…

基于tensorflow深度学习的猫狗分类识别

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

排序算法——归并排序(递归与非递归)

归并排序 以升序为例 文章目录 归并排序基本思想核心步骤递归写法实现代码 非递归处理边界情况实现代码 时间复杂度 基本思想 归并排序是建立在归并操作上的一种有效的排序算法&#xff0c;该算法是采用分治法的一个非常典型的应用&#xff1a;将已有序的子序列合并&#xff…

《C++ Primer》--学习7

顺序容器 容器库概览 迭代器 与容器一样&#xff0c;迭代器有着公共的接口&#xff1a;如果一个迭代器提供某个操作&#xff0c;那么所有提供相同操作的迭代器对这个操作的实现方式都是相同的。 迭代器范围 一个迭代器范围是由一对迭代器表示&#xff0c;两个迭代器分别指向…

IM即时通讯APP在聊天场景中的应用

即时通讯&#xff08;IM&#xff09;应用可以满足人们随时随地进行文字、语音、图片、视频等多媒体信息的传递需求&#xff0c;为个人和企业提供了高效、便捷的沟通方式。在企业中&#xff0c;IM即时通讯APP更是发挥着重要的作用&#xff0c;促进了协作和团队工作的效率提升。以…

项目——学生信息管理系统3

目录 班级添加的界面实现 创建班级的实体类 在org.xingyun.dao 包下 编写 ClassDao 创建 AddStudentClassFrm 添加班级页面 注意创建成 JInternalFrame 类型 给控件起个名字 注释掉main方法 给提交按钮绑定事件 回到 MainFrm.java 给添加班级按钮绑定事件 启动测试 班…

基于卡尔曼滤波进行四旋翼动力学建模(SimulinkMatlab)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

网络安全实战植入后门程序

在 VMware 上建立两个虚拟机&#xff1a;win7 和 kali。 Kali&#xff1a;它是 Linux 发行版的操作系统&#xff0c;它拥有超过 300 个渗透测试工具&#xff0c;就不用自己再去找安装包&#xff0c;去安装到我们自己的电脑上了&#xff0c;毕竟自己从网上找到&#xff0c;也不…

通俗易懂,十分钟读懂DES,详解DES加密算法原理,DES攻击手段以及3DES原理。Python DES实现源码

文章目录 1、什么是DES2、DES的基本概念3、DES的加密流程4、DES算法步骤详解4.1 初始置换(Initial Permutation&#xff0c;IP置换)4.2 加密轮次4.3 F轮函数4.3.1 拓展R到48位4.3.2 子密钥K的生成4.3.3 当前轮次的子密钥与拓展的48位R进行异或运算4.3.4 S盒替换&#xff08;Sub…

Object counting——生成密度图density map

文章目录 过程代码参考 过程 首先构造一个和原始图片大小相同的矩阵&#xff0c;并将其全部置为0&#xff0c;然后将每个被标记的人头对应的位置置为1&#xff0c;这样就得到了一个只有0和1的矩阵&#xff0c;最后通过高斯核函数进行卷积得到一个连续的密度图。 代码 import…

CSS知识点汇总(十)--移动端适配

文章目录 怎么做移动端的样式适配&#xff1f;1、方案选择2. iPhoneX 适配方案 怎么做移动端的样式适配&#xff1f; 在移动端虽然整体来说大部分浏览器内核都是 webkit&#xff0c;而且大部分都支持 css3 的所有语法。但手机屏幕尺寸不一样&#xff0c;分辨率不一样&#xff0…