程序设计导论 —— 第 26 讲

22
补补补补补补补补补补补补 (2) 程程程程程程 ——程 26 程

description

程序设计导论 —— 第 26 讲. 补充内容以及重点内容复习 (2). freopen 函数. FILE *freopen( const char *path, const char *mode, FILE *stream ); 使用头文件 stdio.h path: 文件名 mode: 文件打开的模式(如 r, w ) stream: 一个文件,通常使用标准流文件( stdin, stdout 等) 实现输入输出重定向,把预定义的几个标准流文件 (stdin, stdout) 定向到由 path 指定的文件中. freopen 函数举例. - PowerPoint PPT Presentation

Transcript of 程序设计导论 —— 第 26 讲

Page 1: 程序设计导论 —— 第 26 讲

补充内容以及重点内容复习(2)

程序设计导论——第 26 讲

Page 2: 程序设计导论 —— 第 26 讲

freopen 函数 FILE *freopen( const char *path,

const char *mode, FILE *stream ); 使用头文件 stdio.h path: 文件名 mode: 文件打开的模式(如 r, w ) stream: 一个文件,通常使用标准流文件

( stdin, stdout 等) 实现输入输出重定向,把预定义的几个标准流

文件 (stdin, stdout) 定向到由 path 指定的文件中

Page 3: 程序设计导论 —— 第 26 讲

freopen 函数举例 freopen(“data.in”, “r”, stdin);

把标准输入定向到文件 data.in 中

freopen(“data.out”, “w”, stdout); 把标准输出定向到文件 data.out 中

调试程序时不用每次都输入数据,将输入数据保存在 data.in 中即可 提交系统上的题目以后将逐步公开测试数据 可以用这种方式方便的调试程序

Page 4: 程序设计导论 —— 第 26 讲

#include <stdio.h>#include <string.h>int main(){

freopen(“data.in”, “r”, stdin); // 运行之后 scanf 从data.in 中读入

freopen(“data.out”, “w”, stdout); // 运行之后 printf 输出到data.out 中

char str[600];char s[]="RUC";int i, j=0;scanf("%s", str);printf("%d", strlen(str));for (i=0; i<strlen(str); i++){

if (s[j]==str[i])j++;

if (j==3) break;}if (j==3)

printf("YES");else

printf("NO");return 0;

}

例:寻找 RUC 一题源代码

Page 5: 程序设计导论 —— 第 26 讲

复习内容 指针

指针的定义 指针的使用

指向结构的指针 指向数组元素的指针 指向数组的指针

函数相关 函数的参数传递 数组作为函数的参数 函数指针的定义、使用 函数指针作为参数传递

Page 6: 程序设计导论 —— 第 26 讲

指针的定义 定义一个指针变量

类型 * 指针变量名 = 指针初值; 类型是指针指向的变量的类型

int *pNum; float *p; char *str; int *pNumArray[10]; // 指针数组

Page 7: 程序设计导论 —— 第 26 讲

指针相关的操作符 & :求地址运算符 * :间接引用操作符

int a=10, *p;p = &a;即:( 1 ) *p 与 a 等价,都代表变量 a 的存储单

元( 2 ) p 与 &a 都是变量 a 的地址

*p

a 10&

a

&p p

&a

Page 8: 程序设计导论 —— 第 26 讲

指针的使用 指向结构的指针#include <iostream>// 预编译命令using namespace std;struct MyPoint { // 定义结构类型 MyPoint;

float x, y;};int main(){

MyPoint point={2.0, 3.0}; MyPoint *pPoint; pPoint = &point; // 指针 pPoint 指向结构变量pointcout << "The point is ("; // 输出提示信息cout << pPoint->x << "," << (*pPoint).y << ")" << endl; return 0;

}

Page 9: 程序设计导论 —— 第 26 讲

当指针指向数组的首元素时,指针可等同数组变量使用。

数组变量本身的值是地址 数组是一组同类型的变量在内存中顺序存放

int scores[ MAX ]; 数组变量代表数组整体占用的内存空间

sizeof(scores) 相等于 sizeof(int)*MAX 数组变量代表数组的起始内存地址

scores 等价于 &scores[0] int *pscores; pscores = scores 等价于 pscores =

&scores[0] *scores 等价于 scores[0]

不能给数组变量赋值 scores = ……

指向数组元素的指针

Page 10: 程序设计导论 —— 第 26 讲

#include <iostream>// 预编译命令using namespace std;#define MAXNUM 10

int main(){

int scores[MAXNUM]={90,91,92,93,94,95,96,97,98,99};int *p1 = scores;int *p2, *p3; p2 = scores; p3 = scores;for (int i=0; i<MAXNUM; i++) // 利用指针输出数组元素{

cout << p1[i] << " " << *p2 << " " << *(p3+i) << endl;

p2++; // 指针的加法运算}cout << endl;return 0;

}

Page 11: 程序设计导论 —— 第 26 讲

指针的加减法运算 指针的加减法运算不是简单的地址值的加减法

(pscore+1) 的值是&pscore[1] *(pscore+1) 等价于 pscore[1] *(scores+i) 等价于 scores[i] // 假定 i整数变量指针的加减法是考虑了类型大小的地址加减法

指针变量可以用指针运算的结果赋值pscore = scores;pscore = pscore+1;pscore++; 上述三条语句执行后 *pscore 与 scores[2] 等价

Page 12: 程序设计导论 —— 第 26 讲

指针的加减法运算 两个指针变量相加是无意义的

float* pscore1 = scores;float* pscore2 = scores+1;pscore1 + pscore2; // 无意义

两个同类型指针变量相减是其间的元素数目(pscore2 - pscore1)==1; // 值为真

两个同类型指针变量可比较大小(pscore2 > pscore1); // 值为真(pscore2 < pscore1); // 值为假pscore1 == scores; // 两个指针变量所指的地址相同

Page 13: 程序设计导论 —— 第 26 讲

指向数组的指针#include <iostream>// 预编译命令using namespace std;int main(){

int roomscores[3][3]={{90,91,92}, {80,81,82},{70,71,72}}; int (*p1)[3]; // 定义一个指向数组的指针p1 = roomscores; // 等价于 p2 = &roomscores[0];for (int i=0; i<3; i++){

for (int j=0; j<3; j++)cout << (*p1)[j] << " ";

cout << endl;p1++;

}return 0;

}

90 91 92

80 81 82

70 71 72

Page 14: 程序设计导论 —— 第 26 讲

数组作为函数的参数 以地址方式传递参数void myFunction( char str[], int array[], int

length){

printf("string in myFunction: %s \n", str);

if (strlen(str)>10) strcpy(str, "new string");

elsestrcpy(str, " ");

for(int i=0; i<length; i++) array[i]=0;return;

}

Page 15: 程序设计导论 —— 第 26 讲

函数指针的定义 返回值类型 ( * 函数指针名)(参数表); 例 1 : int square(int); int (*f)(int)=square; 例 2 :

void f1(int);void f2(int);void f3(int);

void (*f[3])(int)={f1,f2,f3};

Page 16: 程序设计导论 —— 第 26 讲

函数指针的使用#include <iostream>int square(int x){cout << x; return 0;};int (*f)(int)=square;void f1(int x){cout <<1 <<endl;};void f2(int x){cout <<2 <<endl;};void f3(int x){cout <<3 <<endl;};void (*fp[3])(int)={f1,f2,f3};void main(){ (*f)(0); (*fp[0])(1); (*fp[1])(2); (*fp[2])(3);}

Page 17: 程序设计导论 —— 第 26 讲

函数指针作为参数传递int sum(int a,int b,int (*term)(int)){ if(a>b) return 0; return (*term)(a) + sum(a+1,b,term);}int term(int a){ return a ;}void main(){ cout << sum(69, 90, term) << endl;

int s=0;for(int i=69;i<=90;i++) s += i ;cout << s << endl;

}

Page 18: 程序设计导论 —— 第 26 讲

qsort 函数 void qsort(void* base, size_t n,

size_t size, int (*cmp)(const void*, const void*)) base 为要排序的数组 n 为要排序数组的长度 size 为数组元素的大小(以字节为单位) cmp 为判断大小函数的指针

这个函数需要自己定义, 如果 a>b ,函数返回1 ; a<b ,函数返回 -1 ; a=b ,函数返回 0

Page 19: 程序设计导论 —— 第 26 讲

#include <iostream>// 预编译命令#include <time.h>#include <stdlib.h>using namespace std;int compare(const void *a, const void *b);

int main(){int ary[20], i;srand((unsigned)time(NULL)); // 随机产生 20 个数for (i=0; i<20; i++)

ary[i]=rand();for (i=0; i<20; i++) // 输出 20 个数printf("%6d ", ary[i]);printf("\n\n");

qsort((void*)ary, 20, sizeof(int), compare );// 排序

for (i=0; i<10; i++) // 输出排序后的 20 个数printf("%6d ", ary[i]);

printf("\n");return 0;

}

Page 20: 程序设计导论 —— 第 26 讲

int compare(const void *a, const void *b){

if ( *(int*)a > *(int*)b )return 1;

else if ( *(int*)a == *(int*)b )

return 0;else

return -1;}

整数比较

Page 21: 程序设计导论 —— 第 26 讲

int compare(const void *a, const void *b){

char *p, *q;p = (char *)a;q = (char *)b;

return strcmp(p, q);}

字符串比较:

Page 22: 程序设计导论 —— 第 26 讲

结 束