引言:在重新搭个人博客之前,还是把笔记迁移到这里来好了,emmm
指针的使用是C语言中最复杂的部分,而数组由于其与指针的关联性致使在使用指针操作数组时尤为复杂。
但事实上,只要掌握基本的概念和使用方法,我们完全不必害怕使用指针,相反,良好的指针操作效率更好,也能使代码简洁明了
- 一维数组
声明一个char array[],array是一个指针,指向数组所分配的空间的首地址
*array就可以直接取到array[0],注意,当我们要取数组后面的元素时,可以直接使用*(array+i)取到array[i],注意,如果使用的是*array+i,其实是取array[0]+i,这是因为双目运算符+的优先级小于单目运算符*
对于指针k而言,*k++这种操作是没问题的,但是*array++是不允许的,这是因为array是数组的标识名,是常量,不能跟++,所以要使用++的用法,可以这样做,声明一个同类型的指针k
char *k;
k = array;
此时k指着array数组的空间,就可以进行很多骚操作,比如strcpy的复制就可以这样:
strcpy(*s,*t) {
while(.....)
*s++ = *t++ //s和t是指向两个数组的指针
}
*k++是先取*k,再对k进行自增操作。而对于*++k,就是先进行自增,再取值,这是因为++和*是同优先级的单目运算符,结合顺序是从右到左
这里说明一下 绝大部分运算符都是从左至右
但是有这么几种是特殊的:赋值运算符、单目运算符、三目运算符
这里再提一下(*k)++就是取k的值,对该值进行自增,而不是对k自增,这里直接用( *array)++也是没问题的,因为自增的是array数组中的值,而不是array
- 多维数组
对于多维数组来说,指针的操作更复杂了。
首先要理解多维数组的形式,声明一个marray[][MAXSIZE],这里marray[i]每个都是指针,指向该行的首地址,但多维数组的列长度是确定的,这里与指针数组就区别开了。
多维数组实质存放在连续地址空间,而不是逻辑上的多维矩阵,意味着我们指针的操作可以变得非常强大。
声明这么一个二维数组
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
注意这里的daytab,作为指针,指向的是数组{daytab[0],daytab[1]}的首地址,而daytab[0]也是数组,指向的是{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}的首地址。
当我们要求取daytab[0][0]时,是用**daytab。*daytab事实上就等于daytab[0],**daytab就是*daytab[0],所以这里其实是一个三级结构:
(图)
当我们要操作某一行某一列的时候,可以用*(daytab+i)+j表示daytab[i][j]的地址,用*(*(daytab+i)+j)才是daytab[i][j]的值,由于地址的连续性,使用*(*daytab + len*i + j)和*(*(daytab+i)+j)是完全等价的,这里len是二维数组的列数。
指针的声明
声明一个指针的时候,虽然分配了地址空间,但是其内容是不确定的,意味着在未对指针初始化的情况下进行操作是不允许的,这样的指针也被称为野指针
对于指针数组,*p[10]表示10个指针组成的数组,(*p)[10]表示一个指向有10个元素的指针。
在这里,未初始化的指针数组也是不能直接操作的