2026/5/21 17:09:07
网站建设
项目流程
iis v6 新建网站,网站的制作与调试,开发app应用公司排名,网页编辑栏无法写入函数和二维数组
为编写将二维数组作为参数的函数#xff0c;必须牢记#xff0c;数组名被视为其地址#xff0c;因此#xff0c;相应的形参是一个指针#xff0c;
就像一维数组一样。比较难处理的是如何正确地声明指针。例如#xff0c;假设有下面的代码#xff1a;
int…函数和二维数组为编写将二维数组作为参数的函数必须牢记数组名被视为其地址因此相应的形参是一个指针就像一维数组一样。比较难处理的是如何正确地声明指针。例如假设有下面的代码int data[3][4]{{1,2,3,4},{9,8,7,6},{2,4,6,8}}; int totalsum{data,3};则sum( )的原型是什么样的呢函数为何将行数3作为参数而将列数4作为参数呢Data 是一个数组名该数组有3 个元素。第一个元素本身是一个数组有4 个int 值组成。因此data的类型是指向由4 个int 组成的数组的指针因此正确的原型如下int sum(int (*ar2)[4],int size);其中的括号是必不可少的因为下面的声明将声明一个由4 个指向int 的指针组成的数组而不是由一个指向由4 个int 组成的数组的指针另外函数参数不能是数组int *ar2[4];还有另外一种格式这种格式与上述原型的含义完全相同但可读性更强int sum(int ar2[][4],int size);上述两个原型都指出ar2 是指针而不是数组。还需注意的是指针类型指出它指向由4 个int 组成的数组。因此指针类型指定了列数这就是没有将列数作为独立的函数参数进行传递的原因。由于指针类型指定了列数因此sum( )函数只能接受由4 列组成的数组。但长度变量指定了行数因此sum( )对数组的行数没有限制int a[100][4]; int b[6][4]; ... int total1sum(a,100); int total2sum(b,6); int total3sum(a,10); int total4sum(a10,20);由于参数ar2 是指向数组的指针那么我们如何在函数定义中使用它呢最简单的方法是将ar2 看作是一个二维数组的名称。下面是一个可行的函数定义int sum(int ar2[][4],int size) { int total0; for(int r0;rsize;r) for(int c0;c4;c) totalar2[r][c]; return total; }同样行数被传递给size 参数但无论是参数ar2 的声明或是内部for 循环中列数都是固定的—4 列。可以使用数组表示法的原因如下。由于ar2 指向数组它的元素是由4 个int 组成的数组的第一个元素元素0因此表达式ar2 r 指向编号为r 的元素。因此ar2[r]是编号为r 的元素。由于该元素本身就是一个由4 个int 组成的数组因此ar2[r]是由4 个int 组成的数组的名称。将下标用于数组名将得到一个数组元素因此ar2[r][c]是由4 个int 组成的数组中的一个元素是一个int 值。必须对指针ar2 执行两次解除引用才能得到数据。最简单的方法是使用方括号两次ar2[r][c]。然而如果不考虑难看的话也可以使用运算符*两次ar2[r][c]*(*(ar2r)c)为理解这一点读者可以从内向外解析各个子表达式的含义ar2 ar2r *(ar2r) *(ar2r)c *(*(ar2r)c)sum( )的代码在声明参数ar2 时没有使用const因为这种技术只能用于指向基本类型的指针而ar2是指向指针的指针。函数和C-风格字符串C-风格字符串由一系列字符组成以空值字符结尾。前面介绍的大部分有关设计数组函数的知识也适用于字符串函数。例如将字符串作为参数时意味着传递的是地址但可以使用const 来禁止对字符串参数进行修改。然而下面首先介绍一些有关字符串的特殊知识。将C-风格字符串作为参数的函数假设要将字符串作为参数传递给函数则表示字符串的方式有三种char 数组用引号括起的字符串常量也称字符串字面值被设置为字符串的地址的char 指针。但上述3 种选择的类型都是char 指针准确地说是char*因此可以将其作为字符串处理函数的参数char ghost[15]galloping; char *strgalumphing; int n1strlen(ghost); int n2strlen(str); int strlen(gamboling);可以说是将字符串作为参数来传递但实际传递的是字符串第一个字符的地址。这意味着字符串函数原型应将其表示字符串的形参声明为char *类型。C-风格字符串与常规char 数组之间的一个重要区别是字符串有内置的结束字符前面讲过包含字符但不以空值字符结尾的char 数组只是数组而不是字符串。这意味着不必将字符串长度作为参数传递给函数而函数可以使用循环依次检查字符串中的每个字符直到遇到结尾的空值字符为止。程序清单7.9 演示了这种方法使用一个函数来计算特定的字符在字符串中出现的次数。由于该程序不需要处理负数因此它将计数变量的类型声明为unsigned int。#include iostream unsigned int c_in_str(const char* str, char ch); int main() { using namespace std; char mmm[15]minimum; const char *wailululate; unsigned int ms c_in_str(mmm, m); unsigned int us c_in_str(wail, u); cout ms m characters in mmm endl; cout us u characters in wail endl; return 0; } unsigned int c_in_str(const char* str, char ch) { unsigned int count0; while (*str) { if(*strch) count; str; } return count; }下面是该程序的输出3m characters inminimum 2u characters inululate程序说明由于程序清单7.9 中的c_int_str( )函数不应修改原始字符串因此它在声明形参str 时使用了限定符const。这样如果错误地址函数修改了字符串的内容编译器将捕获这种错误。当然可以在函数头中使用数组表示法而不声明strunsignex int c_in_str(const char str[],char ch)然而使用指针表示法提醒读者注意参数不一定必须是数组名也可以是其他形式的指针。该函数本身演示了处理字符串中字符的标准方式while(*str) { statements str; }str 最初指向字符串的第一个字符因此*str 表示的是第一个字符。例如第一次调用该函数后*str的值将为m—“minimum”的第一个字符。只要字符不为空值字符\0str 就为非零值因此循环将继续。在每轮循环的结尾处表达式str将指针增加一个字节使之指向字符串中的下一个字符。最终str 将指向结尾的空值字符使得str 等于0—空值字符的数字编码从而结束循环。返回C-风格字符串的函数现在假设要编写一个返回字符串的函数。是的函数无法返回一个字符串但可以返回字符串的地址这样做的效率更高。例如程序清单7.10 定义了一个名为buildstr( )的函数该函数返回一个指针。该函数接受两个参数一个字符和一个数字。函数使用new 创建一个长度与数字参数相等的字符串然后将每个元素都初始化为该字符。然后返回指向新字符串的指针。#include iostream char* buildstr(char c, int n); int main() { using namespace std; int times; char ch; cout Enter a character:; cin ch; cout Enter an iteger:; cin times; char* ps buildstr(ch, times); cout ps endl; delete[] ps; ps buildstr(, 20); cout ps -DONE- ps endl; delete[] ps; return 0; } char* buildstr(char c, int n) { char* pstr new char[n 1]; pstr[n] \0; while(n--0) pstr[n] c; return pstr; }运行结果Enter a character:V Enter an iteger:46 VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV -DONE-程序说明要创建包含n 个字符的字符串需要能够存储n 1 个字符的空间以便能够存储空值字符。因此程序清单7.10 中的函数请求分配n 1 个字节的内存来存储该字符串并将最后一个字节设置为空值字符然后从后向前对数组进行填充。在程序清单7.10 中下面的循环将循环n 次直到n 减少到0这将填充n 个元素while(n--0) pstr[n]c;在最后一轮循环开始时n 的值为1。由于n−−意味着先使用这个值然后将其递减因此while 循环测试条件将对1 和0 进行比较发现测试为true循环继续。测试后函数将n 减为0因此pstr[0]是最后一个被设置为c 的元素。之所以从后向前而不是从前向后填充字符串是为了避免使用额外的变量。从前向后填充的代码将与下面类似int i0; while(in): pstr[i]c;注意变量pstr 的作用域为buildstr 函数内因此该函数结束时pstr而不是字符串使用的内存将被释放。但由于函数返回了pstr 的值因此程序仍可以通过main( )中的指针ps 来访问新建的字符串。当该字符串不再需要时程序清单7.10 中的程序使用delete 释放该字符串占用的内存。然后将ps指向为下一个字符串分配的内存块然后释放它们。这种设计让函数返回一个指针该指针指向new 分配的内存的缺点是程序员必须记住使用delete。在第12 章中读者将知道C类如何使用构造函数和析构函数负责为您处理这些细节。