指针

来源:互联网 发布:世界之窗浏览器 知乎 编辑:程序博客网 时间:2024/05/20 20:04

一维数组指针
  int a[10], *ptr;
  ptr=a;或ptr=&a[0];
  ptr+n与a+n表示数组元素a[n]的地址,即&a[n]。
  *(ptr+n)和*(a+n)等效于a[n]。
  ptr[n]等效于*(ptr+n)。
二维数组指针
  int a[3][4], *ptr;
  把二维数组看成n行一维数组,a[n]就是第n行的首地址。将每行的首地址传递给指针变量,行中的其余元素均可以由指针来表示。
  &a[1][2]等效于a[1]+2。
  ptr=a[1]等效于ptr=*(a+1)。
  数组元素a[1]是一维数组的首地址(一个指向int型的指针)。
  二维数组其实就是包含数组的数组。a[1]的元素类型是数组int [4],当访问数组元素a[1]时,编译器知道这是一个int [4]的数组(首地址)。
  数组名不是变量,它只是一个记录地址的标签,在对元素的访问上所起的作用和指针一样。可以将二维数组名理解为指针的指针。
  ptr=a; // 错误:int *与int (*)[4]的间接级别不同。a实际上是一个指向int [4]类型的指针。
  int (*ptr)[4]=a; // 正确。一个指向4个元素的数组的指针,数组元素的数据类型为int。
  在引用元素的时候,可以这样:(*ptr)[0],(*ptr)[1],(*(ptr+1))[0],(*(ptr+1))[1]。
指针数组
  指针类型 *数组名[数组长度]
  int *p[4];
  由于[]比*优先级高,因此p先与[4]结合,形成p[4]的形式,这显然是数组形式。然后再与p前面的*结合,表示数组元素的数据类型为int *。
函数指针数组
  函数返回值类型 (*数组名[])(形参列表)
  *数组名[]外面的括号改变了默认的运算符优先级。圆括号和数组说明符的优先级相同,如果不用圆括号将指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,*数组名[]()则会产生一个怪物:返回值类型为指针的函数数组。所以必须括起来,以保证数组的每一个元素是指针(指向函数入口地址)。
指针的指针
  #include <stdio.h>
  func(int **fp)
  {
   while(**fp != 0)
   {
    if(**fp == 7) break;
    else (*fp)++;
   }
  }
  main()
  {
   int a[10] = {1,2,3,4,5,6,7,8,9,0};
   int *p = a;
   printf("%d/n",*p);
   func(&p);
   printf("%d/n",*p);
  }
  指针的指针另一种用法是处理指针数组。有些程序员喜欢用指针数组来代替多维数组,一个常见的用法就是处理字符串。
  #include <stdio.h>
  main()
  {
    char *Names[] = {"Bill","Sam","Jim","Paul","Charles",0};
    char **nm = Names;
    while(*nm != 0) printf("%s/n",*nm++);
  }
  先用字符型指针数组Names的地址来初始化指针nm。每次调用printf()都首先传递指针nm指向的字符型指针,然后对nm进行自增运算使其指向数组的下一个元素(还是指针)。注意*nm++,++优先级高于*,该表达式等价于*(nm++),由于nm++是后缀增量运算,因此按自左向右的计算顺序,它首先取得指针指向的内容,然后使指针自增。
  注意数组中最后一个元素被初始化为0,while循环以此来判断是否到了数组末尾。具有零值的指针常常被用做循环数组的终止符。程序员称零值指针为空指针(NULL)。采用空指针作为终止符,在数组增删元素时,就不必改动遍历数组的代码,因为此时数组仍然以空指针作为结束。
函数指针
  函数返回值类型 (*指针变量名)(形参列表)
  指针变量名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。注意:函数指针没有++和--运算。
  int (*fptr)();
  fptr=&function;
  fptr=function;
  取地址运算符&不是必需的,因为函数标识符就表示了它的地址。
  x = (*fptr)();
  x = fptr();
  第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。
  #include<stdio.h>
  int max(int x,int y){return(x>y?x:y);}
  void main()
  {
    int a,b,c;
    int (*ptr)(int,int);
    ptr=max;
    scanf("%d,%d",&a,&b);
    c=(*ptr)(a,b);
    printf("a=%d,b=%d,max=%d",a,b,c);
  }
  void (*)(); // 只声明了数据类型
  unsigned psize = sizeof(void (*)()); // 获得函数指针大小。
  char (*pfv)(int);
  typedef void (*pfv)(); // 定义数据类型,类型名为pfv,即一个指向特定函数的指针。
  pfv ptrfv;
LPCTSTR,LPWSTR,PTSTR,LPTSTR
  L:表示long指针,在Win32中以及其他的32位操作系统中,long指针和near指针及far修饰符没有实际意义。long,near,far与普通指针没有区别,LP与P是等效的。
  P:表示这是一个指针。
  T:表示_T宏,这个宏用来表示你的字符是否使用UNICODE。如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。
  STR:表示这个变量是一个字符串。
  C:表示是一个常量,const。
  W:表示宽字符。

原创粉丝点击