📄 第21章 指针三 实例演练与提高.htm
字号:
lang=en-us>1</SPAN>)</FONT> = 80;</B>
<P>
<P>请大家自己对比,并理解。如果觉得困难,请复习第19章关于*的用法,和指针偏移部分的内容。
<P>
<H3><A name=21.4><B>21</B>.4</A> 小王成绩管理系统<SPAN lang=en-us>
V3.0</SPAN></H3>
<P>
<P><SPAN lang=en-us>3.0 </SPAN>版的最重要的改进就是:用户可以事先指定本校的学生总数。
<P>
<P>请仔细看好。
<P>
<P>//定义一个指针,用于存入未知个数学生的成绩:</P>
<P>int<SPAN lang=en-us>*</SPAN> <SPAN lang=en-us>pC</SPAN>j;</P>
<P> </P>
<P>//总成绩,平均成绩:</P>
<P>int zcj=0, pjcj;</P>
<P> </P>
<P><SPAN lang=en-us>//</SPAN>首先,要求用户输入本校学生总数<SPAN lang=en-us>:</SPAN></P>
<P><SPAN lang=en-us>int <B>xszs</B>; //</SPAN>学生总数</P>
<P><SPAN lang=en-us>cout << "</SPAN>请输入本校学生总数<SPAN
lang=en-us>:";</SPAN></P>
<P><SPAN lang=en-us>cin >> </SPAN><B>xszs</B><SPAN
lang=en-us>;</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>//</SPAN>万一有调皮用户输入不合法的总数,我们就不处理</P>
<P><SPAN lang=en-us>if (</SPAN><B>xszs</B><SPAN lang=en-us> <=
0)</SPAN></P>
<P><SPAN lang=en-us>{</SPAN></P>
<P><SPAN lang=en-us> cout <<
"</SPAN>喂,你想耍我啊?竟然输入一个是0或负数的学生总数<SPAN lang=en-us>.</SPAN>我不干了!<SPAN
lang=en-us>" << endl;</SPAN></P>
<P><SPAN lang=en-us> return -1; //</SPAN>退出</P>
<P><SPAN lang=en-us>}</SPAN></P>
<P> </P>
<P><SPAN lang=en-us>pCj = new int[</SPAN><B>xszs</B><SPAN
lang=en-us>];</SPAN></P>
<P> </P>
<P>//仍然可以用我们熟悉的循环来实现输入:</P>
<P>for(int i=0; i<SPAN lang=en-us> </SPAN><<SPAN lang=en-us>
</SPAN><B>xszs</B>; i++) </P>
<P>{</P>
<P> cout << "请输入第" << i+1 << "学员的成绩:";</P>
<P> cin >> <SPAN
lang=en-us>pC</SPAN>j[i]; //输入数组中第i个元素</P>
<P> </P>
<P> //不断累加总成绩:</P>
<P> zcj += <SPAN
lang=en-us>pC</SPAN>j[i];
</P>
<P>}</P>
<P> </P>
<P>//平均成绩:</P>
<P>pjcj = zcj / <B>xszs</B>;</P>
<P> </P>
<P>//输出:</P>
<P>cout << "总成绩:" << zcj << endl;</P>
<P>cout << "平均成绩:" << pjcj << endl;</P>
<P> </P>
<P>//下面实现查询:</P>
<P>int i; </P>
<P> </P>
<P>do</P>
<P>{</P>
<P> cout << "请输入您要查询的学生次序号(1<SPAN lang=en-us>
</SPAN>~<SPAN lang=en-us> </SPAN>" << <B>xszs</B> << "):"
;</P>
<P> cin >> i;</P>
<P> </P>
<P> if( i >= 1 && i <= <SPAN
lang=en-us><B>xszs</B></SPAN>)</P>
<P> {</P>
<P> cout << cj[i-1] << endl;
//问:为什么索引是 i-1,而不是 i ?</P>
<P> }</P>
<P> else if( i != 0)</P>
<P> {</P>
<P> cout << "您的输入有误!" <<
endl;</P>
<P> }</P>
<P>}</P>
<P>while(i != 0); //用户输入数字0,表示结束。</P>
<P> </P>
<P><FONT color=#ff0000><SPAN
lang=en-us>//</SPAN>最后,要释放刚才分配出的内存:</FONT></P>
<P><FONT color=#ff0000><SPAN lang=en-us>delete [] pCj;</SPAN></FONT></P>
<P>......</P>
<P>
<P>请大家现在就动手,实现小王成绩管理3.0版。这是本章的第一个重点。通过该程序,你应该可以记住什么叫“动态分配内存”。
<P>
<H3><A name=21.5>21.5</A> 字符<B>串</B>指针</H3>
<H4><A name=21.5.1>21<SPAN lang=en-us>.5.1</SPAN></A><SPAN lang=en-us>
</SPAN>为字符串分配指定大小的空间</H4>
<P>
<P>有必要的话,你应复习一下第16章之第6节:字符数组。
<P>
<P>假设有个老外叫<SPAN lang=en-us> "Mike"</SPAN>,以前我们用字符数组来保存,需要指定是5个字符大小的数组:
<P>
<P><SPAN lang=en-us>char name[5] = "Mike";</SPAN>
<P>
<P><SPAN lang=en-us>"Mike"</SPAN>长4个字符,为什么要5个字符的空间来保存?
这是因为计算机还需要为字符串最后多保存一个零字符:<SPAN lang=en-us>'\0'</SPAN>。用来表示字符串结束了。
<P>
<P>在学了指针以后,我们可以用字符串指针来表达一个人的姓名:
<P>
<P><SPAN lang=en-us>char* pname = "Mike";</SPAN>
<P>
<P>此时,由系统自动为<SPAN lang=en-us>pname </SPAN>分配5个字符的位置,并初始化为<SPAN lang=en-us>
"Mike"</SPAN>。 最后一个位置仍然是零字符:‘<SPAN lang=en-us>\</SPAN>0’。
<P>
<P>采用字符串的好处,同样前面所说的,可以在程序中临时决定它的大小(长度)。
<P>比如:
<P>
<P><SPAN lang=en-us>char* pname;</SPAN>
<P><SPAN lang=en-us>pname = new char[9]; //</SPAN>临时分配9个字符的大小。
<P>
<P>除了要记得额外为字符串的结束符<SPAN
lang=en-us>'\0'</SPAN>分配一个位置以外,字符串指针并没有和其它指定有太多的不同。
<P>
<P>既然讲到字符串,我们就顺带讲几个常用的字符串操作函数
<P>
<H4><SPAN lang=en-us><A name=21.5.2>21.5.2</A> </SPAN>字符串常用函数</H4>
<P>
<P>字符串操作函数的声明都包含在该头文件:<SPAN lang=en-us> <string.h></SPAN>
<P>
<P><B><A name=21.5.2.1>21.5.2.1</A> 字符串比较</B>
<P>
<P>int strcmp(const char *s1, const char *s2);
<P>
<P>比较<SPAN lang=en-us>s1</SPAN> 和<SPAN lang=en-us> s2
</SPAN>两个字符串,返回看哪个字符串比较大。对于字母,该比较区分大小写
<P>返回值:
<P> <SPAN lang=en-us>< 0 </SPAN>: <SPAN lang=en-us>s1
< s2;</SPAN>
<P><SPAN lang=en-us> 0 : s1 ==
s2;</SPAN>
<P><SPAN lang=en-us> > 0 : s1 > s2;</SPAN>
<P>
<P><SPAN lang=en-us>int strcmpi(const char *s1, const char *s2);</SPAN>
<P>该函数类似于上一函数,只是对于字母,它不区分大小写,比如它认为<SPAN lang=en-us>'A'</SPAN>和<SPAN
lang=en-us>'a'</SPAN> 是相等的。
<P>
<P>要说两个字符串相等不相等,还好理解,比如:<SPAN lang=en-us> "Borland"</SPAN> 和<SPAN
lang=en-us> "Borlanb" </SPAN>显然不相等。不过,字符串之间还有大小之分吗?
<P>对于字母,采用ASCII值来一个个比较。谁先出现一个ASCII值比较大的字母,谁就是大者。比如:<SPAN lang=en-us>"ABCD"
</SPAN>比<SPAN lang=en-us> "AACD"</SPAN>大。
<P>如果一直相等,但有长短不一,那就长的大。比如:“<SPAN lang=en-us>ABCD</SPAN>” 比 “<SPAN
lang=en-us>ABC</SPAN>”。
<P>记住了,由于在ASCII表里,小写字母比大写字母靠后,所以小写的反倒比大写的大。比如:<SPAN
lang=en-us>"aBCD"</SPAN>比<SPAN lang=en-us>"ABCD"</SPAN>大啊。
<P>
<P>我这里写个例子,看如何比较字符串:
<P>
<P><SPAN lang=en-us>#include <string.h> </SPAN>
<P><SPAN lang=en-us>#include <iostream.h></SPAN>
<P><SPAN lang=en-us>...</SPAN>
<P>
<P><SPAN lang=en-us>int reu = strcmp ("ABCD", "AACD");</SPAN>
<P>
<P><SPAN lang=en-us>if (reu > 0)</SPAN>
<P><SPAN lang=en-us> cout << "</SPAN>没错,<SPAN
lang=en-us> ABCD > AACD" << endl;</SPAN>
<P><SPAN lang=en-us>else </SPAN>
<P><SPAN lang=en-us> cout << "</SPAN>搞错了吧?<SPAN
lang=en-us>" << endl;</SPAN>
<P>
<P>请大家照此例,分别比较 <SPAN lang=en-us>"ABCD" </SPAN>和<SPAN lang=en-us> "ABC"
</SPAN>、<SPAN lang=en-us> "aBCD" </SPAN>和<SPAN lang=en-us> "ABCD"</SPAN>。
<P>如果你对如何用<SPAN lang=en-us>C++ Builder</SPAN> 建立一个控制台下的工程,请复习第二章第3节。
<P>
<P>前面说的是英文字母,对于汉字字符串的比较,大小是如何确定的呢?
<P>对于常用汉字,<SPAN
lang=en-us>Windows</SPAN>按其拼音进行排序,比如“啊”是最小的,排在最前面,而“坐”之类的,则比较大,排在后面。
<P>对于非常用的汉字,则按笔划来排序。有关常用不常的划分,是国家管的事,我们就不多说了。
<P>
<P>我一直在网上叫“南郁”,大家可以拿你的名字和我做一下<SPAN lang=en-us>
strcmp</SPAN>,看看谁的名字比较大。(友情提醒:名字大没有什么好处,相反,名字大了,在各种场合里,一般是排名靠后的……)
<P>
<P><B><A name=21.5.2.2>21.5.2.<SPAN lang=en-us>2</SPAN></A> 字符串复制</B>
<P>
<P>char *strcpy(char *dest, const char *src);
<P>
<P>该函数用于将字符串<SPAN lang=en-us> src</SPAN>的内容,复制给<SPAN lang=en-us>
</SPAN>字符串<SPAN lang=en-us>dest</SPAN>。 注意,一定要保证<SPAN lang=en-us>
dest</SPAN>有足够的空间。
<P>该函数最后返回<SPAN lang=en-us>dest.</SPAN>
<P>
<P>比如:
<P><SPAN lang=en-us>char name1[10];</SPAN>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -