资源预览内容
第1页 / 共109页
第2页 / 共109页
第3页 / 共109页
第4页 / 共109页
第5页 / 共109页
第6页 / 共109页
第7页 / 共109页
第8页 / 共109页
第9页 / 共109页
第10页 / 共109页
亲,该文档总共109页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
排错涉及到一种逆向推理,就像侦破一个杀人谜案。有些不可能的事情发生了,而仅有的信息就是它确实发生了!因此,我们必须从结果出发,逆向思考,去发现原因。有时你“看到的代码”实际上是你自己的意愿,而不是你实际写出来的东西。离开它一小段时间能够松驰你的误解,帮助代码显出其本来面目。 程序设计实践现实就是这样,总是存在许多程序错误,需要通过测试来发现,通过排错去纠正。关于数组、指针、函数的综合讨论2014.11.05(III-3200)3任务:姓名排序任务:姓名排序n电视歌手大奖赛开赛报名时,由于人数较多,一些参电视歌手大奖赛开赛报名时,由于人数较多,一些参赛信息需要及时录入计算机并用计算机进行管理。赛信息需要及时录入计算机并用计算机进行管理。n其中一个很重要的工作就是:要按选手姓名(汉语拼其中一个很重要的工作就是:要按选手姓名(汉语拼音)排序后编号,以决定选手比赛的顺序。音)排序后编号,以决定选手比赛的顺序。n请你编程实现对姓名拼音串按英文字典顺序排序的程请你编程实现对姓名拼音串按英文字典顺序排序的程序。序。n为测试程序,假定共有为测试程序,假定共有10名选手,选手姓名拼音最长名选手,选手姓名拼音最长不超过不超过20个英文字符,且中间无空格。个英文字符,且中间无空格。引子引子引子引子4#include #include using namespace std;using namespace std;int mainint main()() char namelist1020;char namelist1020;for (int i=0; i10; i+)for (int i=0; i10; i+) cout i singer name: ;cout i namelisti;cin namelisti; / / 此处代码省略(见后)用冒泡排序法对姓名进行排序此处代码省略(见后)用冒泡排序法对姓名进行排序for (int i=0; i10; i+)for (int i=0; i10; i+)cout i namelisti endl;cout i namelisti endl;return 0;return 0; 5#include #include using namespace std;using namespace std;int mainint main()() char namelist1020;char namelist1020;for (int i=0; i10; i+)for (int i=0; i10; i+) cout i singer name: ;cout i namelisti;cin namelisti; / / 此处代码省略(见后)用冒泡排序法对姓名进行排序此处代码省略(见后)用冒泡排序法对姓名进行排序for (int i=0; i10; i+)for (int i=0; i10; i+)cout i namelisti endl;cout i namelisti endl;return 0;return 0; 6#include #include using namespace std;using namespace std;int mainint main()() char namelist1020;char namelist1020;for (int i=0; i10; i+)for (int i=0; i10; i+) cout i singer name: ;cout i namelisti;cin namelisti; / / 此处代码省略(见后)用冒泡排序法对姓名进行排序此处代码省略(见后)用冒泡排序法对姓名进行排序for (int i=0; i10; i+)for (int i=0; i10; i+)cout i namelisti endl;cout i namelisti endl;return 0;return 0; 7#include #include using namespace std;using namespace std;int mainint main()() char namelist1020;char namelist1020; / / 数组下标从数组下标从0 0开始!开始!for (int i=0; i10; i+)for (int i=0; i10; i+) cout i singer name: ;cout i namelisti;cin namelisti; / / 此处代码省略(见后)用冒泡排序法对姓名进行排序此处代码省略(见后)用冒泡排序法对姓名进行排序for (int i=0; i10; i+)for (int i=0; i10; i+)cout i namelisti endl;cout i namelisti endl;return 0;return 0; 8先看看整数数组的冒泡算法先看看整数数组的冒泡算法for (j=for (j=1 1; ; j j=5 5; j+); j+) for (i=for (i=1 1; i=; i=6 6-j; i+)-j; i+) if (ai ai+1)if (ai ai+1) p = ai;p = ai;ai = ai+1;ai = ai+1;ai+1 = p;ai+1 = p; Page 93如何修改成以如何修改成以0为首元素下标?为首元素下标?9改成以改成以0 0为首元素下标为首元素下标for (j=for (j=0 0; ; j j 5 5; j+); j+) for (i=for (i=0 0; i; i5 5-j; i+)-j; i+) / why not “i6-j” ?/ why not “i6-j” ? if (ai ai+1)if (ai ai+1) p = ai;p = ai;ai = ai+1;ai = ai+1;ai+1 = p;ai+1 = p; 10依依样样画画葫葫芦芦for (j=for (j=0 0; ; j j 5 5; j+); j+) for (i=for (i=0 0; i; i5 5-j; i+)-j; i+) / why not “i6-j” ?/ why not “i6-j” ? if (ai ai+1)if (ai ai+1) p = ai;p = ai;ai = ai+1;ai = ai+1;ai+1 = p;ai+1 = p; for (j=for (j=0 0; ; j j 9 9; j+) ; j+) for (i=for (i=0 0; i; i9 9-j; i+)-j; i+) if (if (namelistnamelisti i namelistnamelisti+1)i+1) p = p = namelistnamelisti;i;namelistnamelisti = i = namelistnamelisti+1;i+1;namelistnamelisti+1 = p;i+1 = p; 11for (int i=0; ifor (int i=0; i9 9; i; i+)+)/轮轮( (遍遍, ,趟趟) )数数= =元素数目元素数目-1-1 for (int j=0; jfor (int j=0; j 0)(namelistj, namelistj+1) 0) char tmp20;char tmp20;strcpystrcpy(tmp, namelistj);(tmp, namelistj);strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1);strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 12for (int i=0; ifor (int i=0; i9 9; i; i+)+) for (int j=0; jfor (int j=0; j 0)(namelistj, namelistj+1) 0) char tmp20;char tmp20;strcpystrcpy(tmp, namelistj);(tmp, namelistj);strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1);strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 13for (int i=0; ifor (int i=0; i9 9; i; i+)+) for (int j=0; jfor (int j=0; j 0)(namelistj, namelistj+1) 0) / page 345, “strcpy()”/ page 345, “strcpy()”char tmp20;char tmp20;strcpystrcpy(tmp, namelistj);(tmp, namelistj);strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1);strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 字符串元素的特殊交换算法如何按字典逆序来排序姓名呢?如何按字典逆序来排序姓名呢?14如何按字典逆序来排序姓名如何按字典逆序来排序姓名for (int i=0; ifor (int i=0; i9 9; i; i+)+) for (int j=0; jfor (int j=0; j9-i9-i; j; j+)+) if (if (strcmpstrcmp(namelistj, namelistj+1) (namelistj, namelistj+1) 0)0) / / 同前省略同前省略 比较关系符改为小于号,即按字典逆序排序姓名。如何根据用户输入来决定按何种次序排序姓名呢?如何根据用户输入来决定按何种次序排序姓名呢?15n可以用一个变量来记录用户的输入,根据输可以用一个变量来记录用户的输入,根据输入选择来判定用户是想正逆排序姓名还是想入选择来判定用户是想正逆排序姓名还是想逆序排序姓名。逆序排序姓名。n该变量的类型可以是:该变量的类型可以是:布尔型布尔型 bool整数类型整数类型 int字符类型字符类型 char。排序准则的动态变化排序准则的动态变化为什么这些类型都可以?假设使用假设使用 char UserInput; 来记录用户选择:来记录用户选择:U表示升序,表示升序,D表示降序表示降序16排序准则的动态变化排序准则的动态变化 if (UserInput = D) / Down, if (UserInput = D) / Down, 降序排列降序排列if (if (strcmpstrcmp(namelistj, namelistj+1) (namelistj, namelistj+1) 0)0) / / 交换相邻元素,同前省略交换相邻元素,同前省略 17char UserInput;cout UserInput; / 确保输入合法 assert(UserInput = D | UserInput = U); 如果输入不合法,则程序会以崩溃的方式退出。如果输入不合法,则程序会以崩溃的方式退出。18for (int i=0; i9; i+)for (int i=0; i9; i+) for (int j=0; j9-i; j+)for (int j=0; j9-i; j+) ifif (UserInput = D) (UserInput = D) ifif (strcmp(namelistj, namelistj+1) 0) (strcmp(namelistj, namelistj+1) 0) (strcmp(namelistj, namelistj+1) 0) char tmp20;char tmp20; strcpy(tmp, namelistj);strcpy(tmp, namelistj); strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1); strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 程序代码还能程序代码还能更更简简捷一些捷一些吗?吗?19程序代码的简化程序代码的简化 if (UserInput = D)if (UserInput = D) if (strcmp(namelistj, namelistj+1) 0)if (strcmp(namelistj, namelistj+1) 0) char tmp20;char tmp20; strcpy(tmp, namelistj);strcpy(tmp, namelistj); strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1); strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 接连两个接连两个if判断,可合成一个!判断,可合成一个!if (cond_1) if (cond_2) / . if (cond_1 & if (cond_1 & cond_2) cond_2) / . / . 20for (int i=0; i9; i+)for (int i=0; i9; i+) for (int j=0; j9-i; j+)for (int j=0; j9-i; j+) if (if ( ( (UserInput = D)UserInput = D) & & (strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0) ) ) char tmp20;char tmp20; strcpy(tmp, namelistj);strcpy(tmp, namelistj); strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1); strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 程序代码还能做进一步的简化吗?程序代码还能做进一步的简化吗?21for (int i=0; i9; i+)for (int i=0; i9; i+) for (int j=0; j9-i; j+)for (int j=0; j9-i; j+) if (if ( ( (UserInput = D)UserInput = D) & & (strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0) ) ) char tmp20;char tmp20; strcpy(tmp, namelistj);strcpy(tmp, namelistj); strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1); strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 怎么简化?怎么简化?22for (int i=0; i9; i+)for (int i=0; i9; i+) for (int j=0; j9-i; j+)for (int j=0; j9-i; j+) if (if ( ( (UserInput = D)UserInput = D) & & (strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0)(strcmp(namelistj, namelistj+1) 0) ) ) char tmp20;char tmp20; strcpy(tmp, namelistj);strcpy(tmp, namelistj); strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1); strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp); 怎么定义怎么定义Swap()函数函数呢?呢?Swap(namelistj, namelistj+1);Swap(namelistj, namelistj+1);Swap(namelistj, namelistj+1);Swap(namelistj, namelistj+1);23Swap(Swap() )函数的定义函数的定义n注意到:调用该函数时,实参是注意到:调用该函数时,实参是 namelistjnamelistj和和 namelistj+1namelistj+1,它们分别对应二维数组变量,它们分别对应二维数组变量 namelistnamelist的的第第j j“行行” 和和第第j+1j+1“行行”n二维数组的二维数组的“行变量行变量”对应的是一个数组:对应的是一个数组: void Swap(void Swap(charchar first first , , charchar second second ););24void Swap(char first, char second)char tmp20;strcpy(tmp, first);strcpy(first, second);strcpy(second, tmp);if ( (UserInput = D) & (strcmp(namelistj, namelistj+1) 0) ) char tmp20;char tmp20;strcpy(tmp, namelistj);strcpy(tmp, namelistj);strcpy(namelistj, namelistj+1);strcpy(namelistj, namelistj+1);strcpy(namelistj+1, tmp);strcpy(namelistj+1, tmp);25for (int i=0; i9; i+) for (int j=0; j9-i; j+) if ( (UserInput = D) & (strcmp(namelistj, namelistj+1) 0) ) SwapSwap(namelistj, namelistj+1);26依依样样画画葫葫芦芦for (j=0; j5; j+)for (j=0; j5; j+) for (i=0; i5-j; i+)for (i=0; i5-j; i+) if (ai ai+1)if (ai ai+1) p = ai;p = ai;ai = ai+1;ai = ai+1;ai+1 = p;ai+1 = p; for (j=0; j5; j+)for (j=0; j5; j+) for (i=0; i5-j; i+)for (i=0; i5-j; i+) if (ai ai+1)if (ai ai+1) Swap(ai, ai+1);Swap(ai, ai+1); Page 9327Swap(Swap() )函数的定义函数的定义n注意到:调用该函数时,程序中的实参是注意到:调用该函数时,程序中的实参是 aiai和和 ai+1ai+1,它们分别对应一维数组变,它们分别对应一维数组变量量a a的第的第i i和第和第i+1i+1个元素个元素n一维整数数组的元素,是一个整数,其类一维整数数组的元素,是一个整数,其类型是整数类型型是整数类型n故有故有void Swap(void Swap(intint first, first, intint second); second);依依样样画画葫葫芦芦28#include using namespace std;void Swap(int first, int second)void Swap(int first, int second) int p;int p;p = first;p = first;first = second;first = second;second = p;second = p; int main() int i, j, p, a6;memset(a, 0, sizeof(a);for (i=0; i6; i+) cout 请输入待排序的数a i ai;依依样样画画葫葫芦芦29for (j=0; j5; j+)for (i=0; i5-j; i+)if (ai ai+1)Swap(ai, ai+1); for (i=0; i6; i+)cout ai endl;return 0;依依样样画画葫葫芦芦可惜啊!程序结果并不正确!30BUGBUG(问题)在哪里?(问题)在哪里?void Swap(int first, int second) int p;p = first;first = second;second = p;变量first和second是函数Swap的形式参数,该函数被调用时,实参的值是被赋值给形参的,即相当于是复制了一份。所以,在函数Swap中交换的是“复制品”之间内容的交换,并不影响实参的内容(值)!31验证一下验证一下#include using namespace std;void Swap(int first, int second)int p;p = first;first = second;second = p;int main()int a = 3, b = 4;cout Before calling Swap(), a = a , b = b endl;Swap(a, b);cout After calling Swap(), a = a , b = b endl;return 0;32void Swap(int first, int second) cout &first = &first , &second = &second endl;/ 同前省略int main() int a = 3, b = 4;cout &a = &a , &b = &b endl;/ 同前省略进一步验证进一步验证33比较实参与形参的内存单元比较实参与形参的内存单元34如何改正这个如何改正这个BUGBUG(问题)(问题)void Swap(int* first, int* second)int p;p = *first;*first = *second;*second = p;/ in main()for (j=0; j5; j+)for (i=0; i5-j; i+)if (ai ai+1) Swap(& &(ai), & &(ai+1);35为什么这样为什么这样BUGBUG就被去掉了?就被去掉了?firstsecond3849aiai+10X22FF400X22FF440X22FF400X22FF443849aiai+10X22FF400X22FF44int p = *first; *first = *second; *second = p;0X22FF400X22FF4449aiai+10X22FF400X22FF44?0X22FF400X22FF440X22FF400X22FF400X22FF440X22FF440X22FF400X22FF400X22FF440X22FF400X22FF44firstsecondfirstsecondfirstsecond函函数数调调用用前前函函数数调调用用时时函函数数调调用用中中3836为什么这样为什么这样BUGBUG就被去掉了?就被去掉了?firstsecond3849aiai+10X22FF400X22FF440X22FF400X22FF443849aiai+10X22FF400X22FF44int p = *first; *first = *second; *second = p;0X22FF400X22FF44aiai+10X22FF400X22FF44?0X22FF400X22FF440X22FF400X22FF400X22FF440X22FF440X22FF400X22FF400X22FF440X22FF400X22FF44firstsecondfirstsecondfirstsecond函函数数调调用用前前函函数数调调用用时时函函数数调调用用中中494937为什么这样为什么这样BUGBUG就被去掉了?就被去掉了?firstsecond3849aiai+10X22FF400X22FF440X22FF400X22FF443849aiai+10X22FF400X22FF44int p = *first; *first = *second; *second = p;0X22FF400X22FF44aiai+10X22FF400X22FF44?0X22FF400X22FF440X22FF400X22FF400X22FF440X22FF440X22FF400X22FF400X22FF440X22FF400X22FF44firstsecondfirstsecondfirstsecond函函数数调调用用前前函函数数调调用用时时函函数数调调用用中中493838为什么这样为什么这样BUGBUG就被去掉了?就被去掉了?firstsecond3849aiai+10X22FF400X22FF440X22FF400X22FF443849aiai+10X22FF400X22FF44int p = *first; *first = *second; *second = p;?aiai+10X22FF400X22FF44?0X22FF400X22FF44?0X22FF400X22FF440X22FF400X22FF440X22FF400X22FF44firstsecondfirstsecondfirstsecond函函数数调调用用前前函函数数调调用用时时函函数数调调用用后后493839for (int i=0; i9; i+) for (int j=0; j9-i; j+) if ( (UserInput = D) & (strcmp(namelistj, namelistj+1) 0) ) SwapSwap(namelistj, namelistj+1);程序代码还能做进一步的简化吗?程序代码还能做进一步的简化吗?回到 姓名排序(二维数组) 问题上来40strcmp(strcmp() )的返回值是什么?的返回值是什么?#include #include using namespace std;using namespace std;int main()int main() cout strcmp(AAA, BBB) endl;cout strcmp(AAA, BBB) endl;cout strcmp(DDD, BBB) endl;cout strcmp(DDD, BBB) endl;return 0;return 0; 程序输出为:1141for (int i=0; i9; i+) for (int j=0; j9-i; j+) ifif ( (UserInput = D) & (strcmp(namelistj, namelistj+1) = -1) ) SwapSwap(namelistj, namelistj+1);ifif ( (UserInput = U) & (strcmp(namelistj, namelistj+1) = 1) ) SwapSwap(namelistj, namelistj+1);int UserInput ? 042/ .int UserInput;cin UserInput;assert(UserInput = -1 | UserInput = 1);for (int i=0; i9; i+) for (int j=0; j9-i; j+) ifif (strcmp(namelistj, namelistj+1) = UserInput) / 两种排序准则合并在一起处理 SwapSwap(namelistj, namelistj+1);/ .抽取两种排序准则的共性思考题:如果用户仍然希望使用U和D表示升序和降序,程序应如何修改?43下面,任务又改变啦!领导和观众都强烈要求按歌手类型分开比赛,以保证公平竞争。即,会有多个不同人数的姓名数组需要排序处理。程序该如何修改呢?如通俗歌手有20人,美声歌手有15人。44难道是这样么?不过难道是这样么?不过有点有点for (int i=0; i19; i+) / 通俗歌手排序for (int j=0; j19-i; j+) if (strcmp(NL_1j, NL_1j+1) = UserInput) SwapSwap(NL_1j, NL_1j+1);for (int i=0; i14; i+) / 美声歌手排序for (int j=0; j14-i; j+) if (strcmp(NL_2j, NL_2j+1) = UserInput) SwapSwap(NL_2j, NL_2j+1);45冒泡泡的函数上场啦冒泡泡的函数上场啦Void bubble(char NL20, int num, char NL20, int num, char NL20, int num, char NL20, int num, int UserInput int UserInput int UserInput int UserInput) for (int i=0; inum-1; i+) for (int j=0; jnum-1-i; j+) if (strcmp(NLj, NLj+1) = UserInput) SwapSwap(NLj, NLj+1);/ .bubble(NL_1, 20, UserInput);bubble(NL_2, 15, UserINput);46void bubble(int a, int num)for (int j=0; jnum-1; j+)for (int i=0; inum-1-j; i+)if (ai ai+1) Swap(&(ai), &(ai+1);依依样样画画葫葫芦芦Page 93示例修改示例修改47另一种常见的定义方式另一种常见的定义方式void bubble(int* a, int num)for (int j=0; jnum-1; j+)for (int i=0; inum-1-j; i+)if (ai ai+1) Swap(&(ai), &(ai+1); 编译器认为上述两种写法是相同的编译器认为上述两种写法是相同的Page 93示例修改示例修改48如果排序准则也要求动态设定如果排序准则也要求动态设定void bubble(int* a, int num, int order)for (int j=0; jnum-1; j+)for (int i=0; inum-1-j; i+)if (ai ai+1) Swap(&(ai), &(ai+1); 依依样样画画葫葫芦芦上述函数应该如何修改其实现呢?上述函数应该如何修改其实现呢?Page 93示例修改示例修改49回顾一下姓名排序代码回顾一下姓名排序代码Void bubble(char NL20, int num, char NL20, int num, char NL20, int num, char NL20, int num, int UserInput int UserInput int UserInput int UserInput) for (int i=0; inum-1; i+) for (int j=0; jnum-1-i; j+) if (strcmp(NLj, NLj+1) = UserInput) SwapSwap(NLj, NLj+1); Page 93示例修改示例修改50增加一个增加一个 int_cmp(int_cmp() ) 函数?函数?void bubble(int* a, int num, int order)for (int j=0; jnum-1; j+)for (int i=0; inum-1-j; i+)if (int_cmp(ai, ai+1) = order) Swap(&(ai), &(ai+1); 依依样样画画葫葫芦芦Page 93示例修改示例修改51int_cmp(int, int)int_cmp(int, int)的实现的实现int int_cmp(int a, int b)if (a b)return 1;return 0; / 完全参照 strcmp 的功能实现Page 93示例修改示例修改52为什么不这样为什么不这样实现呢?实现呢?bool int_cmp(int a, int b, int order)if (a b) return order = 1;return false; / V1.0Page 93示例修改示例修改53为什么不这样为什么不这样实现呢?实现呢?bool int_cmp(int a, int b, int order) if ( (a b) & (order = 1) ) return true; return false; / V2.0Page 93示例修改示例修改54为什么不这样为什么不这样实现呢?实现呢?bool int_cmp(int a, int b, int order) if ( (a b)&(order = 1) ) return true; return false; / V3.0Page 93示例修改示例修改55为什么不这样为什么不这样实现呢?实现呢?bool int_cmp(int a, int b, int order) return (a b)&(order = 1) ; / V4.0Page 93示例修改示例修改56void bubble(int* a, int num, int order)for (int j=0; jnum-1; j+)for (int i=0; inum-1-j; i+)if (int_cmp(ai, ai+1, order) Swap(&(ai), &(ai+1);你还想到怎么修改上面的代码?你还想到怎么修改上面的代码?Page 93示例修改示例修改(未完持续)数组与指针int main() int a14 = 1,2,3, a25 = 1,2,1,2,9;int *p = a1, *q; / 注意指针q的定义方式for (int i=0; i4; i+) cout pi = *(p+i) ;cout =a2; p-) cout *p ; / 指针用作循环变量cout endl;q = a2;for (; qa2+5; q+) cout *q ;cout endl;p = a1; / 数组变量可以直接赋值给指针变量cout p = p a1 = a1 endl; p = a2; cout p = p , a2 = a2 endl;cout p+1 = p + 1 , a2+1 = a2 + 1 endl;cout *(p+2) = *(p + 2) , p2 = p2 endl;cout *(a2+2) = *(a2 + 2) , a22 = a22 endl;return 0;/ pointer-array-1.cpp58参考输出59请请在此在此页总结页总结要点要点60数组与指针#include using namespace std;int main() int a14 = 1,2,3, a25 = 1,2,1,2,9;int *p = a1, *q; / 指针变量与数组变量的“大小”是不同的cout sizeof(a1) = sizeof(a1) endl;cout sizeof(a2) = sizeof(a2) endl;cout sizeof(p) = sizeof(p) endl;cout sizeof(q) = sizeof(q) endl;#ifdef SHOW_ERRORa1 = q; / 数组变量不能接受赋值a2 = p; #endifreturn 0; / pointer-array-2.cpp61参考输出62请请在此在此页总结页总结要点要点63#include using namespace std;void test_1(int a, int len) / 数组变量作函数参数cout test_1(): a = a , len = len endl tt;for (int i=0; ilen; i+) cout ai = *(a+i) ;cout endl;void test_2(int* a, int len) / 指针变量作函数参数cout test_2(): a = a , len = len endl tt;for (int i=0; ilen; i+) cout ai = *(a+i) ;cout endl;数组与指针64int main()int a14 = 1,2,3;int a25 = 1,2,1,2,9;cout main(): a1 = a1 , a2 = a2 endl;test_1(a1, 4);test_1(a2, 5);test_2(a1, 4);test_2(a2, 5);int* p = a2;test_1(p, 2);test_2(p, 3);return 0; / pointer-array-3.cpp数组与指针65参考输出66请请在此在此页总结页总结要点要点67数组与指针#include using namespace std;void test_3(charchar a, int len)cout test_3(): a = a , len = len endl tt;for (int i=0; ilen; i+)cout ai = *(a+i) ;cout endl;void test_4(char* char* a, int len)cout test_4(): a = a , len = len endl tt;for (int i=0; ilen; i+)cout ai = *(a+i) ;cout endl;68数组与指针int main() char* name1= XXX; / 这是初始化,不是赋值!char name2= tsinghua;char name310= computer;name1 = name1 = J0X-?; / OK! 改变字符指针变量的值/ name2 = YYY; name3 = ZZZ; ERROR!/ (数组形式的)字符串赋值,必须使用 strcpy 函数!test_3(name1, 4);test_4(name1, 4);test_3(name2, 8);test_4(name2, 8);test_3(name3, 8);test_4(name3, 8);test_3(name3, 10);test_4(name3, 10);test_3(name3, 3);test_4(name3, 3);return 0; / pointer-array-4.cpp注意代码中关于注意代码中关于 name1 = name1 = “J0X-?J0X-?”; ; 的说明。的说明。“J0X-?J0X-?”是一个常量字符串,它也对应一个地是一个常量字符串,它也对应一个地址值,所以语句址值,所以语句 name1 = name1 = “J0X-?J0X-?”; ; 的意思的意思是:将存放是:将存放“J0X-?J0X-?”的内存单元首地址赋给变的内存单元首地址赋给变量量 name1name1。因为。因为 name1 name1 是指针类型,不是数组类是指针类型,不是数组类型,所以这样做是正确的。型,所以这样做是正确的。而而 name2 = name2 = “YYYYYY”; ; 语句等号左边是数组类型语句等号左边是数组类型的变量,等号右边是常量字符串指针(地址值),的变量,等号右边是常量字符串指针(地址值),类型不符合,不能赋值!类型不符合,不能赋值!69参考输出70请请在此在此页总结页总结要点要点71数组与指针void test_1(int a, int len)void test_1(int a, int len) / / 同前省略同前省略 void test_5(int a, int len)void test_5(int a, int len) / / 数组参数数组参数a a中的元素内容被更新了!中的元素内容被更新了! cout test_5(): a = a , len = len endl;cout test_5(): a = a , len = len endl;for (int i=0; ilen; i+)for (int i=0; ilen; i+) cout tta i = ai ;cout tta i = ai ;ai = ai + i * 2;ai = ai + i * 2; / / 在这里把数组元素更新了在这里把数组元素更新了cout ai endl;cout ai endl; cout endl;cout endl; void test_6(int a, int len, void test_6(int a, int len, int bint b) ) cout test_6(): a = a , len = len cout test_6(): a = a , len = len b = b endl tt; b = b endl tt;for (int i=0; ilen; i+)for (int i=0; ilen; i+)bi = ai + i * 2;bi = ai + i * 2; / / 运算结果赋值给了参数数组运算结果赋值给了参数数组 b bcout endl;cout endl; 72数组与指针int main()int a14 = 1,2,3;int a25 = 1,2,1,2,9;test_5(a1, 4);test_1(a1, 4); test_6(a1, 4, a2); / 数组a2的内容发生了改变test_1(a2, 4);test_1(a2, 5);return 0; / pointer-array-5.cpp73参考输出74请请在此在此页总结页总结要点要点75void test_7(int a34)void test_7(int a34) / / 两个维度都是固定的两个维度都是固定的 二维数组二维数组 int len1 = 3, len2 = 4;int len1 = 3, len2 = 4;for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+) cout aij ;cout aij ; cout endl;cout endl; void test_8(int a4, int len)void test_8(int a4, int len) / / 第二维固定的第二维固定的 二维数组二维数组 int len1 = len, len2 = 4;int len1 = len, len2 = 4;for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+) cout aij ;cout aij ; cout endl;cout endl; 数组与指针76void test_9(int* a4, int len)void test_9(int* a4, int len) int len1 = len, len2 = 4;int len1 = len, len2 = 4;for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+) cout aij ;cout aij ;cout endl;cout endl; #ifdef SHOW_ERROR#ifdef SHOW_ERRORvoid test_10(void test_10(int a, int a, int len1, int len2)int len1, int len2) for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+) cout aij ;cout aij ;cout endl;cout endl; #endif#endifvoid test_11(int* a, int len1, int len2)void test_11(int* a, int len1, int len2) for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+) cout aij ;cout aij ;cout endl;cout endl; 数组与指针参数参数a a实际上是一维的指针数组!实际上是一维的指针数组!77int main()int main() int b34 = 1,1,1,81, 2,2,2,72, 3,3,3,63;int b34 = 1,1,1,81, 2,2,2,72, 3,3,3,63;int c43 = 1,2,3, 4,5,6, 7,8,9, 9,8,7;int c43 = 1,2,3, 4,5,6, 7,8,9, 9,8,7;cout call test_7() to output matrix b: endl;cout call test_7() to output matrix b: endl;test_7(b);test_7(b); / test_7(int a34) / test_7(int a34)cout call test_8() to output matrix b: endl;cout call test_8() to output matrix b: endl;test_8(b, 3);test_8(b, 3); / test_8(int a4, int len) / test_8(int a4, int len)#ifdef SHOW_ERROR#ifdef SHOW_ERRORtest_7(c);test_7(c);test_8(c, 4);test_8(c, 4);test_9(b, 3);test_9(b, 3);test_10(b, 3, 4);test_10(b, 3, 4); / test_10(int a, int, int) / test_10(int a, int, int)test_11(b, 3, 4);test_11(b, 3, 4); / test_11(int*, int, int) / test_11(int*, int, int)test_11(int*)(b), 3, 4);test_11(int*)(b), 3, 4); / / 强制转换也不行!强制转换也不行!test_11(int*)(c), 4, 3);test_11(int*)(c), 4, 3);#endif#endif return 0;return 0; / pointer-array-6.cpp / pointer-array-6.cpp数组与指针78参考输出79参考输出80请请在此在此页总结页总结要点要点81void test_9(int* a4, int len)int len1 = len, len2 = 4;for (int i=0; ilen1; i+)for (int j=0; jlen2; j+)cout aij ;cout endl;void test_11(int* a, int len1, int len2)for (int i=0; ilen1; i+)for (int j=0; jlen2; j+)cout aij ;cout endl;这两个函数到底应该如何被使用呢?83void test_9(int* a4, int len) int len1 = 4, len2 = len;for (int i=0; ilen1; i+) for (int j=0; jlen2; j+) cout aij ;cout endl;int main() int* d4;for (int i=0; i4; i+) di = new int3;for (int i=0; i4; i+)for (int j=0; j3; j+)dij = 10 * i + j;test_9(d, 3);for (int i=0; i4; i+) delete di; return 0; / pointer-array-7.cpp先来看test_9(.)84参考输出85一一维维数数组组的的动态动态内存分配内存分配n先来看看数组中元素在内存中的位置0 1 2 3 28 290 1 2 3 28 29int a30;aa = &(a0)a+8 = &(a8)a+9 = &(a8) + 4a+10 = &(a9) + 4 = &(a9) + sizeof(int).sizeof(a) = sizeof(int) * 30&(a30) = a + sizeof(int) * 3086#include using namespace std;int main()int a30;for (int i=0; i=30; i+)cout i : &(ai) - a+i endl;return 0; / pointer-array-9.cpp0: 0x22fec0 - 0x22fec01: 0x22fec4 - 0x22fec42: 0x22fec8 - 0x22fec83: 0x22fecc - 0x22fecc4: 0x22fed0 - 0x22fed05: 0x22fed4 - 0x22fed46: 0x22fed8 - 0x22fed87: 0x22fedc - 0x22fedc8: 0x22fee0 - 0x22fee09: 0x22fee4 - 0x22fee410: 0x22fee8 - 0x22fee811: 0x22feec - 0x22feec.26: 0x22ff28 - 0x22ff2827: 0x22ff2c - 0x22ff2c28: 0x22ff30 - 0x22ff3029: 0x22ff34 - 0x22ff3430: 0x22ff38 - 0x22ff38测试代码参考输出结果表明:一维数组中的元素是依次存放的;下标相邻的单元,内存地址也相邻;第一个元素地址值最小。87n注意到,数组a占用的内存空间(即元素数量),是在源程序中直接给定的(如),在程序运行期间不能改变:既不能增长、也不能缩减。通常称此类数组为“静态数组”。0 1 2 3 28 290 1 2 3 28 29int a30; /所以,a实际上是一个常量指针,不能给a赋值。a一一维维数数组组的的动态动态内存分配内存分配a不是占内存空间的变量,所以图示中用虚框表示。88n若想要在程序执行时再确定“数组”的大小,必须使用“动态数组”。这需要通过 new 运算符来实现:n使用该运算符的语法规则如下,其中NUM既可以是变量,也可以是常量!0 1 2 3 28 290 1 2 3 28 29int* a = new int30;0xffec0aTYPE* var = new TYPENUM;一一维维数数组组的的动态动态内存分配内存分配a是占内存空间的指针变量,所以图示中用实线框表示。89dd0d1d2d3数组d的元素类型为 int*,它含有个元素。也可称为:指针数组因为各元素为指针类型。?静态分配的空间动态分配的空间d不是占内存空间的变量,所以图示中用虚框表示。90n凡是由 new 运算符“生成”的内存空间,在不再需要(使用)它时,应该(或者说,必须)使用 delete 运算符将内存“释放”掉。n对于动态生成的一维数组,参照下面的格式(delete,这里的表示要释放数组空间)释放分配的内存单元:delete a; / 若已有 int* a = new int30;一一维维数数组组的的动态动态内存分配内存分配91#include #include using namespace std;using namespace std;void void test_11test_11(int* a, int len1, int len2)(int* a, int len1, int len2) for (int i=0; ilen1; i+)for (int i=0; ilen1; i+) for (int j=0; jlen2; j+)for (int j=0; jlen2; j+)cout aij ;cout aij ;cout endl;cout endl; 再来看test_11(.)92int main()int main() int* e;int* e;e = e = new int*4;new int*4; for (int i=0; i4; i+) for (int i=0; i4; i+) ei = new int3;ei = new int3;for (int i=0; i4; i+)for (int i=0; i4; i+)for (int j=0; j3; j+)for (int j=0; j3; j+)eij = 10 * i + j;eij = 10 * i + j;test_11(e, 4, 3);test_11(e, 4, 3);for (int i=0; i4; i+) delete ei;for (int i=0; i4; i+) delete ei;delete e;delete e;return 0;return 0; / pointer-array-8.cpp / pointer-array-8.cpp93参考输出94二二维维数数组组的的动态动态内存分配内存分配n二维(甚至更多维)数组(设为m*n)的动态分配过程,是分两步来完成的:n 根据需要,分配第一维的空间。实际上是m个指针组成的动态数组。n 分别为m个指针分配一维动态数组空间,每个都包含n个元素。这一步与前面所讲的“一维数组的动态内存分配”是一样的。n 示例:950xffeedde0e1e2e3指针e指向连续4个内存单元的首地址,这些内存单元中存放都是内存地址,类型为 int*。所以,也可称e为:指向指针的指针。通常,可以将之直观理解为特殊的“二维数组”变量。?动态分配的第一维空间动态分配的第二维空间e是占内存空间的指针变量,所以图示中用实线框表示。e96二二维维数数组组的的动态动态内存内存释释放放n二维(甚至更多维)数组内存的动态释放过程,实际上是分配过程的严格逆过程:n 先通过逐一枚举第一维各元素,将该维中的各元素(即第二维的一维动态数组)指向的内存单元释放掉。n 释放第一维占用的内存空间。n示例:970xffeedde0e1e2e3?动态分配的第一维空间动态分配的第二维空间e是占内存空间的指针变量,所以图示中用实线框表示。e?上图中有错误吗?98#include using namespace std;int main()int *a = new int4;for (int i=0; i4; i+)ai = i * 10 + i % 7;for (int i=0; i4; i+)cout ai ;cout endl; cout before delete, a = a endl;delete a; / 分配给a的内存全部释放了cout after delete, a = a endl;for (int i=0; i4; i+)cout ai ;cout endl;return 0; / pointer-array-B.cpp以一维动态数组为例,说明指针被delete前后的变化和注意事项99悬挂指针(野指针)问题虽然a指向的空间被释放了,但变量a的内容并没有改变!若通过变量a再次访问那些内存空间,结果将不可预知。 切记!解释原因,需用到大三的操作系统课程的知识100#include using namespace std;int main()double array43; / 4 * 3 matrixint num = 1;for (int i=0; i4; i+)/ rowfor (int j=0; j3; j+) / colarrayij = num+;for (int i=0; i4; i+)/ rowfor (int j=0; j3; j+) / colcout &(arrayij) : arrayij endl;cout = endl;猜猜下面程序段的猜猜下面程序段的输输出出PART-1PART-1102你你 猜猜 对对 了了 吗吗 ?103猜猜下面程序段的猜猜下面程序段的输输出出double *ptr = (double*) array; / 一层循环,将二维数组当作一维动态数组来访问 for (int i=0; i12; i+)cout ptr+i : *(ptr+i) ptri endl;cout = endl;PART-2PART-2104你你 猜猜 对对 了了 吗吗 ?105猜猜下面程序段的猜猜下面程序段的输输出出/ 两层循环,将一维动态数组变量当作二维数组来访问for (int i=0; i4; i+)for (int j=0; j3; j+)cout *(ptr + i*3 + j) ;cout endl;return 0; / pointer-array-C.cppPART-3PART-3106你你 猜猜 对对 了了 吗吗 ?读完上面的代码,你有什么要总结的吗?107请请在此在此页总结页总结要点要点108结束
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号