概述
文章目录
- 一、指针相关概念
- 1. 地址与指针
- 2、变量与指针
- 3 、指针变量
- 4、指针自加自减运算
- 二、指针与数组
- 1、一维数组与指针
- 2 、二维数组与指针
- 3、字符串与指针
- 三、返回指针值的函数
一、指针相关概念
指针是C语言显著的优点之一,其使用起来十分灵活而且能提高某些程序的效率,但是如果使用不当则很容易造成系统错误。许多程序**“挂死”**往往都是错误地使用指针造成的。
1. 地址与指针
系统的内存就好比是带有编号的小房间,如果想使用内存就需要得到房间编号。图1定义了一个整型变量i,整型变量需要4个字节,所以编译器为变量i分配的编号为1000~1003。
什么是地址?
地址就是内存区中对每个字节的编号,如图1所示的1000、1001、1002和1003就是地址。为了进一步说明,来看图2。
图1:
如图2所示的1000、1004等就是内存单元的地址,而0、1就是内存单元的内容,换种说法就是基本整型变量i在内存中的地址从1000开始。因为基本整型占4个字节,所以变量j在内存中的起始地址为1004,变量i的内容是0。
图2:
那么指针又是什么呢?
这里仅将指针看作是内存中的一个地址,多数情况下,这个地址是内存中另一个变量的位置,如图3所示。
图3:
在程序中定义了一个变量,在进行编译时就会给该变量在内存中分配一个地址,通过访问这个地址可以找到所需的变量,这个变量的地址称为该变量的“指针”。图3所示的地址1000是变量i的指针。
2、变量与指针
变量的地址是变量和指针二者之间连接的纽带,如果一个变量包含了另一个变量的地址,则可以理解成第一个变量指向第二个变量。所谓“指向”就是通过地址来体现的。因为指针变量是指向一个变量的地址,所以将一个变量的地址值赋给这个指针变量后,这个指针变量就“指向”了该变量。例如,将变量i的地址存放到指针变量p中,p就指向i,其关系如图4所示。
图4:
在程序代码中是通过变量名对内存单元进行存取操作的,但是代码经过编译后已经将变量名转换为该变量在内存中的存放地址,对变量值的存取都是通过地址进行的。
3 、指针变量
由于通过地址能访问指定的内存存储单元,可以说地址“指向”该内存单元。地址可以形象地称为指针,意思是通过指针能找到内存单元。一个变量的地址称为该变量的指针。如果有一个变量专门用来存放另一个变量的地址,它就是指针变量。在C语言中有专门用来存放内存单元地址的变量类型,即指针类型。
下面将针对如何定义一个指针变量、如何为一个指针变量赋值及如何引用指针变量这3个方面加以介绍。
- (1)指针变量的一般形式如果有一个变量专门用来存放另一变量的地址,则它称为指针变量。图4所
示的p就是一个指针变量。如果一个变量包含指针(指针等同于一个变量的地址), 则必须对它进行说明。
定义指针变量的一般形式如下:
类型说明 * 变量名
其中,“*”
表示该变量是一个指针变量,变量名即为定义的指针变量名,类型
说明表示本指针变量所指向的变量的数据类型。
- (2)指针变量的赋值 指针变量同普通变量一样,使用之前不仅需要定义,而且必须赋予具体的值。
未经赋值的指针变量不能使用。给指针变量所赋的值与给其他变量所赋的值不同,
给指针变量的赋值只能赋予地址,而不能赋予任何其他数据,否则将引起错误。C语 言中提供了地址运算符“&”来表示变量的地址。
其一般形式如下:
& 变量名;
如&a表示变量a的地址,&b表示变量b的地址。给一个指针变量赋值可以有以下
两种方法。
(1)定义指针变量的同时就进行赋值,例如:
int a; int *p=&a;
(2)先定义指针变量之后再赋值,例如:
int a; int *p; p=&a;
**注意:**这两种赋值语句的区别,如果在定义完指针变量之后再赋值注意不要加“*”
。
- (3)指针变量的引用 引用指针变量是对变量进行间接访问的一种形式。对指针变量的引用形式如下:
*指针变量
其含义是引用指针变量所指向的值。
- (4)“&”和“*”运算符
在前面介绍指针变量的过程中,用到了“&”和“*”两个运算符,运算符“&”是一个返回操作数地址的单目运算符,叫作取地址运算符,例如:
p=&i;
就是将变量i的内存地址赋给p,这个地址是该变量在计算机内部的存储位置。
运算符“*”
是单目运算符,叫作指针运算符,作用是返回指定地址内变量的
值。如前面提到过p中装有变量i的内存地址,则:
q=*p;
就是将变量i的值赋给q,假如变量i的值是5,则q的值也是5。
- (5)“&”和“&”的区别
如果有如下语句:
int a; p=&a;
下面通过以上两条语句来分析“&”和“&”的区别,**“&”和“”的运算符优先级别相同,按自右而左的方向结合**。因此“&p”先进行“”运算,“p”相当于变量a;再进行“&”运算,“&p”就相当于取变量a的地址。“&a”先进
行“&”运算,“&a”就是取变量a的地址,然后执行“”运算,“*&a”就相当于取变量a所在地址的值,实际就是变量a。
#include<stdio.h>
int main()
{
int *p;
int a ;
printf("请输入a的值:n");
scanf("%d",&a);
p = &a; /*把a的地址赋值给p*/
printf("%pn",&*p);
printf("%pn",&a);
return 0;
}
输出结果:
4、指针自加自减运算
指针的自加自减运算不同于普通变量的自加自减运算,也就是说,并非简单地加1减1。
基本整型变量i在内存中占4个字节,指针p是指向变量i的地址的,这里的p++不是简单地在地址上加1,而是指向下一个存放基本整型数的地址。
二、指针与数组
系统需要提供一段连续的内存来存储数组中的各元素,内存都有地址,指针变量就是存放地址的变量,如果把数组的地址赋给指针变量,就可以通过指针变量来引用数组。
下面就介绍如何用指针来引用一维数组及二维数组元素。
1、一维数组与指针
当定义一个一维数组时,系统会在内存中为该数组分配一个存储空间,其数组的名称就是数组在内存中的首地址。若再定义一个指针变量,并将数组的首地址传给指针变量,则该指针就指向了这个一维数组。
例如:
int *p,a[10]; p=a;
这里a是数组名,也就是数组的首地址,将它赋给指针变量p,也就是将数组a的
首地址赋给p。也可以写成如下形式:
int *p,a[10]; p=&a[0];
上面的语句是将数组a中的首个元素的地址赋给指针变量p。由于a[0]的地址就是数组的首地址,因此两条赋值操作效果完全相同。
2 、二维数组与指针
定义一个3行5列的二维数组,其在内存中的存储形式如下图所示。
从上图中可以看到几种表示二维数组中元素地址的方法,下面逐一进行介绍。
- **&a[0][0]**既可以看作数组0行0列的首地址,也可以看作二维数组的首地址。
- **&a[m][n]**就是第m行n列元素的地址。a[0]+n表示第0行第n个元素的地址。
利用指针对二维数组进行输入和输出:
#include<stdio.h>
int main()
{
int i,j;
int array[2][3];
printf("请输入数据:n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("array[%d][%d]=",i,j);
scanf("%d",array[0]+j);
}
}
printf("输出二维数组:n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("array[%d][%d]=%d ",i,j,*(array[0]+j));
}
putchar('n');
}
return 0;
}
输出结果:
在运行结果仍相同的前提下,还可将程序改写成如下形式:
#include<stdio.h>
int main()
{
int i,j,*p;
int array[2][3];
p = array[0]; /*p为第一个元素的地址*/
printf("请输入数据:n");
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("array[%d][%d]=",i,j);
scanf("%d",p++);
}
}
printf("输出二维数组:n");
p = array[0]; /*p为第一个元素的地址*/
for(i=0;i<2;i++)
{
for(j=0;j<3;j++)
{
printf("array[%d][%d]=%d ",i,j,*(p++));
}
putchar('n');
}
return 0;
}
输出结果:
3、字符串与指针
可以通过两种方式访问一个字符串,第一种方式就是前面讲过的使用字符数组来存放一个字符串,从而实现对字符串的操作;另一种方式就是下面将要介绍的使用字符指针指向一个字符串,此时可不定义数组。
字符型指针应用:
#include<stdio.h>
int main()
{
char *string = "I wil be successful";
printf("%sn",string);
return 0;
}
输出结果:
上例中定义了字符型指针变量string,用字符串常量“I wil be successful”为
其赋初值。注意,这里并不是把“I wil be successful”中的所有字符存放到string中,只是把该字符串中的第一个字符的地址赋给指针变量string。
示。
语句:
char *string="I wil be successful";
等价于下面两条语句:
char *string; string="I wil be successful";
三、返回指针值的函数
指针变量也可以指向一个函数。函数在编译时会被分配一个入口地址,该入口地址就称为函数的指针。可以用一个指针变量指向函数,然后通过该指针变量调用此函数。
一个函数可以带回一个整型值、字符值、实型值等,也可以带回指针型的数据,即地址。其概念与之前介绍的类似,只是带回的值的类型是指针类型而已。返回指针值的函数简称为指针函数。
定义指针函数的一般形式如下:
类型名 *函数名(参数表列);
例如:
int *fun(int x,int y)
fun是函数名,调用它以后能得到一个指向整型数据的指针。x和y是函数fun的形式参数,这两个参数均为基本整型。这个函数的函数名前面有一个“*”
,表示此函数是指针型函数,类型说明是int表示返回的指针指向整型变量。
利用返回指针值的函数求长方形的面积:
#include<stdio.h>
int *Area(int a,int b)
{
int *p,iPer=0;
p = &iPer;
iPer = (a+b)*2;
return p;
}
int main()
{
int length = 0;
int width = 0;
printf("请输入length的值:n");
scanf("%d",&length);
printf("请输入width的值:n");
scanf("%d",&width);
printf("长方形的面积是:%dn",*Area(length,width));
return 0;
}
输出结果:
最后
以上就是凶狠音响为你收集整理的c语言的指针总结一、指针相关概念二、指针与数组的全部内容,希望文章能够帮你解决c语言的指针总结一、指针相关概念二、指针与数组所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复