C/C++——指针做参数

来源:互联网 发布:linux 更新grub命令 编辑:程序博客网 时间:2024/06/05 08:09

需求分析:

指针做参数
数组做参数
指针数组做参数
二维数组做为参数
二维指针做数组



编译环境:

vsiual studio 2010




解决方案:

1. 指针做参数

#include <stdio.h>// 形参做参数void Func1( char cTemp ){    cTemp = 'B';}// 指针做参数void Func2( char *pChar ){    *pChar = 'C';}int main( int argc, char *argv[] ){    char m = 'A';    printf( "初始值: m = %c\n", m );    // 形参做参数的时候,变量的值保留不变    Func1( m );    printf( "形参做参数: m = %c\n", m );    // 指针做参数的时候,变量的值发生了改变    Func2( &m );    printf( "指针做参数: m = %c\n", m );    return 0;}

这里写图片描述



2. 数组做参数

#include <stdio.h>// 形参做参数void Func1( char cTemp ){    cTemp = 'B';}// 数组做参数void Func3( char pChar[] ){    pChar[0] = 'D';}int main( int argc, char *argv[] ){    // 数组在声明式可以通过方括号逐个赋值,但是过了声明阶段以后就不能使用该方式逐个赋值    char T[10] = { 'a', 'b', 'c' };    char m[1] = {'A'};    printf( "初始值: m = %c\n", m[0] );    // 数组做参数时,值改变保留下来    Func3( m );    printf( "数组做参数: m = %c\n", m[0] );    return 0;}

声明的时候,超过数组的范围时候会报错
不够的话则会以0补全
不初始化的话则会是不确定的随机值
这里写图片描述

运行结果
这里写图片描述



3. 指针和数组的转换
一维数组

#include <stdio.h>int main(int argc, char *argv[]){    // 一维数组    char aTemp[10] = { 'a', 'b', 'c' };    // 也就是一维数组可以通过下述方式转换    char *pTemp = aTemp;    char *pTemp2 = &aTemp;    char *pTemp3 = &aTemp[0];    // 实际测试会发现上面三个值都是相等的,一维数组和指针的关系还是比较清晰的    return 0;}

二维数组

int main(int argc, char *argv[]){    // 二维数组    char aaTemp[3][4] = { {'a', 'b', 'c'},                          {'x', 'y', 'z'},                          {'u', 'v', 'w'} };    // 可以正常转换    char* pTemp = &aaTemp[0][0];    // 但是此时的数组名表示的一个aaTemp[][4]的指针    // 以下会发生编译错误     char** pTemp = aaTemp;      // 编译通过    char(*pTemp)[4] = aaTemp;    return 0;}

这里写图片描述



4. 指针指针做参数
基于上述现象,就会经常容易碰到一些问题

int GetConfig( char **pName, char **pFile, int nSize ){    int nCount = 0;    // ... 经过一些处理    for( int i = 0; i < 10 && i < nSize; i++ )    {        // 做某些处理然后假设筛选出我们要的功能名字和对应的配置名字        // 需要将该结果输出到接收数组里        strcpy( pName[nCount], "Function" );        strcpy( pFile[nCount], "Setting.set" );        nCount++;    }    return nCount;}int main( int argc, char *argv[] ){    char Name[100][256] = {0};    char File[100][256] = {0};    GetConfig( Name, File, 100 );}

编译器直接告诉你不能从char[100][256]转换到char**类型
这里写图片描述

这个时候我们就需要修改函数的参数格式

// 这个是目前个人碰到概率稍大,但是写法又比较奇特的,实际又还算有使用价值的情况int GetConfig( char(*pName)[256], char(*pFile)[256], int nSize ){    // ....}// 也可以通过typdef简化参数typdef char(*AA_256)[256];int GetConfig( AA_256 pName, AA_256 pFile, int nSize ){    // ....}

这个时候就可以正常编译通过
这里写图片描述





To be modifed。。。
结果:
传递给pArray的指针,是一大堆为未初始化的指针,这些野指针对我们来说没有什么实际价值。
运行结果

如果修改其中代码

int main(int argc, char* argv[]){    // char* pGroup[20]; 修改为下面形式    char Group[20][256];    // 无法转换成char* []    Func( Group, sizeof(Group) );    Func( Group[0], sizeof(Group) );    Func( &Group[0], sizeof(Group) );    // 无法转换成char* []    Func( (char *[])Group, sizeof(Group) );    Func( (char *[])Group[0], sizeof(Group) );    Func( (char *[])&Group[0], sizeof(Group) );    // 无法转换成char* []    Func( reinterpret_cast<char*[]>(Group), sizeof(Group) );    Func( reinterpret_cast<char*[]>(Group[0]), sizeof(Group) );    Func( reinterpret_cast<char*[]>(&Group[0]), sizeof(Group) );    return 0;}

编译的时候系统就会提示:

error C2664: ‘Func’ : cannot convert parameter 1 from ‘char [20][256]’ to ‘char *[]’

error C2664: ‘Func’ : cannot convert parameter 1 from ‘char [256]’ to ‘char *[]’

error C2664: ‘Func’ : cannot convert parameter 1 from ‘char (*)[256]’ to ‘char *[]’

没有任何方法将参数转换成该形式,对应的都会提示上述信息。



当然任何问题都有解决之道:

// 方法一int main(int argc, char* argv[]){    char* pGroup[20];    for( int i = 0; i < 20; i++ )    {        pGroup[i] = new char[256]; // (1)    }    Func( Group, sizeof(Group) );}// 方法二int main(int argc, char* argv[]){    char* pGroup[20];     char Group[20][256];    for( int i = 0; i < 20; i++ )    {        pGroup[i] = (char*)&Group[i]; // (2)需要强制转换一下        }    Func( pGroup, sizeof(pGroup)/sizeof(char*) );}

上述两种操作,都可以令这个函数形式有意义
上面的内容可能不容易看出问题,char*可能实际上都可以较正常的使用,当把char* 替换成int* 的时候就能看出这种传递参数不合理的地方。



当把 char* 替换成别的指针类型的时候例如: int* 的时候,依然存在上述问题。本质上是二维数组做参数的时候却没有指定第二维的长度。

int Func2( int* pArray[], int Count ){    // 例如此时如果你想求数组所有的数据的和的时候,你会发现维度的丢失    // 这个时候除非依靠上下文才能保证函数可以工作,但是仅仅只是工作于你所已知的上下文,例如第二个纬度为256的时候    // 如果提供第二个维度的信息,那还不如用下面函数替代}int BetterFunc2( int* pArray, int First, int Second ){    // ...}// int* 数组的时候需要同样的处理int main(int argc, char* argv[]){    int* pnGroup[20];    int nGroup[20][256] = {0};    for( i = 0; i < 20; i++ )    {        pnGroup[i] = (int*)&nGroup[i];       }    Func2( pnGroup, 256 );}

2. 二维数组

假如二维数组生命如下,编译的时候系统就会提示错误

int GetSum( int pArray[][], int Count ){    // .... }

编译结果:
这里写图片描述



正常二维数组做参数时候的声明,需要添加第二个维度的长度定义

int GetSum( int pArray[][20], int Count ){    int sum = 0;    for( int i = 0; i < Count; i++ )    {        for( int j = 0; j < 20; j++ )        {            sum += pArray[i][j];        }    }    return sum;}

同理上面的char* pArray[] 在实际使用的时候还是声明具体的第二个维度比较合适

// 打印文件路径集合里面的所有路径信息void printFilePath( char pPathGroup[][512], int count ){    for( int i = 0; i < count; i++ )    {        printf( "Path%d : %s", pPathGroup[i] );    }}

当使用指针做参数的时候,就会造成维度信息的丢失,所以一般往往都会附加一个int 型参数说明具体长度

【返回】

C/C++——分类目录

1 0
原创粉丝点击