指针·对于指针传参的一些规定

本文深入探讨了C语言中指针的基本概念与操作技巧,包括野指针的概念及如何避免,以及指针传参时的常见误区与正确实践。通过具体示例帮助读者更好地理解和运用指针。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

许久没用指针,很多东西都遗忘了,在学习C语言版的数据结构时,对于某些指针显得力不从心,不定期更新指针的操作

一、野指针

int main() {
    int *p1, *p2;
    if (p1 == NULL) {
        cout << "+++" <<endl;
    }
}

实际上,这并没有能输出+++,这里只是随机分配一个地址,而并非NULL;

二、指针传参

指针传参确实可以从根本上对变量进行操作,但是关于内存分配上有一点不同。

#include <stdio.h>

void mall(int * p) {
    p = (int* )malloc(sizeof(int));
}

int main()
{
    int *p1 = NULL, *p2 = NULL;
    p1 = (int *) malloc(sizeof(int ));
    mall(p2);
    if (p1 == NULL) {
        printf("++++\n");
    }
    if (p2 == NULL) {
        printf("----\n");
    }
    else {
        printf("//////\n");
    }
    return 0;
}

我们我们发现通过这种传参方式并不能给p2分配内存空间,这是因为,我们虽然将p2指针传到函数中实际上这个p2是一个形参变量,和我们传递一个int index(int a)的这个a一样,并没有从根本上将其改变所以并不能影响到p2,我们只是给p分配了一块空间。

正确的做法应该是

void mall(int ** p) {
    *p = (int* )malloc(sizeof(int));
}


### 如何传递二维数组作为函数参数 当处理二维数组并将其作为参数传递给函数时,需要注意几个关键点。对于一维数组而言,可以简单地通过指针来表示整个数组 `void fun(int a[])` 或者 `void fun(int *a)`[^1]。 然而,针对二维数组,情况有所不同。如果尝试使用如下方式定义函数: ```c void fun(int matrix[][], int m, int n); ``` 编译器将会报错 `error C2087: '': missing subscript`,这是因为C语言规定在声明多维数组的时候除了最左边维度外其他所有维度都必须指定大小[^2]。 为了正确地将二维数组传入函数,有两种常见方法: #### 方法一:固定列数 可以通过显式指出第二维(即每行中的元素数量)的方式来进行传递: ```c #include <stdio.h> // 定义具有固定宽度的二维数组 #define COLS 3 void printMatrix(int mat[][COLS], int rows) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < COLS; ++j) { printf("%d ", mat[i][j]); } printf("\n"); } } int main() { int myArray[2][3] = {{1, 2, 3}, {4, 5, 6}}; // 调用printMatrix函数 printMatrix(myArray, 2); return 0; } ``` 这种方法适用于已知每一行长度相同的情形下,并且该长度在整个程序运行期间不会改变。 #### 方法二:使用指向指针的方法 另一种更灵活的选择是利用双重指针或者说是“指针指针”的概念。这种方式允许创建不规则形状的数据结构,其中各行可能拥有不同数量的元素。下面是一个例子说明如何实现这一点: ```c #include <stdio.h> #include <stdlib.h> void printIrregularMatrix(int **mat, int rows, int cols[]) { for (int i = 0; i < rows; ++i) { for (int j = 0; j < cols[i]; ++j) { printf("%d ", mat[i][j]); } printf("\n"); } } int main() { const int ROWS = 2; int colSizes[ROWS] = {3, 4}; // 各自不同的列宽 // 动态分配内存空间用于存储各行列地址 int **myIrregArray = malloc(ROWS * sizeof(*myIrregArray)); if (!myIrregArray) exit(-1); // 分配实际数据区域并将它们链接起来形成矩阵形式 for (int i = 0; i < ROWS; ++i){ myIrregArray[i] = malloc(colSizes[i]*sizeof(**myIrregArray)); if(!myIrregArray[i]) exit(-1); // 初始化一些值以便观察效果 for(int j=0;j<colSizes[i];++j) myIrregArray[i][j]=(i+1)*(j+1); } // 使用前先打印出来看看是不是我们想要的样子 printIrregularMatrix(myIrregArray, ROWS, colSizes); // 清理资源防止泄漏 for (int i = 0; i < ROWS; ++i) free(myIrregArray[i]); free(myIrregArray); return 0; } ``` 此代码片段展示了如何构建一个非矩形(也称为稀疏或锯齿状)的二维数组,并成功地将其传递给了另一个函数进行操作。注意这里涉及到动态内存管理的知识点,因此要特别小心避免造成内存泄露等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值