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++——分类目录
- C/C++——指针做参数
- 指针做函数参数——高效C语言
- c指针做函数参数
- c语言指针做参数的优点
- C语言:指针做函数参数
- C/CPP点滴积累—数组做函数参数退化为指针
- C语言之指针专题四:指针做函数参数
- C语言之指针专题四:指针做函数参数
- C语言函数指针做函数参数案例
- C/C++ 指针做参数 堆内存分配
- 黑马程序员-------C语言----指针做函数参数
- C/C++ 指针做参数 堆内存分配
- C++\C指针作为参数
- c语言用指针做函数参数和用变量做函数参数的不同点
- 【C语言提高37】结构体元素做函数参数与结构指针做函数参数
- C指针参数传递
- C语言之指针专题二:指针做函数参数是指针存在的最大意义
- C语言指针笔记之 一级指针的应用(指针做函数参数)
- java随机生成四位字符验证码(使用Graphics绘图类)
- winform中自定义的窗体移动代码
- 深入理解Java虚拟机 读书笔记
- Mysql优化
- Javascript 多浏览器兼容性问题及解决方案
- C/C++——指针做参数
- Iterator、ListIterator、foreach、Enumeration
- C语言--结构体内存计算规则
- logback使用
- python urllib2爬取网页,编码问题
- intellij ieda下将空包展开显示
- 秒杀多线程-一个经典的多线程同步问题
- 商业模型
- SVProgressHUD 的显示时间