今天主要学习是关于指针的。
指针与地址
可以是用一元运算符&用于取一个对象的地址,格式为:p = &c,而*则是间接寻址或者间接引用。
*p = *p + 10 or *p += 10
表示*p的值增加10,但是在是用如:
(*p)++
时要注意,如果没有括号,则是对p进行加1运算,而不是对p指向的对象进行加1运算。
指针与数组
声明:
int a[10];
int *p;
p = &a[0];
表示指针pa指向数组a的第0个元素,也就是p的值为数组a[0]的地址。也可以写成如下形式:p = a;
对于数组元素a[i]的引用可以写成*(a+i),C语言在计算数组元素a[i]时,实际上是先将其转换为*(a+i)的形式,因此在程序中,a[i]与*(a+i)是等价的。
如果分别在两边都加上地址运算符&,我们则可以得出结论:&a[i]与a+i也是等价的。
字符指针与函数
如果p是一个指向数组中某个元素的指针,那么p++将对p进行自增运算并指向下一个元素,那么p+=i将对p进行加i的增量运算,使p指向第i个元素。
因此我们可以改写strlen函数(用于计算字符串长度的函数):
int strlen(char *s) { char *p = s; while (*p != '\0') { p++; } return p - s; }
如下定义是有很大差别的:
char s[] = "abc";
char *p = "abc";
s是一个仅仅足以存放初始化字符串以及空字符的一维数组,数组中的单个字符可以进行修改;但是s始终指向同一个存储地址,指向的是一个字符串常量,试图修改字符串内容,结果是没有定义的,但是可以修改指向其他地址。
接着是一个字符串复制的例子,代码如下:
1 void strcpy(char *s, char *t) 2 { 3 int i = 0; 4 5 while((s[i] = t[i]) != '\0') 6 { 7 i++; 8 } 9 }
以上是一个比较简单的写法,但是其实有经验的程序员不这么写,以下2种方式比较好:
1 //版本1 2 void strcpy(char *s, char *t) 3 { 4 while ((*s++ == *t++) != '\0') 5 { 6 ; 7 } 8 } 9 10 //版本2(掌握、推荐) 11 void strcpy(char *s, char *t) 12 { 13 while ((*s++ == *t++)) 14 { 15 ; 16 } 17 }
因此我们可以推导出对于strlen函数的修改,代码如下:
1 int strlen(char* s) 2 { 3 int len = 0; 4 while (*s++) 5 { 6 len++; 7 } 8 return len; 9 }
今天就学到这里了,明天继续,加油!