标签:
1.指针(变量的地址):
指针变量:存放指针(地址)的变量
直接存取(访问):按变量地址取值
间接存取(访问):将变量的地址放入指针变量中
定义指针变量:基类型 *指针变量名
2.与指针有关的运算符:
&:取地址运算符
*:指针运算符(间接访问运算符);
int *pointer_1,*pointer_2;
int a = 1, b = 2;
pointer_1 = &a;
pointer_2 = &b;
pointer_2 = &*pointer_1;//*,&优先级一样,自右至左结合,所以是先取a的值,再取a的地址&a给指针变量pointer_2
若有*&a,表示的是先取a的地址,再取a的值。
3.谨记:函数传参:实参->形参 之间的数据是单向传递的“值传递方式”,指针变量也遵守这一原则,调用函数时,不会改变实参指
针变量的值,但可以改变实参指针变量所指向的值。所以可以利用指针来改变主调函数中多个变量的值,不用指针变量来实现这个是
很难实现这一点的。
4.数组元素的指针就是数组元素的地址
int a[10];
int *pointer;
pointer = a[0];与pointer = a; 等价都表示数组的第一个元素的地址。
如果初始:pointer = a; 以下都为此前提,那么:
pointer+1 = a+1 = a[1] //实际地址看类型,pointer+1*n 或者 a+1*n 或者&a[1]
所以有pointer+i = a+i = a[i] pointer+i*n a+i*n &a[i] 例:int型n=4;
所以可以看出[]是变址运算符,对a[i]的处理是这样的:先按a+i*n计算数组元素的地址,然后由此地址找出所指向的单元的
值
指向数组元素的指针变量也可以带下标,如:pointer[i]与*(pointer+i)等价。
所以引用数组元素有两种方法:
a.下标法:a[i];
b.指针法:*(a+i)或者*(pointer+i);使用这种方法能使目标程序质量高(占运行内存小,运行速度快)
·注意:指针变量可以指向有效的数组元素,也可以指向数组以后的内存单元。例:
int a[10], *p = a;
cout <<*(p+10);//编译不会提示出错。
5.如果先使p=a,即p指向数组a的首元素:
(1).p++(或p+=1):使p指向下一元素,即a[1],如果用*p,则得到a[1]的值;
(2).*p++: ++与*优先级相同,右结合,相当于*(p++),所以是先取*p的值,再使p++。
例如:
for(p=a;p<a+10;p++)
cout <<*p ; //可改写为:
for(p=a;p<a+10; )
cout <<*p++;
(3).*(p++):先取*p值,p再加1
*(++p):先p加1,再取*p值,二者区别仅在于p++ 与 ++p 的含义。
(4).(*p)++:先取*p的值,再使取得的值加1.
(5).如果p当前指向a[i]:
*(p--): 先取*p的值,即a[i],再使指针变量p指向a[i-1];
*(++p): 先使指针变量自增1,指向a[i+1],再取*p的值a[i+1];
*(--p): 先使指针变量自减1,指向a[i-1],再取*p的值a[i-1];
6.使用指针变量作函数参数接收数组地址
因为数组作形参时接收的也是实参数组的首地址,所以可以用指针变量来接收以数组为实参的参数,例如:
void select(int array[]);//实际上可以表示为
void select(int *array );/*编译器实际上是将数组名作为指针变量来处理的。所以实际上,在函数调用时并不存在一个
占有存储空间的形参数组,只有指针变量。*/
7.多维数组与指针:
int arr[3][4];假设arr起始为2000
(1)C++中规定了数组名作为首地址,所以
arr[0]是arr[0][0]的首地址,arr[1]是arr[1][0]的首地址即&arr[1][0],
arr[0]+1,表示arr[0][1]的地址,arr[0]+2表示的是arr[0][2]的地址;
*(arr[0]+2) 表示a[0][2]的值。所以有
arr[i]+j 表示&arr[i][j],
*(arr[i]+j) 表示arr[i][j]的值。
(2)arr,表示首行地址&arr[0],则a+1表示第二行起始地址&arr[1],其值为2000+4*4=2016;
arr[1]+1: 表示 &arr[1][1],所以有
arr[i]+j: 表示 &arr[i][j],
*(arr[i]+j):表示 arr[i][j]的值,因为arr[i] = *(arr+i);所以
*(*(arr+i)+j): 也表示arr[i][j]的值。
(3)指向数组元素的指针变量:
#include<iostream>
using namespace std;
int main(){
int array[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int *p;
p = array[0];//注意此处是array[0],而不是array,要符合指针类型。
cout <<"--------------" <<endl;
for( p; p<array[0]+12;p++ )
cout <<*p<< ‘ ‘;
cout <<endl;
cout <<"--------------" <<endl;
return 0;
}
(4)指针变量指向由m个元素构成的一维数组
#include<iostream>
using namespace std;
int main(){
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int (*p)[4],i,j;/*(*p)[4]是一个指针变量,它指向包含4个整型元素的一维数组,()不可丢,
否则变成*p[4],[]优先级高,变成了指针数组
*/
p = a;//p指向a[0];
cout <<"please input i,j:";
while(1){
cin >>i >>j;
if( i>=3||j>=4 )
cout <<"warning:i must less then 3,j must less then 4,please try a again:" <<endl;
else break;
}
cout <<"---------------------" <<endl;
cout <<*(*(p+i)+j);
cout <<endl <<"---------------------" <<endl;
return 0;
}
8.指向数组的指针作函数参数(一维数组名,多维数组名也可,之前有讲过)
#include<iostream>
using namespace std;
int main(){
void output(int (*p)[4]);
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
output(a);//a指向a[0]
return 0;
}
void output(int (*p)[4]){//注意形参声明为指向一维数组的指针变量,而不是int型指针变量
int i,j;
for( i=0;i<3;i++ )
for( j=0;j<4;j++ )
cout <<*(*(p+i)+j) <<" ";
cout <<endl;
}
9.字符指针(C++中共3种方法访问一个字符串,之前已经学习过两种)
(1)用字符指针指向一个字符串
#include<iostream>
using namespace std;
int main(){
char *str = "I love China!";//对字符指针变量str的初始化其实是把字符串第一个元素的 地址 赋给str
//等价于 char *str; str = "I love China"; 输出时,系统先输出str指向的第一个字符数据,
//然后str+1,使之指向下一个字符,然后输出......直至遇到‘\0‘为止,在内存中,字符串的末尾
//被自动加了一个‘\0‘
cout <<str<<endl;
return 0;
}
(2)利用字符指针实现对字符串的存取
#include<iostream>
using namespace std;
int main(){
char str1[] = "I love liu_xiao_min",str2[20];
char *p1,*p2;
p1 = str1;
p2 = str2;
for( ;*p1!=‘\0‘;p1++,p2++ )
*p2 = *p1;//其实string str1 = "I love liu_xiao_min",str2;str2 = str1;最简单快捷
*p2 = ‘\0‘;
p1 = str1;
p2 = str2;
cout <<p1 <<endl;
cout <<p2 <<endl;
return 0;
}
10.函数与指针
(1)用函数指针变量调用函数(原理:一个函数被编译时被分配一个入口地址。这个函数入口地址就称为函数的指针)
函数指针定义:
函数类型 (*指针变量名)(函数形参表);
例:
#include<iostream>
using namespace std;
int main(){
int max( int x, int y );
int (*p)( int, int );//(*p)括号不能漏
int a,b,n;
p = max; //函数名代表函数入口地址
cin >>a >>b;
m = p( a,b );
cout <<"max=" <<m<<endl;
return 0;
}
int max( int x, int y ){
int z;
if( x>y )
z = x;
else
z = y;
return z;
}
(2)用指向函数的指针作函数参数
类似:float intern(float a, float b, float (*fun)(float));
11.指针函数(函数返回值为指针的函数)
指针函数定义:
函数类型 *函数名(参数表列);
例:
#include<iostream>
using namespace std;
int main(){
int *a(int a);
int i = 10;
cout <<a( 10 ) <<endl;
return 0;
}
int *a( int a ){
return &a;
}
12.指针数组(一个数组,其元素全部为指针类型数据)
一维指针数组:
类型名 *数组名[数组长度];
例:int *a[3]; //注意与int (*a)[3];的区别,后者是指向含有3个整型元素的一维数组的指针变量
#include<iostream>
#include<cstring>
using namespace std;
int main(){
void sort( char *name[], int n );//指针数组做函数参数
void print( char *name[], int n );
char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };//指针数组
int n = 5;
sort( name,n );
print( name,n );
return 0;
}
void sort( char *name[], int n ){ //选择法排序
char *temp;
int i,j,k;
for( i=0;i<n-1;i++ ){
k = i;
for( j=i+1;j<n;j++ ){
if( strcmp( name[k],name[j] )>0 )//name[x]中存放各个字符串的首地址
k = j;
}
if( k!=i ){
temp = name[i];name[i] = name[k];name[k] = temp;
}
}
}
void print( char *name[] , int n ){
int i;
for( i=0;i<n;i++ )
cout <<name[i] <<endl;
}
输出:
BASIC
C++
COBOL
FORTRAN
Pascal
13.指向指针的指针(指向 指针数据 的指针)
如12所述,数组name[x]是一个指针数组,此时设一个指针变量p,它指向指针数组元素的元素,则p就是指向指针型数据的指
针变量。
定义一个指向指针数据的指针:
char *(*p);//可以写成 char **p;
分析:
char *p:表示指向字符型数据的指针变量(即字符指针变量)。
char *(*p):表示p指向的是字符指针数据
例:
#include<iostream>
using namespace std;
int main(){
char **p;//定义指向 字符指针数据 的指针变量p
char *name[] = { "BASIC","FORTRAN","C++","Pascal","COBOL" };
p = name + 2; //指向name[2]
cout <<*p <<endl;//输出name[2]中指针指向的字符串的值
cout <<**p <<endl;//输出name[2]指向的字符串中的第一个字符
return 0;
}
输出:
C++
C
分析:
由于*p代表name[2],它指向字符串"C++",即在name[2]中存放了字符串"C++"的第一个字符串的地址,因此"cout <<*p <<endl;"就
是从第一个字符开始输出字符串"C++"。第二个cout中的**p是*p(值为name[2])指向的"C++"第一个字符元素的内容,即字符"C",所以
第二个cout语句输出"C".
标签:
原文地址:http://www.cnblogs.com/ysys/p/5686534.html