本文共 3839 字,大约阅读时间需要 12 分钟。
//部分有误,阅慎!! C语言之指针,数组,引用 [指针] 指针定义:是一种数据类型 , int a,*b;定义整形的变量a,指向整形的指针变量b. 指针变量:是一种 变量,其中存放的值是指针类型的值 0x06E4000H(内存地址) 指针变量的定义与初始化 int a,*b; char c; b=&a; int *c=&a; char *d=&c; 一个指针变量在使用之前必须被初始化,否则指向不一定或者为0、空。 一个指针变量只能指向同一类型的变量;(强制类型转换??) int a[5]; 定义一个四字节的一维数组,每个元素是四个字节 int *p,*q; 定义两个指向四字节指针 char *t; 定义一个指向一字节指针 p=a; p指向数组的首元素 q=&a; q指向数组,是数组指针 t=(char *)a; printf(“%d\n”,a); printf("%d %d %d %d\n",t, t+1, t+2,t+3); 当用一个变量的地址去初始化一个指针变量时,这个变量必须是已经定义过的; 不能把非地址量赋给指针变量; 空指针的值是0的指针,并不是值储存空间为空的意思,这里的0也不是数值的0(asc为48),而 是NULL字符的ASCII码值。不表示任何指向,只是指针变量的一种状态。Int *p=0; 两种特殊的运算符 *:指针运算符取内容运算符(解引用) &:取地址运算符 若p是指针变量; 那么*p 就是指针变量所指向的变量,是指针变量所指向的内存空间中的数据. &p 指针变量所占储存空间的地址(32位机子均为四个字节,二级指针)。 指针的算术运算 与普通整数的加减 p+n表示p当前所指位置向后第n个单元内存地址,这里的单元是与指针变量(p)所指向的存 储空间存储的值类型(*p)相同,所以如果*p是整数则单元是4字节,如果是char则单元是1字节. p+n <----->(unsigned int )p +n * sizeof(* p) 与指针的相减运算 ((p)-(q))/数据长度 (单元的个数) 指针的自增,自减 指针的自增自减是(p+n) n为1的特殊情况 指针的关系运算 指针变量进行关系运算的前提是类型相同,否则都是没有意义,指针变量的关系运算表示他们所 指向的变量在内存中的位置关系,若两个相同类型(指向一致)的指针变量相等,就表示这两个 指针变量指向同一块内存空间。 指针与一般整数常量关系运算也没有意义,但可以与整数0之间进行相等或不等的运算。 指针的赋值运算 把普通变量的地址赋给相同类型的指针变量。 int x,*P; p=&x; 具有相同数据类型的两个指针变量之间可以相互赋值 char *p,*q;(区char *p, q) p=q; 把数组的地址赋给具有相同数据类型的指针变量 double x[10],*p,*q; p=x;q=&x[2];(注 p指向x[0] q指向x[2]) 其他的常用赋值运算 int *p,*q,n; p=q+n; p=q-n; p+=n; p-=n; [多级指针] 数据类型 **变量名; int i=5; int *p=&i; int **pp=&p; 则只有一级指针指向的变量才是要处理的变量,多级指针的数据类型是最终变量的类型。 [引用,这个归c++吧] 引用:就是某一个变量的一个别名 声明:数据类型 &引用名 = 目标变量名; int num; int &ref = num;//在声明的同时必须被初始化 说明: & 在此(定义时)是一个引用运算符,在此不再是进行求地址运算符,而是起标识作用,标志在 此声明的是一个引用的名称。 数据类型既可以是系统的数据类型,也可以是用户自定义的对象 引用在声明时必须被初始化 引用声明完毕后,相当于一个变量,有两个变量名,但是新声明的引用只表示目标变量的一个别 名,所以系统不给引用分配存储单元,二是对应目标的的存储单元地址作为自己的地址,并且从 此不改变,不能在定义为其他变量的别名,从一至终。 操作: 对引用求地址就是对目标变量求地址。 指针变量也是变量,可以声明一个指针变量的引用 数据类型 *&引用名=指针变量名; int * a; int * &p = a; 对比求地址 int b; p=&b; 不能建立数组的引用(不同于指针); 引用本身不占存储单元,就不能声明引用的引用,也不能定义引用的指针; 不能建立空指针的引用 Int &n=NULL; 可以把函数的参数声明成引用类型。 [指针与字符串] 在C/C++中存储一个字符串有两种办法 字符数组char s1[]="Hello world"; 字符指针char *p="Hello world";这种形式下定义的字符串在内存中(位于只读数据区)仍然与字 符数组结构相同,即还是以字符数组存储。 字符指针char *p="Hello world"; 但是 char *p; *p="Hello world";这是错误的,因为我们是把字符串常量的首地址存入p而不是把字符串存入p。 (*符号除了在定义指针变量是个符号,标明定义的是个指针变量,其他情况均为取地址符号) 输出时cout<<p<<endl;即可输出字符串 cout<<p[i]<<endl;即可输出特定空间的字母; 不管哪种存储方式,字符串在存储时,都会在最后自动添加'\0',所以在输出时可以根据是否=='\0' 来判断是否结束for(;*p!=0;p++) 《==》 for(int i;p[i]!=0;i++) 注 意: 在定义字符串指针变量时,可以直接用字符串常量作为初始值对其进行初始化 char *p="Hello world"; 在程序中可以直接把一个字符串常量赋值给一个字符指针变量char *p;p="Hello world";但数组却 不能这样赋值char a[20];a="Hello world"错误(a为地址常量); 字符指针变量不能是未经赋值或者初始化的无定向指针,它必须在程序中已经被初始化或把储存 字符串常量的首地址赋给指针变量;否则无定向指针可能破坏程序,因为他可能指向存放指令或 者数据的内存段; 即char *p;cin>>p;是不正确的; [指针与数 组] int a[10]; int *p; p=&a[0];或者p=a;p中存放是数组第一元素的地址; 注意数组的存储位置是由系统分配的,是一个地址常量,一旦被初始化就不能更改,比如赋值自 加自减 通过指针操作数组: 下标法,如a[i]或p[i]; 指针法,如*(a+i)或*(p+i),可以*p++但不能*a++,a是地址常量; 对于一个数组元素a[i]的地址可以表示为:&a[i], p+i; a+i; 指针变量的运算: (1)p++; (2)*p++;由于*和++都是单目运算符,为同一个优先级,结合方向为从右向左所以等于*(p++); (3)*(p++)跟*(++p);前者先取*p在p+1赋值给p,后者相反; (4)(*p)++表示p所指向的值加1,即(a[0])++,如果a[0]=3;则执行a[0]++后,a[0]的值为4,p仍然指向 a[0]。 (5)*p--相当于a[i--],*++p相当于a[++i],*--p相当于a[--i]. [指针数组] 数据类型 *指针数组名[元素个数]; int *a[2]; 初始化 : 指针数组指向多个变量 double a,b,c; double *p[]={&a,&b,&c}; 指针数组中的每个元素都是一个指针,所以可以很方便指向另一个数组 int a[5]={1, 2, 3, 4, 5}; int *p[]={&a[0], &a[1], &a[2], &a[3], &a[4]}; 字符型指针数组的初始化时,可以使用字符串数组也可以使用字符串常量作为初始值 char s1[]="C++"; char s2[]="php"; char *p={s1,s2}; char *p2={"C++","php"}; 使用字符指针数组处理多个字符串时,各个字符串长度可以不相等,若利用二维数组处理多个字 符串时,每一行的元素数都相等,如果按最长的字符串来定义列数,会浪费很多单元。 [数组指针] 确切的说是数组的指针 数据类型 (*指针变量名)[元素个数]; int a[2][3]={1,2,3,4,5,6}; int (*p)[3]; p=&a; [指针与二维数组] int a[3][2]; int * p[3]; p[0]=a[0];或者p[0]=&a[0][0]; 二级指针处理二维数组 续上 int **pp=&p;则*pp=a[0]; *pp+1=a[1]; *pp[2]=a[2]; *(*pp+1)=a[0][1]; ** (pp+1)=a[1][0]; *(*pp+1)+1=a[1][1]; **(pp+2)=a[2][0]; *(*pp+2)+1=a[2][1]; 其中*(*pp+i)+j==p[i][j]; 二级指针与字符串 char *a[]={"tianjin","beijing","shanghai",NULL}; char **pp; pp=a; while(*pp!=NULL) { cout<<*pp++<<endl; }转载地址:http://tjwdn.baihongyu.com/