Presentation is loading. Please wait.

Presentation is loading. Please wait.

多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 多维数组元素的地址 先回顾多维数组的性质,可以认为二维数组是“数组的数组”,例 : 定义int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};

Similar presentations


Presentation on theme: "多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 多维数组元素的地址 先回顾多维数组的性质,可以认为二维数组是“数组的数组”,例 : 定义int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};"— Presentation transcript:

1 多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 多维数组元素的地址 先回顾多维数组的性质,可以认为二维数组是“数组的数组”,例 : 定义int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}}; 则二维数组a是由3个一维数组所组成的。设二维数组的首行的首地址为 ,则

2 表 示 形 式 含义 地 址 a 二维数组名,指向一维数组a[0],即0行首地址 2000 a[0], *(a+0), *a 0行0列元素地址 a+1,&a[1] 1行首地址 2016 a[1],*(a+1) 1行0列元素a[1][0]的地址 a[1]+2, *(a+1) +2, &a[1][2] 1行2列元素a[1][2] 的地址 2024 *(a[1]+2), *(*(a+1)+2), a[1][2] 1行2列元素a[1][2]的值 元素值为13

3 输出二维数组有关的值 #include<stdio.h> #define format ″%d,%d\n″
void main() { int a[3][4]={1,3,5,7,9,11,13, 15,17,19,21,23}; printf(format,a,*a); printf(format,a[0] , *(a+0));  printf(format,&a[0],&a[0][0]);  printf(format,a[1],a+1);  printf(format,&a[1][0],*(a+1)+0);  printf(format,a[2],*(a+2));  printf(format,&a[2],a+2);  printf(format,a[1][2],*(*(a+1)+2)); }

4 某一次运行结果如下: , (0行首地址和0行0列元素地址) , (0行0列元素地址) , (0行0首地址和0行0列元素地址) , (1行0列元素地址和1行首地址) , (1行0列元素地址) , (2行0列元素地址) , (2行首地址) 13, (1行2列元素的值)

5 上机过程中的问题 养成良好的程序书写风格 变量、函数的命名:体现其意义
if/else、swith/case、for、while等复合语句中 { }的使用 { }内代码的缩进 适当的空行 适当的注释 避免太长的语句、适当的换行

6 上机过程中的问题 应该: 误解: 程序运行不正确,怎么办? 在VC环境中写完程序后,就拷贝到编程网格上提交 仔细分析问题 考虑各种情况
把自己当作计算机,给定输入,再运行一下程序 误解: 在VC环境中写完程序后,就拷贝到编程网格上提交 在VC环境中编译正确,程序就是正确的 对于给出的样例输入,输出正确,程序就是正确的 程序运行不正确,怎么办?

7 程序的调试 语法错误:编译(组建)错误 不要惊慌,编译结果输出窗口已经为你指明了程序的出错行及错误原因,可以据此来修改程序错误。
改错时,应从出错信息中的第一条开始,用鼠标双击该条信息,程序源文件窗口就将定位到出错行。 很多时候,程序编译后会出很多错误,但很可能是由第一个错误衍生而来的,改完第一个错误后,再编译时其他错误就不再出现了。所以,应该每修改完一个错误后就编译一次。

8 二、关于程序的错误修改及调试 这里少了一个“{”。 这里的一堆错误,都是由于上面少了一个“{”引起的! 双击第一行,定位错误及了解错误原因!

9 程序的调试 运行结果错:程序跟踪调试 由于程序算法及其他原因,执行结果不正确,这时从源程序表面上就很难发现错误。
跟踪调试:可以手动一步一步执行程序语句,在每条语句执行后,可以查看相关变量的值,以判断和预期结果是否相符;也可以了解程序的执行顺序,看它是否和预期的程序流程相符。 断点设定:在跟踪调试前,还需要确定一下程序可能从哪里出错,设置一个断点,让程序在此停止自动运行,由我们手动一步一步发出程序执行命令。如果不能确定程序是从哪里出错,则可以将断点设置在程序的第一条语句处。

10 设置程序断点

11 跟踪方式执行程序 查看变量值 当前程序执行停留在此行 手动设置变量,查看变量值
程序手动执行 进入函数 一步一步执行 从函数中执行出来 执行到光标所在行 查看变量值 当前程序执行停留在此行 手动设置变量,查看变量值

12 问题1: 骑车与走路

13 n 没有上限了! 骑车: 找到并启动自行车 27秒; 停车锁车 23秒; 速度 3.0米/秒; 走路: 速度 1.2米/秒;

14 假设 n 的上限是 10

15 提交到 编程网格。结果是 … … void compute(int distance){
#include <stdio.h> #define N 10 void compute(int distance); int main(){ int n; int distance[N]; int i; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &(distance[i])); } compute(distance[i]); return 0; void compute(int distance){ int timeBike = distance/3; int timeWalk = (int)(distance/1.2); if(timeBike < timeWalk){ printf("Bike\n"); } else if (timeBike > timeWalk){ printf("Walk\n"); } else { printf("All\n"); } 提交到 编程网格。结果是 … …

16 把 n 的上限修改为 100

17 提交到 编程网格。结果是 … … void compute(int distance){
#include <stdio.h> #define N 100 void compute(int distance); int main(){ int n; int distance[N]; int i; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &(distance[i])); } compute(distance[i]); return 0; void compute(int distance){ int timeBike = distance/3; int timeWalk = (int)(distance/1.2); if(timeBike < timeWalk){ printf("Bike\n"); } else if (timeBike > timeWalk){ printf("Walk\n"); } else { printf("All\n"); } 提交到 编程网格。结果是 … …

18 WHY?

19 编程网格 判断程序是否正确 的机制 对每一个题目, 编程网格 预先设定了 一组测试数据; 只要你的程序在这组测试数据下正确,
编程网格 判断程序是否正确 的机制 对每一个题目, 编程网格 预先设定了 一组测试数据; 只要你的程序在这组测试数据下正确, 编程网格 即认为 你的程序是正确的; 在 骑车与走路 这个题目中, 编程网格使用的测试数据中,所有的n 都小于 100

20 有没有更稳妥的办法呢?

21 动 态 数 组

22 int sz[10]; 静态数组 必须是一个常量 静态数组 的 长度 在 编译时刻 就确定了; 如何能在程序的运行时刻,
动态地确定一个数组的长度呢?

23 动态数组 动态数组? #include <stdio.h> int main(){ int n;
scanf(“%d”, &n); int shzu[n]; return 0; } 在VC下编译失败! error C2133: 'shuzu' : unknown size 怎样才能实现 动态数组?

24 动态数组 如何实现动态数组? 1、使用指针 2、自己申请内存

25 动态数组 #include <stdio.h> #include <malloc.h> int main(){
int n; scanf(“%d”, &n); int *shzu = (int *) malloc(sizeof(int) * n); … … free(shuzu); return 0; } #include <stdio.h> int main(){ int n; scanf(“%d”, &n); int shzu[n]; … … return 0; }

26 动态数组 #include <stdio.h> #include <malloc.h> int main(){
int n; scanf(“%d”, &n); double *shzu = (double *) malloc(sizeof(double) * n); … … free(shuzu); return 0; } #include <stdio.h> int main(){ int n; scanf(“%d”, &n); double shzu[n]; … … return 0; }

27 关于malloc()/free()的使用
别忘了: #include <malloc.h> malloc函数的参数为所需申请内存的大小:以字节为单位 malloc函数返回一个void*类型的地址,必须通过强制类型转换,才能赋值给特定的指针变量: int * pint = (int *) malloc( ... ); 用malloc函数生成各种类型的动态数组,最好使用“sizeof(类型名) * 动态数组长度”形式确定分配内存的大小: int * pint = (int *) malloc( sizeof(int) * 100 ); 分配的内存不再使用时一定要释放: free(pint);

28 动态数组 malloc()在内存中分配的一块连续的内存区域,这与静态数组在内存中的布局是一样的。因此,指向这块内存区域的指针变量就可以像数组一样使用了: int *pint; pint = (int *)malloc(sizeo(int)*10); pint[0], pint[1], ……, pint[9] 在使用动态数组时,一定要注意不要越界引用,即不要引用并没有分配给你使用的内存: 当引用pint[10] 时,对于C语言来说,这是合法的,但是它所引用的却是所分配的内存区域之外的其他内存区域,其内的值是未知的;如果对其进行修改的话,还可能影响整个程序的正确性。 pint 5 6 7 8 9 1 2 3 4 10(?) ? pint+10

29 #include <stdio.h>
#define N 10 void compute(int distance); int main(){ int n; int distance[N]; int i; scanf("%d", &n); for(i = 0; i < n; i++){ scanf("%d", &(distance[i])); } compute(distance[i]); return 0; #include <stdio.h> #include <malloc.h> void compute(int distance); int main(){ int n; int i; scanf("%d", &n); int *distance = (int *) malloc(sizeof(int)*n); for(i = 0; i < n; i++){ scanf("%d", &(distance[i])); } compute(distance[i]); free(distance); return 0;

30 问题2: 跳绳游戏

31 关键信息: 计算1分钟内跳了多少下绳; 1秒钟跳1次; 跳坏后,3秒钟后才能又开始跳;

32 输入、输出 示例 = 60 – 0 * 3 = 60 – 3 * 3 = 60 – 1 * 3 = 60 – 4 * 3 = 60 – 4 * 3 = 47

33 输入:0 输出:60 在y秒时,小朋友停止了跳绳 0秒 60秒 y秒 60下

34 输入:3 12 23 45 输出:51 y秒 51 = 60 – 3*3 在y秒时,小朋友停止了跳绳 0秒 12秒 15秒 26秒 29秒
51秒 54秒 60秒 12下 23下 23下 45下 45下 12下 51 = 60 – 3*3

35 输入:1 17 输出:57 在y秒时,小朋友停止了跳绳 0秒 60秒 y秒 17秒 20秒 17下 17下 57 = 60 – 1*3

36 输入:4 10 20 30 40 输出:48 y秒 48 = 60 – 4*3 在y秒时,小朋友停止了跳绳 0秒 60秒 10秒 13秒
23秒 26秒 36秒 39秒 49秒 52秒 10下 10下 20下 20下 30下 30下 40下 40下 48 = 60 – 4*3

37 输入: 输出:48 60秒 0秒 10秒 13秒 23秒 26秒 36秒 39秒 49秒 52秒 70秒 73秒 10下 10下 20下 20下 30下 30下 40下 40下 58下 58下 48 = 60 – 4*3

38 输入: 输出:47 0秒 60秒 10秒 13秒 23秒 26秒 36秒 39秒 49秒 52秒 59秒 62秒 75秒 78秒 10下 10下 20下 20下 30下 30下 40下 40下 47下 47下 60下 60下 47

39 问题分析 60秒 Case 1 0秒 60秒 Case 2

40 请同学们课后思考 如何编写这个程序

41 下课!


Download ppt "多维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 多维数组元素的地址 先回顾多维数组的性质,可以认为二维数组是“数组的数组”,例 : 定义int a[3][4]={{1,3,5,7},{9,11,13,15},{17,19,21,23}};"

Similar presentations


Ads by Google