第12章 指针与数组.ppt

第12章指针与数组重点讲义

处理多维数组的列 二维数组a中第i列元素清零: int a[NUM_ROWS][NUM_COLS], (*p)[NUM_COLS], i; … for (p = a; p a+NUM_ROWS; p++) (*p)[i] = 0; * p 用多维数组名作为指针 查找数组a[NUM_ROWS][NUM_COLS]最大元素: int find_largest(int a[], int n){ int i, max = a[0]; for (i = 1; i n; i++) if (a[i] max) max = a[i]; return max; } 调用: largest = find_largest(a, NUM_ROWS * NUM_COLS); /* WRONG */ a类型: int(*)[NUM_COLS] 而find_largest希望接受是int * * 用多维数组名作为指针 正确调用: largest = find_largest(a[0], NUM_ROWS * NUM_COLS); a[0]指向a[0][0](类型int *) 结论:以数组为形参的函数,本质上以类型相同的指针来处理 * 指针和变长数组 (C99) 指针可以指向变长数组 (VLAs)中的元素 常规的指针变量可用于指向一维变长数组中的元素 void f(int n) { int a[n], *p; p = a; … } * 指针和变长数组 (C99) 如果变长数组是多维的,则指针的类型取决于除第一维外每一维的长度。 下面是一个二维的例子: void f(int m, int n) { int a[m][n], (*p)[n]; p = a; … } 因为指针 p 的类型取决于 n,而n不是常量,因此称p具有可变类型。 * 指针和变长数组 (C99) 注意:编译器并非总能确定赋值语句p = a的合法性。 例如:下述语句可以通过编译,但只有当m 等于n时结果才是正确的: int a[m][n], (*p)[m]; p = a; 如果 m 不等于 n,则后续对指针p 的使用都将导致未定义的行为。 * 指针和变长数组 (C99) C99对可变类型赋予了一些限制条件。 最重要的限制是:可变类型的声明必须出现在函数体的内部,或者在函数原型中。 * 指针和变长数组 (C99) 对变长数组同样可以执行指针算术运算。 例如对于如下的二维变长数组: int a[m][n]; 可以声明一个指针p,指向 a中的某一行: int (*p)[n]; 下述循环语句可以将数组 a第i列元素清零: for (p = a; p a + m; p++) (*p)[i] = 0; * * * 和 ++ 运算符的组合 最常见组合*p++,在循环中十分方便 先取当前元素,再后移指针,与a[i++]同 例如:对数组a求和 for (p = a[0]; p a[N]; ) sum += *p++; 可以改写为: p = a[0]; while (p a[N]) sum += *p++; * * 和 ++ 运算符的组合 * 和 --组合类似于* 和 ++的组合 “栈”例: 整型变量top跟踪contents数组“栈顶” 指针变量top_ptr替换top,初始指向contents数组的第零个元素: int *top_ptr = contents[0]; = contents;? * * 和 ++ 运算符的组合 新的 push 和 pop 函数: void push(int i) { if (is_full()) stack_overflow(); else *top_ptr++ = i; } ? int pop(void) { if (is_empty()) stack_underflow(); else return *--top_ptr; } * contents top_prt 栈底 栈顶生长方向 用数组名作为指针 数组与指针关联关系: 数组名本质上是数组(首元素)地址 数组名可当做指针使用 指针算术运算 * 用数组名作为指针 声明数组: int a[10]; 以指针方式使用数组名: *a = 7; /* a等价于a[0]*/ *(a+1) = 12; /* a[1]=12 */ a + i 和 a[i]等同 *(a+i) 与 a[i]也等同 * 用数组名作为指针 数组名作指针,编写遍历数组循环更加容易: for (p = a[0]; p a[N]; p++)

文档评论(0)

1亿VIP精品文档

相关文档