指针可是C语言的精髓。本章一开始就用一个例子swap(交换两个数的值)来说明。想想也奇怪,我本科阶段学习C语言的时候其实很差的,这里当时也是一团乱麻,形参、实参、指针这些东西怎么也搞不懂,后来是自学了数据结构以后,就突然开窍了。指针声明通常有两种方法:
int a = 0;
int b = 0;
int *pa = &a;
int* pb = &b;
void strcpy1(char *s,char *t)
{
int i = 0;
while((s[i] = t[i]) != '\0')
i++;
}
void strcpy2(char *s,char *t)
{
while((*s = *t) != '\0')
{
s++;
t++;
}
}
void strcpy3(char* s,char* t)
{
while((*s++ = *t++) != '\0')
;
}
void strcpy4(char *s, char* t)
{
while(*s++ = *t++)
;
}
书中在介绍完多维数组一个,出了一个课后题,大体的意思是通过指针而不是数组下标来访问一个二维数组。具体的解答也很简单,我只想用一个更简单的例子来澄清一些概念(这个类型的题目来自于程序员面试宝典)
int main(void)
{
int Arr[3][4] = {10,20,30,40,50,60,70,80,90,100,110,120};
int (*pArr)[4] =Arr;//注意pArr的类型
printf("%d\n",**pArr);
printf("%d\n",**(pArr+1));
printf("%d\n",*(*pArr+1));
}
#include
#include
#define MAXLINE 1000
int getline(char* line, int max);
int main(int argc, char* argv[])
{
char line[MAXLINE];
long lineno = 0;
int c, except = 0, number= 0,found= 0;
while(--argc > 0 && (*++argv)[0] == '-')//检查第二个命令行参数是否为"-" 这里要注意 (*++argv)[0]与 *++argv[0]的区别
{
while(c = *++argv[0])
{
switch (c)
{
case 'x':
except = 1;
break;
case 'n':
number =1;
break;
default:
printf("find: illegal option %c\n",c);
argc = 0;
found = -1;
break;
}
}
}
if(argc != 1)
printf("Usage: find -x -n pattern\n");
else
{
while(getline(line,MAXLINE) > 0)
{
lineno++;
if((strstr(line,*argv) != NULL) != except)
{
if(number)
{
printf("%ld:",lineno);
}
printf("%s",line);
found++;
}
}
}
return found;
}
int getline(char s[],int lim)
{
int c, i ;
for(i = 0; i < lim-1 && (c = getchar())!= EOF && c != '\n';++i)
s[i] = c;
if(c == '\n')
{
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
我在这里顺便谈一下我对这些问题的处理方法,其实就是3点:
(1)先看变量名,从中间向两边看,注意有没可以构成数组的[]或者函数参数的();
(2)记住()和[]的优先级高于*;
(3)空的()或者()里面有类型,说明这里面一定有函数指针,向前面找函数的返回值。
我举几个例子(这些例子来自于程序员面试宝典):
(1)float(**def)[10];
(2)double*(*gh)[10];
(3)duble(*f[10])();
(4)int*((*b)[10]);
(5)long(*fun)(int);
(6)int(*(*F)(int,int))(int)
书中没有对他们进行详细的说明,我仔细说说我的分析方法。第一个例子,变量名为def紧接着修饰def的**,说明def是一个二级指针。这个指针指向什么呢?看看右边,是[10],再看看左边是float,所以是指向一个数组,数组中有10个元素,每个元素都是float类型。
第二个例子,先看变量名gh,紧接着修饰gh的是*,说明gh是个指针。指向什么?10个元素的数组,数组的类型是double*。
第三个例子,注意:括号优先级高于*,所以f是一个10个元素的数组。数组中的每个元素都是一个指针,什么指针呢?看到了(),向前找返回值,是double类型,所以是指向没有形参,返回值为double类型函数的指针
第四个例子,*b说明b是一个指针,[10]说明是指向数组的指针,int*说明数组的每个元素都是int*类型(指向int的指针)。
第五个例子,*F说明F是一个指针。指向什么,右面看到了(int,int)说明这是一个指向函数的指针,那么函数的返回值是什么呢?(*F)左边是一个*,说明函数返回值也是一个指针。这个指针又是什么类型的呢?还是向右边看有一个(int),说明还是一个指向函数的指针。前面的int说明这个函数的返回值为int类型。
说到这里,其实也能感觉出来《程序员面试宝典》也是很有特色的一本书,它不是教你如何编程或者这样编程正确,或者那样编程容易出错的书,它抠出了很多C和C++的细节问题考你。如果你对自己的基本功很有信息,可以试试看。