分类: LINUX
2007-03-20 02:24:53
5)size_t是由运算符sizeof返回的无符号整型。
6)有效的指针运算包括相同类型指针之间的赋值运算;指针同整数之间的加法或减法运算;指向相同数组中元素的两个指针间减法或比较运算;将指针赋值为0或指针与0之间的比较运算。5.字符指针与函数
1)字符串常量是一个字符数组,例如:"I am a string"在字符串的内部表示中,字符数组以空字符'\0'结尾,所以,程序可以通过检查空字符找到字符数组的结尾。字符串常量占据的存储单元数也因此比双引号内的字符数大1。
2)printf("hello,world");实际上printf接受的是一个指向字符数组第一个字符的指针。也就是说,字符串常量可通过一个指向其第一个元素的指针访问。
3)pmessage="now is the time"将把一个指向该字符数组的指针赋值给pmessage.该过程并没有进行字符串的复制,而只是涉及到指针的操作。C语言没有提供将整个字符串作为一个整体进行处理的运算符。
4)复制函数,最后的结果是依次将t指向的字符复制到s指向的位置,直到遇到结束符'\0'为止(同时也复制该结束符)
void strcpy(char *s, char *t)
{
while((s[i] = t[i]) != '\0') --------------------- 版本1
while((*s = *t) != '\0') --------------------- 版本2
while((*s++ = *t++) != '\0') --------------------- 版本3
{
s++;
t++;
}
}6.指针数组以及指向指针的指针
#include
#include
#define MAXLINES 5000
char *lineptr[MAXLINES];int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
void qsort(char *lineptr[], int left, int right);/* 对输入的文本行进行排序 */
main()
{
int nlines;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0)
{
}
}#define MAXLEN 1000
int getline(char *, int);
char *alloc(int);/* readlines函数:读取输入行 */
int readlines(char *lineptr[], int maxlines)
{
int len, nlines;
char *p, line[MAXLEN];
nlines = 0;
while ((len = getline(line, MAXLEN)) > 0)
if(nlines >= maxlines || (p = alloc(len)) == NULL)
return -1;
else {
line[len-1] = '\0'; /* 删除换行符 */
strcpy(p, line);
lineptr[nlines++] = p;
}
return nlines;
}/* writelines函数:写输出行 */
void writelines(char *lineptr[], int nlines)
{
int i;
for (i=0; i < nlines; i++)
printf("%s\n", lineptr[i]);
}
void writelines(char *lineptr[], int nlines)
{
while (nlines-- > 0)
printf("%s\n", *lineptr++);
}char *lineptr[MAXLINES]:lineptr是一个具有MAXLINES个元素的一个维数组,其中数组的每个元素是一个指向字符类型对象的指针。也就是说,lineptr[i]是一个字符指针,而*lineptr[i]是该指针指向的第i个文本行的首字符7.多维数组
1)C语言中二维数组的使用方式和其他语言一样,数组元素按行存储,因此,当按存储顺序访问数组时,最右边的数组下标(即列)变化得最快。
2)数组可以用花括号括起来的初值表进行初始化,二维数组的每一行由相应的子列表进行初始化。3)如果将二维数组作为参数传递给函数,那么在函数的参数声明中必须指明数组的列数;而数组的行数没有多大关系。
比如f(int day[2][13]) {...} 或 f(int day[][13]) {...}
因为数组的行数无关紧要,所以,该声明还可以写成 f(int (*day)[13]) {...}4)假如去掉括号,声明成int *day[13]:则相当于声明了一个数组,该数组有13个元素,其中每个元素都是一个指向整型对象的指针。
5)一般来说,除数组的第一维(下标)可以不指定大小,其余各维都必须明确指定大小。8.指针数组的初始化
char *month_name(int n)
{
static char *name[] = {
"Illegal month","January","February","March","April","May","June",
"July","August","September","October","November","December"
};
return (n < 1 || n > 12) ? name[0] : name[n];
}
1)name数组的初始化通过一个字符串列表实现,列表中的每个字符串赋值给数组相应位置的元素。第i个字符串的所有字符存储在存储器中的某个位置,指向它的指针存储在name[i]中
2)由于上述声明中没有指明数组name的长度,因此,编译器编译时将对初值个数进行统计,并将这一准确数字填入数组的长度。9.指针与多维数组
int a[10][20]; 已分配200个int类型长度的存储空间
int *b[10]; 分配了10个指针,但未初始化
1)假定b的每个元素都指向一个具有20个元素的数组,那么编译器就要为它分配200个int类型长度的存储空间以及10个指针的存储空间。
2)指针数组的一个重要优点在于,数组的每一行长度可以不同,也就是说,b的每个元素不必都指向一个具有20个元素的向量。char aname[][15] = { "Illegal month", "Jan", "Feb", "Mar" };
aname:
Illegal month\0 Jan\0 Feb\0 Mar\0
0 15 30 45
10.命令行参数
main(int argc, char *argv[])
1)因此*++argv是一个指向参数字符串的指针
2)因此(*++argv)[0] <=> **++argv是它的第一个字符
3)实际上,表达式*++argv[0]其目的是遍历一个特定的参数串。在内层循环中,表达式*++argv[0]对指针argv[0]进行了自增运算。11.指向函数的指针
1)函数本身不是变量,但可以定义指向函数的指针。
这种类型的指针可以被赋值,存放在数组中,传递给函数以及作为函数的返回值等等#include
#include
#define MAXLINES 5000
char *lineptr[MAXLINES];int readlines(char *lineptr[], int nlines);
void writelines(char *lineptr[], int nlines);
int numcmp(char *,char *);void qsort( void *lineptr[],int left, int right, int (*comp)(void *,void *) );int main(int argc, char *argv[])
{
int nlines; /* 读入的输入行数 */
int numeric = 0; /* 若进行数值排序,则numeric的值为1 */
if ( argc > 1 && strcmp(argv[1],"-n") == 0 )
numeric = 1;
if ((nlines = readlines(lineptr, MAXLINES)) >= 0)
{
qsort((void **)lineptr, 0, nlines-1, (int (*)(void *,void *))(numeric ? numcmp : strcmp))
writelines(lineptr, nlines);
return 0;
}
else
{
printf("input too big to sort\n");
return 1;
}
}
在调用函数qsort的语句中,strcmp和numcmp是函数的地址;因为它们是函数,所以前面不需要加上取地址运算符&,同样的原因,数组名前面也不需要&运算符。
qsort包含一个指针数组,两个整数和一个有两个指针参数的函数;其中,指针数组参数的类型为通用指针类型void *.
由于任何类型的指针都可以转换为void *类型,并且在将它转换回原来的类型时不会丢失信息
void qsort(void *v[],int left,int right,int (*comp)(void *,void *))
{}int (*comp)(void *,void *)它表明comp是一个指向函数的指针,该函数具有两个void*类型的参数,其返回值类型为int.
例如:if( (*comp)(v[i],v[left]) < 0 )int *comp(void *,void *)表明comp是一个函数,该函数返回一个指向int类型的指针,这同我们的本意显然有很大的差别#include
int numcmp(char *s1,char *s2)
{
double v1, v2;
v1 = atof(s1);
v2 = atof(s2);
if (v1 < v2)
return -1;
else if (v1 > v2)
return 1;
else
return 0;
}12.复杂声明
1) int *f(); /* f:是一个函数,它返回一个指向int类型的指针 */
int (*pf)(); /* pf:是一个指向函数的指针,该函数返回一个int类型的对象 */2)char **argv --- argv : pointer to pointer to char
int (*daytab)[13] --- daytab : pointer to array[13] of int
int *daytab[13] --- daytab : array[13] of pointer to int
void *comp() --- comp : function returning pointer to void
void (*comp)() --- comp : pointer to function returning void
char (*(*x())[])() --- x : function return pointer to array[] of pointer to function return char
char (*(*x[3])())[5] --- x : array[3] of pointer to function returning pointer to array[5] of char