#define 串1 串2 //;不能加
//只进行串的替换,不进行类型优先级的检查。
#define A 6
#define B A
#define PLUS(X,Y) X+Y
int x=1,y=2,z=3,sum;
sum=PLUS(x+y,z)*PLUS(y,z);
=x+y+z*y+z
第6章 指针、引用和动态空间
<1>指针:唯一可以存放地址的变量。
[一般的变量存放是值],宾馆中的房间号
指针:存放是他所指向的变量在内存中的地址。
定义方法:
指针的类型 *指针变量名;
注意事项:
1、指针的类型:是有他所指向的变量类型决定的。
2、指针赋值必须同级,或者使用&;
int a=5,b=7;//
int *kk=&b;
int *pa=&a;
int **ppa=&pa;//&取地址。
printf("%x %x\n",a,&a);
printf("pa=%x %x\n",pa,&a);
printf("%x %x\n",ppa,&pa);
3、指针++加上,--减去整数,表示指针上、下移动。
两个指针相减,表示指针之间相差元素的个数。
4、各种类型的指针,本身所占的空间大小相同都是
4byte,不同点在于++,--时移动的字节数不同。
//sizeof(int)
int *pa;//没有初始化,指针很危险,有可能指向
低地址,内存核心区域,出现异常。
//改为 int *pa=NULL; //pa+1
*pa=87; double *pr=&r;//pa,pr看图
5、空指针:指针不指向任何位置 int *p=NULL;
//int *pp=0;一般用于链表的结束。
6、任意类型的指针:
int a=3,*p=&a;
void *pa=p;//pa是一个指向任意类型的指针,可以
p=pa;//错误,不能把一般的给特殊的
7、指针的两大作用:
一、间接访问:通过指针的间接访问去修改变量的值
二、动态申请空间:链表
<1>、指针的间接访问:*与*的声明一样
int x=6; int*px=&x,*t=&x;
*px=65; cout<<x<<" "<<px<<" "<<*px<<endl;
*t=7;cout<<x<<" "<<t<<" "<<*t<<endl;
int **pp=&t;
**pt=90; //x=90
区别:如果*前面有类型,就是指针的定义,否则为指
针的间接访问,可以修改指针所指向变量的值。
如:
int a=3,b=6;//变量的定义
int *pa=&a;//pa就是一个指向整形的一级指针
int *pb=&b;
float r=3.5; float *pr=&r;//浮点类型指针
int *pt=a;//错误,指针赋值必须同级,或者使用&
int *pt=&a;//错误,指针赋值必须同级,或者使用&
cout<<hex<<&a<<" "<<&b<<endl;
cout<<pa<<" "<<pb<<endl;
cout<<&pa<<endl;
pa=pb;//正确,同是类型相同的一级指针
int **ppa=&pa;//二级指针
8、一维数组的数组名,就是一个一级指针,指向数组
的第一个元素。
int a[5];//a是一级指针 a存放a[0]在内存的地址
int a[5]={1,2,3,4,5};
cout<<hex<<a<<" "<<*a<<endl;
int *sp=a;
*sp=9;//间接修改a[0]
int a[5]={1,2,3,4,5}; int *sp=a;
<1>、i=*sp++;//结果为: i=a[0],sp指向a[1];
<2>i=(*sp)++;//结果为: i=a[0],a[0]=a[0]+1;
<3>i=*(sp++);//结果为: i=a[0],sp指向a[1];与<1>相
同
<4>i=*(++sp);;//结果为: i=a[1],sp指向a[1];
int *w=NULL ;
*w=65;
w=w-200;
printf("%d\n",sizeof(short int));
double r=7;
double *point_1=&r;
double *point_3=&r;
double *point_4=&r;
*point_1=98;
double **point_2=&point_1;
**point_2=65;
int a[5]={1,2,3,4,5};
int *pa=&a[0];//或者pa=a
pa=pa+3;//pa指向a[3]
*pa=77;//指针的间接访问 a[3]=77
pa--;
*pa=66;
//*什么时候是间接访问,什么时指定的定义
//*前面有类型是定义,出现第一次
//*前面没有类型,是指针的间接访问
//一维数组的数组名是一个一级指针,指向
//数组的第一个元素即存放第一个元素a[0]的地址
for(int i=0;i<5;i++)
printf("%d ",*(a+i));//a[i]=*(a+i)
printf("\n%x\n",a);
printf("%x\n",a[0]);
printf("%x\n",&a[0]);
getchar();
getchar();getchar();
}
<1>*sp++=6;//a[0]=6 sp指向a[1]
sp=a;
<2>*++sp=6;//sp先移动指向a[1] a[1]=6
例如:P87
int i,m[50];
int *p=m;
p+=10;
p=m+10
i=*p
i=*(m+10)
i=*p++;
i=(*p)++;
i=*--p;
i=*(p-=5);
(*(p+1)=9;
一维数组:a[i]=*(a+i)
二维数组:
a[i][j]=*(*(a+i)+j)=*(a[i]+ ]
二维数组名:不是一个简单的二级指针,***是一个行
指针,指向第一行,数组名+1移到下一行[移动列那么
个多元素]。
int a[2][3]={{1,2,3},{4,5,6}}
指针:静态指针: 数组下标
动态指针:*
int i,m[50];
int *p=m;
p+=10;
p=m+10 ://p指向m[10]
i=*p;//i=m[10]
i=*(m+10);//i=m[10]
i=*p++;//{i=*p,p++指向m[11]}
i=(*p)++; {i=m[11];m[11]=m[11]+1;}
i=*--p; {p指向m[10];i=m[10];}
i=*(p-=5); {p指向m[5];i=m[5];}
*(p+1)=9; {m[6]=9;}
int a[]={1,2,3,4,5,6},i;
int *p=a;
i=*p++;
cout<<i<<" "<<*p<<endl;
i=(*p)++;
cout<<i<<" "<<*p<<" "<<a[1]<<endl
二维数组名:不是一个二级指针,他是一个行指针,指
向第一行,这行有列那么多个数
***数组名+1移向下一行(移动列那么个数的位置)
.int a[2][3];
a:行指针
a+1:指向下一行
a[i][j]=*(*(a+i)+j)
=*(a[i]+j)=*(a+i)[j]
//int *p=87;错误
调试:
int b[2][3]={{1,2,3},{4,5,6}};
cout<<&b[0][0]<<" "<<&b[1][0]<<endl;
cout<<b<<endl;
cout<<(b+1)<<endl;
int *p; int a[5]
<1>字符串与字符指针:
字符串:放在字符的一维数组中//char name[10];
char name[10]="hello";
字符指针:char * pname="hello";
区别:
字符指针仅仅存放"hello"这个的首地址,pname是
可以修改[可以指向的其它的位置].pname="teacher";
没有自己独立的分配单元,有安全隐患.
字符一维数组名是常值,不能修改,永远只能指向
数组的第一个元素.有自己独立的分配单元,很安全.
调试:char name[10]="世杰";
// cin>>name;cout<<name;
char *pname="学院";
pname=name;
cout<<name<<" "<<pname<<endl;
char s[]; char *s;
***:你遇到的字符串的所有操作,全部用库函数.
char s[]; char *s;
<1>strlen(s);//取串长返回值是整数
<2>strcpy(s1,s2);//把串2复制给串1
<3>strcmp(s1,s2);//比较两个串,相等返回0,不相等返
回数值s1>s2返回值>0,否则<0 s1="ABC";s2="BC"
<4>strcat(s1,s2);//把串s2追加到串s1的后面.
调试:char name[10]="世杰";
char *p="世杰学院";
cout<<strlen(p)<<endl;
strcpy(name,p);
cout<<name<<endl;
if(!strcmp(p,name))
cout<<"正在加载...";
else cout<<"密码错误...";
char s2[]="专修学院";
strcat(name,s2);
cout<<name<<endl;
<2>指针数组:数组的每一个元素都是指针.[多个类型相
同的指针变量]
如: int *p[5];//p是一个二级指针,指向p[0],p有5个
元素,每个元素是一个指向整形的指针.
访问方法:
*(p[0])=4;**p=4;//二级指针访问,一级指针间接访问.
p+=1;指向p1
****:难点及考点:
1、float *array1 [4];array1是指针数组,是一个二
级指针,+1向下移动一个位置。
2、 float (*array2)[4]:array2是一个行指针,指向
某行,该行有4个元素。[与二维数组名等价的指针]
***array2+1指向下一行,移动4个元素的位置。
in tb[40],*p=tb;
int a[2][5],(*p)[5]=a;
#include <iostream.h>
#include"fstream.h"
//----------------------------------------------
-----------------------------
#pragma argsused
int main(int argc, char* argv[])
{
ifstream in;
for(int i=0;i<argc;i++)
cout<<argv[i]<<endl;
in.open(argv[1]);
int a[5];
for(int i=1;i<=4;i++)
{
in>>a[i];
cout<<a[i]<<endl;
}
<3>指针的第二大作用:动态申请空间。
静态数组一定要预先分配空间,造成空间的利用率低。
int a[100];//栈分配,自动回收
new:动态申请,必须动态释放[堆分配,系统不会自动
收回]//malloc()
定义方法:
类型 *指针名=new 类型 ();//申请一个单元
类型 *指针名=new 类型[];//申请一片连续单元[数组]
如:
int *pa= new int (5);//一个单元
int *pb=new int [5];//5个单元 pb[5]
char name[10]="世杰";
char *pname=new char [strlen("世杰")] ;
strcpy(pname,"世杰");
delete:释放空间
(1)释放一个空间:delete pa;
(2)释放连续空间:delete []pb;
<4> 一、函数指针:指针指向函数。函数名就是一个指
针,指向为函数开辟空间的首地址。
例如:int max(int x,int y)
{ return x>y?x:y;}
定义方法:
int (*pmax)(int x,int y)=&max;//可以
pmax=max;//也可以
作用:可以通过函数指针来调用函数
max(a,b); (*pmax)(a,b);pmax(a,b);三种都可以
二、指针函数:函数的返回值是指针。
int* swap(int * x,int *y)
{
return ((*x>*y)?x:y);
}
调用方法:
int a=3,b=5;
cout<<(*swap(&a,&b))<<endl;;
<5>引用:***:唯一传地址的方式。
引用含义:取别名,不分配空间。传地址,但必须初
始化。
例如:int a=5;
int &b=a;
b=7;