指针看书笔记


指针看书笔记
2010年12月10日
  /* 
  * ================================================== =================================== 
  * 
  * Filename: 指针类型的参数和返回值.c 
  * 
  * Description: 指针类型的参数和返回值 
  * 
  * Version: 1.0 
  * Created: 2010年12月05日 18时27分57秒 
  * Revision: none 
  * Compiler: gcc 
  * 
  * Author: Yang Shao Kun (), [email protected] 
  * Company: College of Information Engineering of CDUT 
  * 
  * ================================================== =================================== 
  */ 
  #include
  int *swap(int *px,int *py) 
  { 
  int temp; 
  temp=*px; 
  *px=*py; 
  *py=temp; 
  return px; 
  } 
  int main(void) 
  { 
  int i=10,j=20; 
  int *p=swap(&i,&j); 
  printf("now i=%d j=%d *p=%d\n",i,j,*p); 
  return 0; 
  } 
  运行后结果是: 
  now i=20 j=10 *p=20 
  在使用指针做为返回值的时候,要特别的注意一个,返回值的指向问题: 
  例如: 
  int * foo(void) 
  { 
  int a; 
  .... 
  return &a; 
  } 
  foo函数返回的值是一个指向局部变量的a的指针,可是foo函数返回之后它的栈桢就要被释放,那么我们用这个指针有什么用呢?,这就是一个野指针。有时候,编译器会报错: 
  waring:function returns address of local variable; 
  指针和数组: 
  int a[10]; 
  int *pa=&a[0]; 
  pa++; 
  因为,这里的pa是整型的指针,所以在字增的时候,也就是说每次真加的是4个字节。 
  指针和const限定符 
  const int *a; 
  int const *a; 
  这两种写法一样,a是一个指向const int 型的指针,a所指向的内存单元不可改写,所以(*a)++是不允许改写的,但是a本身可以改写,即,a可以指向别的内存单元。 
  int *const a; 
  a是指向int型的const的指针,*a是可以改写的,但是a本身是不允许改写的。 
  int const *const a; 
  a是指向const int 型的const型指针,因此*a和a本身都是不能改变的。 
  非const变量的指针可以隐式的转换为const变量的指针: 
  char c='q'; 
  const char *pc=&c; 
  左值:的关键是一个变量,是一个实实在在命名的内存区域(an object is a named region of storage ),你可以在里面存放数据和信息。通过非函数类型申明的非类型标识符都是左值。 
  右值:rvalue 是指表达式的值,what is sometimes called "rvalue" is in this international standard described as the "value of an expression",其实,r也有read的意识,也就是要把存在左值的存储空间中的东西读出来。 
  由.运算符组成的表达式能不能做左值取决与点运算符左边的操作数能不能做左值。 
  由->运算符组成的表达式一定能做左值。 
  在调试一个程序的时候,我们可以用一下几种方法来添加运行的参数: 
  1:r 后面加参数 
  2:s 后面加参数 
  3:set args 后面加参数 
  指向数组的指针:其实和二维数组的作用是相似的,但是用起来比二维数组好用的多,能过自增! 
  我们知道指针变量内存单元存放一个地址值,而函数指针的内存单元里存放的是函数的 
  入口(位于.text段),函数类型和数组类型相似,做右值使用时,自动转换成函数指针 
  类型,同时,数组取下标预算符[],要求操作数是指针类型,a[1]等价于*(a+1),如果a是 
  数组类型则要自动转换成指向首元素的指针类型,同样的道理,函数调用预算符(),要求操作数是函数指针类型。 
  函数的返回值可以是 void类型,标量类型,结构体或联合体,但是不能返回函数类型。 
  c语言的类型分为函数类型,对象类型和不完全类型。 
  对象类型包括:scalar types和nonscalar types。其中,不完全类型是没有完全定义好的类型,编译器不知道这种类型占几个字节的存储空间。如果编译器处理到编译单元的末尾仍然无法把不完全 
  类型合成一个完全类型时,就会报错。 
  例如: 
  struct s{ 
  struct t *pt}; 
  struct t{ 
  struct s *ps};这两个结构体中各有一个指针成员指向例外的一种类型,编译器重前面 
  到后面的处理,但看到struct t时,是一个不完全类型,尽管如此,这个指针确实完全 
  类型,因为指针的大小是4个字节的空间,然后又看到 struct t ,这个时候struct t 
  有了完全的定义,pt的类型就组合成一个指向完全类型的指针。 
  但是如果这样的类型定义就是错误的: 
  struct s{ 
  struct t ot}; 
  struct t{ 
  struct s os};但编译器看到 struct s时,认为 struct t是一个不完全类型,无法定 
  义成员ot,因为不知道它应该占几个字节。 
  所以,结构体中可以递归的定义指针成员,但是不能递归的第一变量成员。 
  下面我们来看几个复杂的声明:
  typedef void (*sighandler_t)(int); 
  sighandler_t signal(int signum,sighandler_t handler); 
  合并在一起的时候是: 
  void (*signal(int signum,void (*handler)(int)))(int);
  #include
  int main(int argc,char *argv[])/*这样写给读代码的人提供了有用的信息,argv不是指向单个指针,而是指向一个指针数组的首元素,数组中每个元素都是char*指针,指向一个命令行参数字符串。 
  */ 
  { 
  int i; 
  for(i=0;i;i++) 
  { 
  printf("argv[%d]=%s\n",i,argv[i]); 
  return 0; 
  } 
  }

猜你喜欢

转载自tht868tg.iteye.com/blog/1361714