【C语言】学习笔记4——指针(1)
1. 指针:一种以符号形式使用地址的方法。
因为计算机的硬件指令非常依赖地址, 所以使用指针的程序更有效率。尤其是, 指针能有效地处理数组,数组地表示法其实是在变相地使用指针。
例子:数组名是数组首元素的地址。 也就是说,如果 flizny 是一个数组,下面的语句成立
flizny == &flizny[0]
flizny 和 &flizny 都表示数组首元素的地址(&是地址运算符)。两者都是常量,在程序运行中,不会改变,但是,可以把他们赋值给指针变量, 然后可以修改指针变量。
//指针地址 #include <stdio.h> #define SIZE 4 int main() { short dates[SIZE]; //声明一个short类型的指针变量 short * pti; short index; double bills[SIZE]; double * ptf; pti = dates; ptf = bills; printf("%23s %15s\n", "short", "double"); for(index = 0; index < SIZE; index++) printf("pointers + %d: %10p %10p\n", index, pti + index, ptf + index); return 0; } /* Output: short double pointers + 0: 000000000062FE30 000000000062FE10 pointers + 1: 000000000062FE32 000000000062FE18 pointers + 2: 000000000062FE34 000000000062FE20 pointers + 3: 000000000062FE36 000000000062FE28 */
不知道为什么, 我以前上学的时候看指针跟看天书一样,现在再看指针突然很简单了。可能现在代码写多了,很容易分清楚变量,值, 变量名, 地址的关系。
所以现在看来学校开C语言来作为计算机语言的入门科目确实是有待商榷的,诚然C语言是最早的高级语言,学会了C语言会很容易学习其他计算机语言。但是先学习像java / python这样简单粗暴的计算机语言,可以让学生很轻松地理解写程序到底是怎么一回事。然后再回头深究它底层的原理会轻松地多。
我觉得可以把指针理解为一个变量。这个变量的大小取决于计算机的地址大小(我的电脑是64位的,所以一个指针大小就是8 bytes)。比如上面程序中的例子
//声明一个short类型的指针, 指针增量为sizeof(short)=2, 也就是说pti + 1相当于 pti 所表示的地址 + 2 short * pti; //声明一个double类型的指针, 指针的增量为sizeof(double)=4, 也就是说ptl + 1 表示 pti 所指向的地址 + 4 double * ptf;
看上面的程序结果也很容易看出来, 再看书上的图也是符合的
2. 函数、数组和指针
因为数组名是该数组首元素地地址,作为实际参数地数组名要求形式参数是一个与之匹配的指针。只有在这种情况下,C才会把 int ar[] 和 int * ar 解释成一样的。 也就是说, ar是指向int的指针。
由于函数原型可以省略参数名, 所以下面4中原型都是等价的。
int sum(int * ar, int n); int sum(int *, int); int sum(int ar[], int n) int sum(int [], int);
但是, 在函数定义中不能省略参数名, 下面两种形式的函数定义等价:
int sum(int *ar, int n) { //函数内容省略 } int sum(int ar[], int n) { //函数内容省略 }
看下面示例程序, marbles 的大小为40 bytes, 说明marbles表示的是数组, 而 ar的大小是8 bytes, 说明函数接收的是一个地址();
//数组元素之和 #include <stdio.h> #define SIZE 10 //声明函数原型 int sum(int ar[], int n); int main() { int marbles[SIZE] = {15, 23, 24, 69, 14, 12, 15, 18, 16, 35}; long answer; answer = sum(marbles, SIZE); printf("marbles 所有元素之和为 %1d.\n", answer); printf("marbles 的大小为%u bytes.\n", sizeof marbles); return 0; } int sum(int ar[], int n) { int i; int total = 0; for(i = 0; i < n; i++) { total += ar[i]; } printf("ar 的大小为 %u bytes.\n", sizeof ar); return total; } /* Output: ar 的大小为 8 bytes. marbles 所有元素之和为 241. marbles 的大小为40 bytes. */