当前位置: 首页 > article >正文

11.04学习

一、指针数组的相关知识点

1. 定义指针数组: 指针数组的声明需要指定数组中指针的类型以及数组的大小。例如:

int* ptrArray[10]; // 一个包含10个int类型指针的数组

2. 初始化指针数组: 指针数组的元素可以被初始化为指向特定变量的指针,或者为 NULL (表示空指针)。例如:

int a = 10, b = 20, c = 30;

int* ptrArray[3] = {&a, &b, &c};

3. 访问指针数组中的元素: 可以通过数组索引来访问指针数组中的元素,然后通过解引用操作符 * 来访问指针指向的值。例如:

printf("%d\n", *ptrArray[0]); // 输出a的值

4. 指针数组作为函数参数: 指针数组可以作为参数传递给函数,这在处理动态分配的数组时非常有用。例如:

void printArray(int* arr[], int size) {

for (int i = 0; i < size; i++) {

printf("%d ", *arr[i]);

}

printf("\n");

}

5. 动态分配指针数组: 指针数组的元素可以指向动态分配的内存。例如:

int* ptrArray[10];

for (int i = 0; i < 10; i++) {

ptrArray[i] = malloc(sizeof(int));

*ptrArray[i] = i;

}

6. 释放动态分配的内存: 如果指针数组的元素指向了动态分配的内存,那么在不再需要时,需要逐个释放这些内存。例如:

for (int i = 0; i < 10; i++) {

free(ptrArray[i]);

}

7. 指针数组和函数指针: 指针数组也可以包含函数指针。这在实现回调函数或事件驱动编程时非常有用。例如:

void (*funcArray[2])(void) = {func1, func2};

funcArray[0](); // 调用func1

8. 指针数组和多维数组: 指针数组可以用于模拟多维数组,尤其是在动态分配内存时。例如,可以创建一个指针数组,其中每个元素都是指向另一个数组的指针,从而模拟二维数组。

9. 指针数组和字符串数组: 指针数组经常用于处理字符串数组,其中每个元素都是一个指向 char 的指针,指向一个字符串。

10. 指针数组和结构体: 指针数组也可以包含指向结构体的指针,这在处理复杂的数据结构时非常有用。

 

二、多级指针的相关知识点

C语言中的多级指针,通常指的是指向指针的指针,这种指针可以用于多种高级编程技术,比如动态内存管理、函数指针、链表和树等数据结构。

1. 定义多级指针: 多级指针的定义需要连续使用多个星号(*)来表示指针的级别。例如,指向指针的指针(二级指针)可以这样定义:

int **p;

2. 初始化多级指针: 多级指针需要逐级初始化。首先初始化最内层的指针,然后是外层的指针,依此类推。

int var = 10;

int *p = &var;

int **pp = &p;

3. 访问指向的值: 要访问多级指针指向的值,需要逐级解引用。例如,通过 **pp 可以访问 var 的值。

printf("%d\n", **pp); // 输出10

4. 动态分配内存: 多级指针常用于动态分配多维数组。例如,动态分配一个二维数组:

int **arr = malloc(n * sizeof(int*));

for (int i = 0; i < n; i++) {

arr[i] = malloc(m * sizeof(int));

}

5. 释放动态分配的内存: 与动态分配内存相对应,释放内存时也需要逐级释放。

for (int i = 0; i < n; i++) {

free(arr[i]);

}

free(arr);

6. 函数参数: 多级指针可以作为函数参数传递,用于修改指针指向的值或者操作复杂的数据结构。

void updateValue(int ***p, int index, int value) {

(*(*p))[index] = value;

}

7. 指针数组和多级指针: 指针数组中的每个元素都是指针,因此可以通过多级指针来访问和操作这些指针数组中的元素。

8. 函数指针和多级指针: 多级指针可以指向函数指针,这在实现回调函数时非常有用。

void (*func)(int);

void (*func2)(int) = &someFunction;

func = func2;

9. 结构体和多级指针: 多级指针可以指向结构体指针,用于操作复杂的数据结构,如链表、树等。

struct Node {

int data;

struct Node *next;

};

struct Node **head;

10. 指针的指针和数组: 多级指针可以用于创建指针的数组,其中每个元素都是指向某个类型指针的指针。

11. 指针运算: 多级指针的运算需要特别注意,因为涉及到指针的地址和指针指向的值。

12. 指针的安全性: 使用多级指针时,需要特别注意指针的安全性,避免野指针、内存泄漏和越界访问等问题。

13. 指针和const: 当使用多级指针时,还可以使用 const 关键字来限制指针的修改,例如 const int **p 表示指向常量整数的指针的指针。

 

三、值传递和地址传递的相关知识点

在C语言中,函数参数的传递方式主要有两种:值传递(pass by value)和地址传递(pass by address)。

 

值传递(Pass by Value)

1. 基本机制:

值传递是指在调用函数时,将实际参数的值复制一份传递给函数的形式参数。

函数内部对参数的任何修改都不会影响到实际参数。

2. 参数复制:

当参数被传递到函数中时,会创建新的存储空间来存储这些值。

这意味着多个函数可以同时拥有同名局部变量,它们互不影响。

3. 性能考虑:

对于基本数据类型(如int、float等),值传递是高效的,因为复制这些值的成本很低。

对于大型数据结构(如结构体或数组),值传递可能会导致性能问题,因为需要复制整个数据结构。

4. 使用场景:

当你不希望函数内部修改参数值时,应该使用值传递。

当参数是基本数据类型或者小的数据结构时,值传递是合适的。

 

地址传递(Pass by Address)

1. 基本机制:

地址传递是指在调用函数时,将实际参数的地址传递给函数的形式参数。

函数内部可以通过这个地址来访问和修改实际参数。

2. 指针参数:

地址传递通常通过指针实现,即函数的形式参数是一个指针。

调用函数时,需要传递变量的地址(使用 & 操作符)。

3. 修改实际参数:

由于函数内部操作的是实际参数的地址,所以任何对参数的修改都会反映到实际参数上。

4. 性能优势:

对于大型数据结构,地址传递可以避免复制整个数据结构,从而提高效率。

5. 使用场景:

当你需要函数内部修改参数值,或者操作大型数据结构时,地址传递是合适的。

6. 指针和数组:

在C语言中,数组名在大多数情况下会被解释为指向数组首元素的指针,因此可以通过地址传递来操作数组。

7. 指针的指针:

地址传递也可以用于多级指针,允许函数修改指针本身的值。

8. const修饰符:

使用 const 关键字可以防止函数修改指针指向的值,即使参数是通过地址传递的。

总结

值传递适用于小数据和不需要在函数内部修改数据的场景。

地址传递适用于需要在函数内部修改数据,或者处理大数据结构以避免复制开销的场景。


http://www.kler.cn/a/380861.html

相关文章:

  • SRE 与 DevOps记录
  • Zookeeper基本命令解析
  • 2024 楚慧杯 re wp
  • UE5仿漫威争锋灵蝶冲刺技能
  • K8s HPA的常用功能介绍
  • linux系统编程(五)
  • 《Python游戏编程入门》注-第4章7
  • 如何封装一个axios,封装axios有哪些好处
  • PHP露营地管理平台小程序系统源码
  • Vue3-hooks代替mixins
  • 20241102在荣品PRO-RK3566开发板使用荣品预编译的buildroot通过iperf2测试AP6256的WIFI网速
  • 【GL09】(算法)卡尔曼滤波
  • HCIA(DHCP服务)
  • C++优选算法七 分治-快排
  • 江协科技STM32学习- P29 实验- 串口收发HEX数据包/文本数据包
  • DAY67WEB 攻防-Java 安全JNDIRMILDAP五大不安全组件RCE 执行不出网
  • 大型音频模型:AudioLLMs
  • 深度学习基础知识-编解码结构理论超详细讲解
  • java学习2
  • SPI通信详解-学习笔记
  • 练习LabVIEW第三十九题
  • Prometheus套装部署到K8S+Dashboard部署详解
  • Vue:计算属性
  • Spring 实现异步流式接口
  • jmeter脚本-请求体设置变量and请求体太长的处理
  • Webpack入门教程:从基本概念到优化技巧