C指针
In C, all function arguments are passed "by value".所有传递给函数的参数都是按值传递。
swap(&a, &b);void swap(int *px, int *py){int tmp = *px;*px = *py;*py = tmp;}
int a, *pa;
pa = a;等价于 pa = &a;
数组名就是数组第一个元素的地址。
在计算数组元素 a 的值时,C语言实际上将其转换为 *(a+i) 的形式。
因此,&a 与 a+i 等价,pa 与 *(pa+i) 等价。
当把数组名传递给一个函数时,实际上传递的是该数组第一个元素的地址。
void func(int *a) {...}
void func(int a[]) {...}
参数写成指针形式还是数组形式对编译器来说没区别,都表示这个参数是指针,之所以规定两种形式是为了给读代码的人提供有用的信息,如果这个参数指向一个元素,通常写成指针的形式,如果这个参数指向一串元素中的首元素,则经常写成数组的形式。
只有两指针指向同一个数组的元素时,才允许指针相减,p2 - p1 == j - i。
所有指针算术运算都会自动考虑它指向的对象的长度。
char amessage[] = "123456789";
char *pmessage = "123456789";
amessage 是一个仅仅足以存放初始化字符串以及'\0'的一维数组。
pmessage 指向一个字符串常量,不能修改字符串内容,不如改为 const char *pmessage = "123456789";
*p++ = val;
val = *--p;
是进栈和出栈的标准用法
const char *name[] = {"Illegal month", "Jan", "Feb", "Mar"};
char name[] = {"Illegal month", "Jan", "Feb", "Mar"};
指针数组在处理不同长度字符串时,省了不必要的空间。
用结构体指针做函数参数
结构体作为函数参数时也是值传递,会复制整个结构,效率不高。
在使用指针前,要判断是否为空指针。
传递给free()的指针必须是malloc等返回的指针。
// 释放链表for (p = head; p != NULL; p = p->next)/* Wrong! */free(p);for (p = head; p != NULL; p = q) {q = p->next;free(p);}
下标绝对不会比指针更有效率,但指针有时会比下标更有效率。
函数名:函数代码在内存中代码段的地址。
typedef int (*fun_t)(int, int); /* fun_t为函数指针的类型 */
int *func(void); /* 返回一个指向int类型的指针 */
double (*oper_func[]) = {add, sub, ...}; /* 函数指针数组 */
void指针可以指向任何类型的变量。
int n, *p;
void *vp;
vp = (void *)&n;
p = (int *)vp;
int matrix;
matrix 指向包含10个整型元素的数组指针
matrix+1 同上,指向第二行
*(matrix+1) 指向整型的指针
*(matrix+1)+5 同上,向后移5个元素
*(*(matrix+1)+5) 元素值
int (*p) = &matrix;
int (*p) = matrix; 指向数组的指针
int *p; 指针数组,元素为指针
int calendar;int (*monthp);for (monthp = calendar; monthp < &calendar; monthp++) {int *dayp;for (dayp = *monthp; dayp < &(*monthp); dayp++)*dayp = 0;}
主要摘自《The C Programming Language》 Chapter 5 - Pointers and Arrays
《Pointers on C》
《C Traps and Pitfalls》
页:
[1]