【C语言】为什么C语言中有时候使用指针传递长度 (*n)?|| 通过一个简单的问题来熟悉java、C++、C语言的区别关系? 通过删除demo了解C++,java和C语言中针对指针的不同处理
本次思考合集:
- 为什么C语言中有时候使用指针传递长度 (*n)?一个简单的问题来熟悉java、C++、C语言的区别关系?
- java与C++/C的区别之java丢掉指针 || 带来的优势
- java为什么丢弃了指针?|| 丢掉了指针java如何进行内存管理呢?|| 垃圾回收导致的高并发性能开销问题 !!!
目录
- 本次思考合集:
- C的删除例子:
- 一个经典的C语言删除操作的例子
- 但是为什么使用指针传递长度 (*n)?
- 因为
- 在 C 语言中,参数传递有两种方式:
- 但是
- 那么同样的操作、java和C++中的删除操作是如何实现的呢?
- 一、C++
- 二、Java
- 总结
C的删除例子:
一个经典的C语言删除操作的例子
void deleteElem(int arr[], int *n, int pos) {
// pos有效性检查:确保删除位置合法,0 = *n) {
printf("删除位置不合法\n");
return;
}
// 元素前移:从删除位置开始,逐个向前移动元素覆盖掉被删除的元素
for (int i = pos; i < *n - 1; i++) {
arr[i] = arr[i + 1];
}
(*n)--; // 长度-1
}
在这里,*n(指针) 是一个指向顺序表长度的指针,这样我们可以通过 *n 来获取和修改顺序表的实际长度。当我们删除一个元素时,顺序表的长度需要减 1,因此我们使用 (*n)- -; 来实现这一点。
但是为什么使用指针传递长度 (*n)?
因为
在 C 语言中,参数传递有两种方式:
- 值传递
- 引用传递(通过指针)
但是
值传递会让函数无法修改原始数据。而如果使用指针传递,就能在函数内部修改原始数据。所以,通过这种方式,我们能够在函数中修改顺序表的长度,并且能够在外部继续访问更新后的长度。
那么同样的操作、java和C++中的删除操作是如何实现的呢?
一、C++
在 C++ 中,数组和指针的处理与 C 语言类似,但 C++ 提供了更多的容器类,如 std::vector,可以更方便地处理动态数组。我们将分别讲解两种情况:
- 使用动态数组
这个情况和干柴C语言方法很类似的,定义一个元素然后向前覆盖,
也使用到了指针来获得长度
#include
using namespace std;
void deleteElem(int arr[], int* n, int pos) {
// pos有效性检查:确保删除位置合法,0 = *n) {
cout
输出结果
1 2 4 5
- 使用 std::vector。
使用 (C++ 标准库提供的动态数组)“std::vector”,直接使用 函数删除指定位置的元素,并自动调整大小
- 1)首先定义了一个函数
deleteElem
,不过有效长度的减少函数通过"*n"来实现的 - 2)输出结果一样是
“1 2 4 5”
二、Java
值得关注的是,Java 中不直接使用指针,所有的数组都是对象。 比如对于数组和动态列表,我们不需要通过指针来传递数据,而是通过引用传递
,我们来看两种情况:
- 使用原生数组
在 Java 中,原生数组的大小是
固定的
,无法像 C 和 C++ 中那样直接调整大小。 如果需要删除一个元素并保持数组的大小一致,通常需要创建一个新的数组来替代
原始数组。
- 同样的,我们这里定一个deleteElem函数,传入数组和位置两个参数
- 判断位置是否合法
- 合法的话我们就把要删除的元素后面的元素
全部前移一位
- 然后由于我们没有指针,因此数组的长度
无法自动调整
,删除后通常需要将数组的最后一个元素清零
或设置为默认值。将最后一个元素设置为默认值例如“0”(可根据需要设置为 null 或其他默认值)
import java.util.Arrays;
public class Main {
public static void deleteElem(int[] arr, int pos) {
if (pos < 0 || pos >= arr.length) {
System.out.println("删除位置不合法");
return;
}
// 删除位置之后的元素前移
for (int i = pos; i < arr.length - 1; i++) {
arr[i] = arr[i + 1];
}
// 将数组的最后一个元素设置为默认值(例如 0)
arr[arr.length - 1] = 0; // 可根据需要设置为 null 或其他默认值
}
public static void main(String[] args) {
int[] arr = {1, 2, 3, 4, 5};
deleteElem(arr, 2); // 删除位置为 2(即元素 3)
// 输出删除后的数组
System.out.println(Arrays.toString(arr));
}
}
- ArrayListArrayList
ArrayList 是 Java 中常用的动态数组
类
,它会自动调整大小。使用 ArrayList 提供的 remove 函数删除元素非常方便。
import java.util.ArrayList;
public class Main {
public static void deleteElem(ArrayList list, int pos) {
if (pos < 0 || pos >= list.size()) {
System.out.println("删除位置不合法");
return;
}
list.remove(pos); // 使用 ArrayList 提供的 remove 函数删除元素
}
public static void main(String[] args) {
ArrayList list = new ArrayList(); //新建一个类
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
deleteElem(list, 2); // 删除位置为 2(即元素 3)
// 输出删除后的列表
System.out.println(list);
}
}
总结
C语言:
C 语言没有像 Java 或 C++ 中那样提供现成的库来动态管理数组的大小。因此,在删除数组元素时,我们使用指针直接操作内存。删除操作通常涉及将数组中后续元素向前移动,并在末尾位置处理空值(如设置为 0)以避免数据混乱。C++ 和 Java:
- C++ 提供了
std::vector
,它是一个动态数组,支持高效地删除元素,且会自动调整大小。使用erase
方法可以轻松删除元素,无需手动管理数组大小。 - Java 提供了
ArrayList
,它是一个动态数组类,允许删除元素时自动调整大小,使用remove
方法即可实现元素删除,不需要手动移动元素。
- C++ 提供了
自定义删除函数(C++ 和 Java):
- C++ 和 Java 都可以定义自己的删除函数,处理数组或列表删除操作。删除时,通常的做法是将被删除元素后面的元素向前移动,以填补被删除的空位。
- 在 C++ 中,由于使用指针,函数内部的数组和长度可以直接修改。
- 在 Java 中,不能直接操作指针,而是通过引用传递数组或
ArrayList
。删除时需要手动将数组末尾的元素(如果是原生数组)置为默认值(如0
或null
),以避免脏数据。
总结上,C 语言需要手动处理内存和数组大小,而C++和Java在提供了高级容器类(如std::vector
和ArrayList
)的同时,也允许通过自定义函数来实现元素删除,C++ 通过指针,Java则通过引用传递和适当的额外操作来实现删除功能。
接着我们就要思考:这个区别造成的影响了