C语言指针理解
一指针与数组
1.特别注意指针加1,意味着所指向的对象的下一个对象,不是代表地址的整数值加1。这个无论指针p指向何种类型。
2.数组名所代表的就是该数组最开始的一个元素的地址。在C语言中,a[i]实际等价于*(a+i)的形式,当然&a[i]和a+i意义相同。但我们必须记住数组名和指针还是有差别的,指针式变量,存在pa=a pa++等操作。数组名不是变量,没有上述操作。我们可以理解为数组名就是一个标号,他没有地址,所以也就不能操作。
3.对于形参为数组的函数,我们即可以把函数名字作为形参,也可把数组名字作为指针传给函数,比如
f(int arr[]){...}或
f(int *arr){...}4.C语言保证,0永远不是有效的数据地址。返回值0可用来表示发生了异常事件。
char * pmessage = "now is the time";和数组一样,都是将一个指向字符数组第一个字符的指针传给pmessage。
char * pmessage = "now is the time";是将一个指向该字符数组的指针赋值给pmessage,该过程并没有进行字符串的复制。我们这里理解为message是一个字符指针,它指向一个字符串常量,或者说指向一个字符数组。但要注意和char [] pmessage的区别。
.*p++ = val;val = *--p;
char * c="hello world"; char c[]="hello world";
#include <string.h>#include <stdio.h>#include <stdlib.h>#define MAXLINES 5000char *lineptr[MAXLINES];int readlines(char *lineptr[], int nlines);void writelines(char *lineptr[], int nlines);void qsort(char *lineptr[], int left, int right);int getline(char s[],int lim)//从输入流中读取lim个字符到s中,返回读入的字符个数,因为可能会遇到换行,文件末尾等情况,所以可能指定读的个数不等于实际读的个数{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;}#define ALLOCSIZE 10000 /* size of available space */static char allocbuf[ALLOCSIZE]; /* storage for alloc */static char *allocp = allocbuf; /* next free position */char *alloc(int n) /* return pointer to n characters */{if (allocbuf + ALLOCSIZE-allocp>= n) { /* it fits */allocp += n;return allocp-n;/* old p */}else {/* not enough room */return 0;}}#define MAXLEN 1000int readlines(char *lineptr[], int maxlines){//返回读到的行数int len ,nlines;char *p,line[MAXLEN];nlines = 0;while((len = getline(line,MAXLEN))>1){if(nlines>=maxlines||(p =alloc(len))==NULL){return -1;}else{line[len-1] ='\0';strcpy(p,line);lineptr[nlines++] = p;}}return nlines;}void writelines(char *lineptr[], int nlines){int i;for (i = 0; i < nlines; i++){printf("%s\n", lineptr[i]);}}void swap(char *v[], int i, int j){char *temp;temp = v[i];v[i] = v[j];v[j] = temp;}void qsort(char *v[], int left, int right){int i, last;void swap(char *v[], int i, int j);if (left >= right) /* do nothing if array contains */return; /* fewer than two elements */swap(v, left, (left + right)/2);//先让left指向整个数组的中间,而(left+right)/2指向头部last = left;//使last指向中间for (i = left+1; i <= right; i++)//从中间往后进行循环遍历if (strcmp(v[i], v[left]) < 0)//如果后面的元素比这个事先选择好的中间的值小的话,就把这个小的值移到紧跟中间值的后面,swap(v, ++last, i);swap(v, left, last);//最后把last和left交换,也就是让所有小于中间值的数都移到中间值的前面qsort(v, left, last-1);//递归处理qsort(v, last+1, right);}main(){int nlines; /* number of input lines read */if ((nlines = readlines(lineptr, MAXLINES)) >= 0) {qsort(lineptr, 0, nlines-1);writelines(lineptr, nlines);system("pause");return 0;} else {printf("error: input too big to sort\n");return 1;}}
int daytab[2][13]) { ... }可写成
f(int daytab[][13]) { ... }
f(int (*daytab)[13]) { ... }参数是一个指针,它指向具有13个整数元素的一维数组。因为方括号优先级高于*的优先级,所以上述必须使用圆括号括起*daytab,否则就变为一个长度为13的数组,它的数组元素为int的指针。
int (*comp)(void *, void *)它表明comp是一个指向函数的指针,该函数具有两个void*类型的参数,其返回值类型int。
int *comp(void *, void *)则表明comp是一个函数,它返回一个int型的指针。
(*comp)(v[i], v[left])这里就是对函数的调用,因为comp是一个指针,所以*comp就是取得对这个指针所指向的函数的调用。
int *f();int(*pf)();由于*是一个前缀运算符,其优先级低于(),所以第一个表示f是一个函数,它的返回值是一个int型的指针,第二个pf为一个指针,它指向一个函数,这个函数返回值是int型。