Chinaunix首页 | 论坛 | 博客
  • 博客访问: 44145
  • 博文数量: 12
  • 博客积分: 315
  • 博客等级: 一等列兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-25 11:10
文章分类
文章存档

2011年(12)

我的朋友

分类: C/C++

2011-02-27 12:12:05

5.1指针与地址
1.指针是能够存放一个地址的一组存储单元,通常是两个或四个字节(考虑机器字长)
2.地址运算符&只能应用于内存中的对象,即变量与数组元素,它不能作用于常量,表达式,或者register类型的变量.
3.*ip++,会对ip执行+1操作,这是因为*和++这样的一元操作符遵循从右向左的结合顺序;(*ip)++会对ip指向的对象执行+1操作.
 
5.3指针与数组
1.指针(pa)与数组(a)的不同之处,指针是一个变量,数组名不是变量,所以pa=a;pa++;都是合法的,而a=pa,a++是非法的
2.数组名传递给一个函数时,实际上传递的是该数组第一个元素的地址;而被调用函数中,数组名对应的参数必须是一个指针,因此在函数中,对该参数执行++操作是合法的.
 
3.如果确信相应的元素存在,也可以通过下标访问数组第一个元素之前的元素,类似p[-1],p[-2]这样的写法都是合法的.
 
4. int *p;//整形指针
int a[10];
p=a;//ok, a指向a[0]的地址
p=&a[0];//ok,同上
p=&a;//error,cannot convert from 'int (*)[10]' to 'int *'
int (*q)[10];
q=a;//ok,可见&a是一个指向10维数组的指针
 
5.4指针运算
合法的指针运算包括同类型指针之间的赋值,指针与整数的加减法,指向同一个数组中两个元素的指针的减法或比较,指针与0的赋值或比较.
 
5.5字符指针与函数
1.字符串常量
是不同的含义.
amessage表示一个仅仅足以存放字符串和\0字符的数组,amessage指向的地址不能变,而数组中的单个字符可以变;
pmessage表示指向常量字符串的指针,pmessage可以被指向其它地址,但是如果试图修改字符串的内容,结果是未定义的.
 
2.strcpy和strcmp的指针写法
 
5.6指针数组与指向指针的指针
1.char *lineptr[MAXLINES];//lineptr是一个MAXLINES大小的数组,每个数组元素是一个指向字符的指针
2.利用指向指针的指针,做字符串快速排序
/* qsort: sort v[left]...v[right] into increasing order */
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);//取中间元素值为key,将中间元素换到left位置
last = left;//last记录不大于v[left]的位置
for (i = left+1; i <= right; i++)
if (strcmp(v[i], v[left]) < 0)//v[i]swap(v, ++last, i);//把v[i]换到++last位置,即不大于v[left]的元素都被换到最左边
swap(v, left, last);//交换v[left]和v[last],这样v[last]左边都不大于v[last]
qsort(v, left, last-1);//递归对v[last]左边排序
qsort(v, last+1, right);//递归对v[last]右边排序
}
5.7二维数组
如果将二维数组传递给函数参数,必须要指明数组的列数,数组的行数没有太大关系,因为函数调用时传递的是一个指针,它指向由行向量组成的一维数组.
void qsort(char *v[], int left, int right)//指针数组或者指向指针的指针传参
f(int (*daytab)[13]) { ... }//二维数组传参,注意区别
f(int daytab[][13]) { ... }//和上一个相当
 
5.9指针与多维数组
int a[10][20];//a[0]到a[9]是都是指针,指向20维的int数组
int *b[10];//b[0]到b[9]都是指针,指向的地址不一定是20维的数组
 
5.12复杂声明
1.语法形式
简化的语法形式如下(dcl为declaration的缩写):
dcl:           含有可选"*"的direct-dcl
direct-dcl:    name
                     (dcl)
                     direct-dcl()
                     direct-dcl[可选的长度]
  简而言之,声明符dcl就是前面可能带有多个*的direct-dcl。direct-dcl可以是name、由一对圆括号括起来的dcl、后面跟有一对圆括号的direct-dcl、后面跟有手方括号括起来的表示可选长度的direct-dcl。上面的语法要用来对C语言的声明进行分析。
 
2.结合紧密度
在声明/定义变量时,可以使用一些修饰比如“*”,“[]”,“()”等。“()”(非函数声明中的“()”)具有最高的紧密度,其次才是函数和数组的“()”和“[]”。
没有“*”的声明称为直接声明(direct-dcl),而有“*”称为声明(dcl)。直接声明要比声明结合的紧。分解声明时,先读出结合紧的。在这里,我把direct-dcl称为更紧的结合,它比dcl结合得紧。
 
3.右左法则
右左法则是常用的C语言复杂声明解析方法。右左法则其实并不是C标准里面的内容,它是从C标准的声明规定中归纳出来的方法。C标准的声明规则,是用来解决如何创建声明的,而右左法则是用来解决如何辩识一个声明的,两者可以说是相反的。右左法则的原文如下:
  The right-left rule: Start reading the declaration from the innermost parentheses, go right, and then go left. When you encounter parentheses, the direction should be reversed. Once everything in the parentheses has been parsed, jump out of it. Continue till the whole declaration has been parsed.
  其大致意思如下:首先从最里面的圆括号看起,然后往右看,再往左看。每当遇到圆括号时,就应该掉转阅读方向。一旦解析完圆括号里面所有的东西,就跳出圆括号。重复这个过程直到整个声明解析完毕。
解析结果:
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 returning pointer to array[] of pointer to function returning char
   char (*(*x[3])())[5]
x:  array[3] of pointer to function returning pointer to array[5] of  char

 
阅读(1269) | 评论(0) | 转发(0) |
0

上一篇:没有了

下一篇:6 结构

给主人留下些什么吧!~~