c笔记之指针.docx

上传人:b****3 文档编号:24719150 上传时间:2023-05-31 格式:DOCX 页数:33 大小:24.87KB
下载 相关 举报
c笔记之指针.docx_第1页
第1页 / 共33页
c笔记之指针.docx_第2页
第2页 / 共33页
c笔记之指针.docx_第3页
第3页 / 共33页
c笔记之指针.docx_第4页
第4页 / 共33页
c笔记之指针.docx_第5页
第5页 / 共33页
点击查看更多>>
下载资源
资源描述

c笔记之指针.docx

《c笔记之指针.docx》由会员分享,可在线阅读,更多相关《c笔记之指针.docx(33页珍藏版)》请在冰豆网上搜索。

c笔记之指针.docx

c笔记之指针

指针

指针乃地址也。

变量的地址:

系统为变量分配的内存单元的地址(一个无符号的整型数)

变量--存储内容:

数据值

空间大小:

数据类型

空间位置:

地址

生存周期:

存储类别

变量的访问方式:

直接访问

间接访问

指针变量:

是存放地址的变量,该变量是一个地址(无符号的整型数)

eg:

p为指针变量,它存放整型变量a的首地址

则,指针变量p指向整型变量a

指针变量的定义和引用

1.定义方法

类型符*指针变量名

eg:

int*p1,*p2;

char*ps;

float*pf1,pf2;

指针变量的类型--〉是所指向的内存中存放的数据的类型。

2.赋值

指针变量的值为地址,是个无符号整数。

但不能直接将整型常量赋给指针变量。

1.用变量的地址给指针变量赋值(求地址运算符&)

eg:

inta,b,*p;

p=&a;

变量的类型必须与指针变量的类型相同。

p=123;×p指向地址,不是常量或变量

p=&123;×123是常量,常量没有存储空间,就不可能取地址

*p=123;×不知道指针地址,怎么确定的指针内容?

2.用相同类型的指针变量赋值

eg:

inta;

int*p1,*p2;

p1=&a;

p2=p1;

若不赋值,则指针变量的值是随机的。

---危险(死机...)

3.赋空值NULL

eg:

int*p;

p=NULL;或p=0;

4.指针变量的初始化方法

1.赋空值NULL

eg:

int*p1=NULL;

2.用已定义的变量的地址

eg:

floata;

float*p2=&a;

charch,*p3=&ch;

3.应用

1.两个有关的运算符:

*、&

形式:

&任意变量-->取地址运算符

*指针变量-->指针运算符

含义:

&a表示变量a所占据的内存空间的首地址--一般变量

*p表示指针变量p所指向的内存中的数据--指针变量

inta,*p;p=&a;-->*p相当于a

应用:

通过指针变量访问所指变量(通过指针变量间接访问某一个变量)

将指针变量指向被访问的变量

eg:

inta=5,*p,b;

p=&a;

访问所指变量

取内容:

b=*p;-->*p相当于=a

b=*p;//间接访问<==>b=a;//直接访问

printf("%d\n",*p);

存内容:

*p=100;

注意:

*p若出现在“=”的右边或其他表达式中,则为取内容。

*p若出现在“=”的左边,则为存内容。

注意区分:

intb,*p1,*p2=&b;

1.p1=p2;与*p1=*p2;

p1=p2;//把p2的地址赋给p1,p1和p2的地址都指向了b。

*p1=*p2;//把p2所指向的内容放到p1内容里,p1和p2得内容都等于b的内容(b的值)

2.(*p1)++;与*p1++;

(*p1)++;//*p1<==>a,即(*p1)++;<==>a++;

*p1++;//先得到*p1的内容,*p1++;<==>*(p1++);

3.&*p等价于p

*&a等价于a

eg1:

#include

main()

{

inta=5,b=3;

int*p;

p=&a;

b=*p+5;

printf("%d\n",b);//b=10;

*p=4;

printf("%d,%d\n",a,*p);//a=4;*p=4;

}

eg2:

同指针变量来交换两个单元中的内容。

#include

main()

{

inta,b,c,*p1=&a,*p2=&b;

scanf("%d%d",p1,p2);

c=*p1;*p1=*p2;*p2=c;

printf("a=%d,b=%d\n",*p1,*p2);

}

2.运算规则

*、&:

优先级相同,且右结合

与++、--、!

等单目运算符的优先级相同

高于算术运算符*、/、%

eg1:

#include

main()

{

inta=2,*p=&a,*q=&a;//*p=&a--〉已定义的变量的地址为指针变量赋值

printf("*p++=%d,*(q++)=%d\n",*p++,*(q++));

//*p++=2,*(q++)=2

//*p++,先运算*p,再p++。

*p在左边,为取内容

//*(q++),地址相加(q++=(&a)++)而不是a++。

先运算q,再q++

//指针变量里的值相加,使指针指向了其他的变量

p=&a;

q=&a;

printf("*p=%d,(*q)++=%d\n",*p,(*q)++);

//*p=3,(*q)++=2;

//(*q)++,所指向的变量的值相加,即a++

}

eg2:

写出下面各表达式的结果,并找出具有等价关系的对子。

eg:

inta=5,*p=&a;//*p=&a:

已定义的变量的地址为指针变量赋值*p指向a-->*p=a

&*p=&a;//p=&a;*p=a;&*p=&a=p;

*&a=a;//p=&a;*p=a;*&a=*p=a;

(*p)++=a++;

*p++=*(p++);//*(p++)=*((&a)++)

eg1:

#include

main()

{

inta,b,c;

int*pa,*pb,*pc;

pa=&a,pb=&b,pc=&c;

scanf("%d%d",pa,pb);//*pa=3,*pb=4

//scanf("%d%d",&a,&b);

printf("&a=%d,&b=%d\n",pa,pb);//地址&a=2293408,&b=2293404

printf("a=%d,b=%d\n",*pa,*pb);//数据a=3,b=4

c=a+b;printf("c=%d\n",*pc);//a=3,b=4,c=3+4=7

*pc=a+*pb;printf("c=%d\n",c);//a=3,b=4,c=3+4=7

c=*pa**pb;printf("c=%d\n",c);//a=3,b=4,c=3*4=12

c=++*pa+(*pb)++;printf("c=%d\n",c);//a=4,b=4,c=4+4=8,b=5

c=(*pa)+++*pb;printf("c=%d\n",c);//a=4,b=5,c=4+5=9,a=5

printf("a=%d,b=%d\n",a,b);//a=5,b=5

}

eg2:

交换两个数a、b的值。

#include

main()

{

//inta=5,b=8;

//intt;

//printf("a=%d,b=%d\n",a,b);

//

//t=a;

//a=b;

//b=t;

//printf("a=%d,b=%d\n",a,b);

inta=5,b=8;

int*pa=&a,*pb=&b;//已定义的变量的地址(&a/&b)为指针变量(*pa/*pb)赋值

intt;

printf("a=%d,b=%d\n",a,b);

t=*pa;//*pa:

pa所指向的单元的内容--〉a

*pa=*pb;

*pb=t;

printf("a=%d,b=%d\n",a,b);

}

4.指针变量作函数参数

eg1:

编写一个函数实现两个数的交换。

////×子函数交换,主函数未交换。

//#include存储单元

//voidswap(intx,inty)内容单元名存储单元(假设位置)

//{3a2A02

//intt;//局部变量5b2C16

//t=x;x=y;y=t;//子函数交换变量拷贝赋值

//}3x(a)4012

//main()5y(b)4016

//{值交换后-->存储单元不一样,未完成交换

//inta=3,b=5;5x4012

//swap(a,b);3y4016

//printf("%d%d\n",a,b);//主函数未交换

//}

√指针变量间接访问

#include

voidswap(int*x,int*y)//使用指针变量存储单元

{内容单元名存储单元(假设)

intt;3a2A02

t=*x;*x=*y;*y=t;//地址交换5b2C16

//t=*x;-->*x所指向的单元内容赋值给t。

地址赋值

}2A02x(&a)4012

main()2C16y(&b)4016

{内容交换后

inta=3,b=5;5*x(a)2A02

swap(&a,&b);//地址值3*y(b)2C16

//实参传递地址值,形参一定是指针变量

printf("%d%d\n",a,b);

}

////×地址交换,内容没变。

//#include

//voidswap(int*x,int*y)//定义指针变量存储单元

//{内容单元名存储单元(假设)

//int*t;//定义局部指针变量3a2A02[2C16]

//t=x;x=y;y=t;//地址交换5b2C16[2A02]

//}地址赋值↑

//main()2A02x(&a)4012↑

//{2C16y(&b)4016↑

//inta=3,b=5;地址交换后-->a和b的地址交换了,内容不变。

//swap(&a,&b);//地址值2C16x(&a)4012

//printf("%d%d\n",a,b);2A02y(&a)4016

//}

////×危险错误:

*t中地址不确定,不可存放内容。

//#include

//voidswap(int*x,int*y)//定义指针变量

//{

//int*t;//定义局部指针变量

////intw;t=&w;//给*t指定地址,则程序正确。

//*t=*x;*x=*y;*y=*t;

////*t中地址(t)随机,则*t所指向的单元内容存放位置不得当。

//}

//main()

//{

//inta=3,b=5;

//swap(&a,&b);//地址值

//printf("%d%d\n",a,b);

//}

eg2:

输入a,b,c三个数,按大小顺序输出。

-->四个数排序输出,需要6次两两比较交换。

#include

voidswap(int*x,int*y)//定义指针变量

{

intt;//定义局部指针变量

t=*x;*x=*y;*y=t;

}

main()

{

inta,b,c;

printf("enterdataa,b,c:

");

scanf("%d%d%d",&a,&b,&c);

if(a

if(a

if(b

printf("%d%d%d\n",a,b,c);

}

指针和数组

1.一维数组与指针

1.数组是连续存放的若干个元素的集合。

2.数组名就是指向此数组第1个元素的指针(首地址)

eg:

inta[10],*p=a;则p=a;等价于p=&a[0];

3.某一元素的地址:

p=&a[i];

用指针引用该元素:

*p=a[i];//a[i]:

a数组中下标为i的元素

4.数组元素的下标在内部实现时,统一按“基地址+位移”的方式处理。

a:

a数组中的首地址=&a[0];

a+1:

a数组中下标为1的元素地址=&a[1];

a+i:

a数组中下标为i的元素地址=&a[i];

位移eg:

a数组是int整型,占用两个字节。

假设a数组首地址a=3A00;

则a[1]=a+1*2=3A02;

a[i]=a+i*2;

故表示数组元素的地址可以用:

&a[i]、p+i、a+i(p=a)

表示数组元素的内容可以用:

下标表示法a[i]

指针表示法*(p+i)、*(a+i)

5.数组名a(数组的指针)与指向数组首地址的指针变量p性质不同。

(a不是变量,它是一个常量,不会改变值。

eg1:

#include

main()

{

inta=3,b=5;

int*p=&a;//p=&a;

printf("*p=%d\n",*p);//*p=3

*p=4;//a=*p;

p=&b;

printf("*p=%d\n",*p);//*p=5

*p=6;//b=*p;

printf("a=%d,b=%d\n",a,b);//a=4,b=6

}

eg2:

1.#include

main()

{

inti,a[5];

int*p;

for(i=0;i<5;i++)

{

p=&a[i];x

a[i]=i;//*p=a[i]=i;

printf("a[%d]=*p=%3d\n",i,*p);

}

printf("\n");

}

/*

a[0]=*p=0

a[1]=*p=1

a[2]=*p=2

a[3]=*p=3

a[4]=*p=4

--------------------------------

*/

2.#include

main()

{

inti,a[5];

int*p=a;//p=a;或p=&a[0];

//i++;指i单元的内容+1

//p++;指地址移到下一个元素(下一个元素的长度与数据的类型有关系)

for(i=0;i<5;i++,p++)

{

*p=i;//a[i]=i;

printf("a[%d]=*p=%3d\n",i,*p);

}

printf("\n");

}

/*

a[0]=*p=0

a[1]=*p=1

a[2]=*p=2

a[3]=*p=3

a[4]=*p=4

--------------------------------

*/

6.数组指针(a)、指针变量(p)与数组元素(a[i])之间的关系:

设有inta[10],*p=a;则

地址关系

指针变量p数组指针a数组元素

pa&a[0]

p+1a+1&a[1]

p+2a+2&a[2]

...

p+ia+i&a[i]

...

p+9a+9&a[9]

内容关系

指针变量p数组指针a数组元素

*p*aa[0]

*(p+1)*(a+1)a[1]

*(p+2)*(a+2)a[2]

...

*(p+i)*(a+i)a[i]

...

*(p+9)*(a+9)a[9]

eg:

数组的使用形式

#include

main()

{

inti,a[5],*p=a;

printf("input5numbers:

\n");

for(i=0;i<5;i++)

//scanf("%d",&a[i]);//数组的使用形式

//scanf("%d",a+i);

scanf("%d",p+i);

printf("outputthesenumbers:

\n");

for(i=0;i<5;i++)printf("%d",a[i]);//a[i]可换为*(a+i)或*(p+i)

printf("\n");

}

2.指针的运算(指向数字的指针p的运算)

1.赋值运算-->指针类型相同。

eg:

p=&x;//将x的地址赋给p

p=a;//将a数组的首地址赋给p

p=NULL;

2.加减运算-->只能用于数组元素的引用,注意下标的有效范围。

即加减运算必须在连续空间上的加减(移动)才有意义。

用法:

指针+/-整数

eg:

a+i-->a是一个数组名,表示地址的首地址,只能加不能减。

p+/-i-->p是一个指针变量,指向某一个数组元素,可进行加减。

p-q;//p和q都是指向同一个连续存储的空间(相减得到相隔两个元素的个数)

3.两指针的相减运算:

求两地址的间距-->两个指针的类型相同,并指向同一连续的存储区域。

用法:

指针-指针

eg:

p-a-->a为数组首地址保持不变,p可以移动(求这个地址到首地址跟了几个元素)

4.移动指针(++、--)-->对数组名(常量)/简单变量不能实施该运算。

eg:

p++;//后移p=p+1;要求p为变量(指针变量),不能是常量(数组名)。

p--;//前移

5.比较运算(p和q都是指向同一个连续存储的空间)

比较两个元素相隔的个数

用法:

指针运算符指针

eg:

p

地址

比较:

字符量根据ascii码;

数值量根据数值大小;

指针变量根据地址大小

2~5运算通常用于指向数组的指针[连续空间的指针]

eg:

将数组a的数据复制到数组b中并输出出来。

//数组下标的方法

#include

#defineM7

main()

{

inti,a[M]={23,15,50,3,21,20,35};

intb[M];

for(i=0;i

printf("outputthesenumbers:

\n");

for(i=0;i

printf("\n");

}

//指针的方法

#include

#defineM7

main()

{

inti,a[M]={23,15,50,3,21,20,35};

intb[M];

//p指向a的首地址&a[0];q指向b的首地址&b[0]

int*p=a,*q=b;

for(i=0;i

{

//*q=*p;//将p地址所指向的内容赋给q地址

//q++;//地址指针+1

//p++;

//将p地址所指向的内容赋给q地址,然后p、q后移

*q++=*p++;

}

printf("outputthesenumbers:

\n");

//for(i=0;i

q=b;//将q指针重新指向b数组的首地址

for(i=0;i

printf("\n");

}

3.数组的指针与函数参数

数组作为函数参数,实参和形参的对应关系可归纳以下四种情况:

①形参是数组x[];实参是数组名a

intf(intx[],intn)

{}

main()

{

inta[10];

...

f(a,10);

...

}

②形参是指针变量*x;实参是数组名a---常用形式

intf(int*x,intn)

{}

main()

{

inta[10];

...

f(a,10);

...

}

③形参是指针变量*x;实参是指针变量p,指向数组a的首地址---常用形式

传进去地址,也用指针接收

intf(int*x,intn)

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 表格模板 > 调查报告

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1