指针与数组(第一次写博,写些自己总结的东西)
2010-11-11 23:25
267 查看
数组是c语言的核心,是c语言非常独特的地方,其中有很广泛用途之一的就是数组与指针,数组与指针中的各种*,&的运算经常使很多童鞋甚是烦恼,下面就让本人来讲解一些我自己总结的东西(我个人认为比书上写的好理解。。)。
1,首先是比较基本的指向数组的指针,和通过指针指针引用数组元素,这是两个是非常基础的内容,
for example: int a[10],*p;
p=&a[0];
这样就把a数组的0号元素a[0]的地址付给了指针变量p,此时p指向了a[0],
下面三行都是是等价的:int *p=&a[0];
int *p;p=&a[0];
int *p=*a;
通过指针引用数组元素的形式:for example:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},*p;
for(p=a;p<a+10;p++)
printf("%d",p);
return 0;
}
我们要理解,一个数组的数组名其实就是指针,两者就是相同的。。。。
2,下面,来说比较麻烦一些的用数组名作函数参数
我们可以分出以下四类:1形参和实参都是数组名2实参用数组名形参用指针变量3实参形参都用指针变量4实参用指针变量形参用数组名。
1例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i;
void f(int a[],int n);
f(a,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
printf("/n");
return 0;
}
void f(int a[],int n)
{
int i,j,m=(n-1)/2,temp;
for(i=0;i<=m;i++)
{
j=n-1-i;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
return ;
}
2例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i;
void f(int *x,int n);
f(a,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}
void f(int *x,int n)
{
int *i,*j,*p,temp,m=(n-1)/2;
for(i=x,j=n-1+x,p=m+x;i<=p;i++,j--)
{
temp=*i;
*i=*j;
*j=temp;
}
return ;
}
3例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i,*p=a;
void f(int *x,int n);
f(p,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}
void f(int *x,int n)
{
int *i,*j,*p,m=(n-1)/2,temp;
for(i=x,j=n-1+x,p=m+x;i<=p;i++,j--)
{
temp=*i;
*i=*j;
*j=temp;
}
}
4例:
#include<stdio.h>
int main()
{
void sort(int x[],int n);
int *p,i,a[10];
p=a;
for(i=0;i<10;i++)
scanf("%d",a[i]);
p=a;
sort(p,10)
for(p=a,i=0;i<10;i++)
printf("%d",p++);
}
void sort(int x[],int n)
{
int ,i,j,k,t;
for(i=0;i<n;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(x[i]>x[k])k=j;
if(k!=i)
{
t=x[i];
x[i]=x[k];
x[k]=t;
}
}
}
我们来观察以下规律,从例1到例4,若形参变量相同(这里指都是数组名或都是指针变量,下同),则定义函数的形式相同(指都是通过定义数组形式或是都是定义指针变量形式),若实参变量相同,则输出形式可以相同,但也可以不相同,比如:实参变量都是指针变量,那么输出的形式可以是用数组元素,或用指针变量输出,若形参为指针变量,那么定义函数时也用指针变量,若形参为数组名,那么定义函数时,也用数组名来,总之,形参和定义函数形式有关。
3,多维数组与指针:
设a为一个二维数组的数组名,那么a代表的是a[0]的地址,即,二维数组a第0行的地址,而a[0]代表二维数组a[0][0]的地址,a[0],a[1],a[2]...............既是一维数组名,又代表a[0][0],a[1][0],a[2][0].....的地址,即&a[0][0],&a[1][0],&a[2][0]......,而第0行第1列的元素的地址应该用a[0]+1表示,也等价于*(a+0)+1,同理第一行第二个元素....说到这里就不得不说一下*,&这两个运算符了,&叫做取地址运算符,*叫做指针运算符(或称”间接访问“运算符),取其指向的内容,*,&的优先级别相同,但按自左而右的方向结合,那么*(a+0),&a[i],*(*(a+0)+1)....又是代表什么呢?
下面我来说一下我自己对*,&的理解:
*加上多维中其中一维的地址,那么它就表示紧接着下一维的地址或元素的地址,
*加上数组中一个元素的地址,那么它就表示数组中元素的值,
&加上数组中其中一维的的地址,那么它就表示与它相邻的上一维的地址,
&加数组中元素的地址,那么它就表示它上一维的地址,
&加上数组中元素(注意不是地址),那么它就表示此元素的地址,
&加上数组其中的一维(不是地址如&a[0]),那么它就代表这一维的首地址,
总结一下,如果把*理解为向正方向运算,那么&就可以理解为向反方向运算,(理解,有助于记忆),即,*进&退。
如此来说:
a 是二维数组名,指向一维数组a[0],即0行首地址,
a[0],*(a+0),*a 根据上述,a是0行首地址,那么加上*,就代表0行0列元素的地址,
a+1,&a[1] 根据上述,其代表第一行的首地址,
a[1],*(a+1) 根据上述,(a+1)代表第1行的首地址,那么*(a+1)就”进“一下,代表1行0列元素的地址,
a[1]+2,*(a+1)+2,&a[1][2] 代表1行2列元素的地址,其中,&a[1][2],a[1][2]代表1行2列的元素,根据上述,再加上&,就要退
一步,变为1行2列元素的地址,
*(a[1]+2),*(*(a+1)+2),a[1][2] 有上述可知,代表第一行第二列元素的值。
1,首先是比较基本的指向数组的指针,和通过指针指针引用数组元素,这是两个是非常基础的内容,
for example: int a[10],*p;
p=&a[0];
这样就把a数组的0号元素a[0]的地址付给了指针变量p,此时p指向了a[0],
下面三行都是是等价的:int *p=&a[0];
int *p;p=&a[0];
int *p=*a;
通过指针引用数组元素的形式:for example:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},*p;
for(p=a;p<a+10;p++)
printf("%d",p);
return 0;
}
我们要理解,一个数组的数组名其实就是指针,两者就是相同的。。。。
2,下面,来说比较麻烦一些的用数组名作函数参数
我们可以分出以下四类:1形参和实参都是数组名2实参用数组名形参用指针变量3实参形参都用指针变量4实参用指针变量形参用数组名。
1例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i;
void f(int a[],int n);
f(a,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
printf("/n");
return 0;
}
void f(int a[],int n)
{
int i,j,m=(n-1)/2,temp;
for(i=0;i<=m;i++)
{
j=n-1-i;
temp=a[i];
a[i]=a[j];
a[j]=temp;
}
return ;
}
2例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i;
void f(int *x,int n);
f(a,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}
void f(int *x,int n)
{
int *i,*j,*p,temp,m=(n-1)/2;
for(i=x,j=n-1+x,p=m+x;i<=p;i++,j--)
{
temp=*i;
*i=*j;
*j=temp;
}
return ;
}
3例:
#include<stdio.h>
int main()
{
int a[5]={1,2,3,4,5},i,*p=a;
void f(int *x,int n);
f(p,5);
for(i=0;i<5;i++)
printf("%d",a[i]);
return 0;
}
void f(int *x,int n)
{
int *i,*j,*p,m=(n-1)/2,temp;
for(i=x,j=n-1+x,p=m+x;i<=p;i++,j--)
{
temp=*i;
*i=*j;
*j=temp;
}
}
4例:
#include<stdio.h>
int main()
{
void sort(int x[],int n);
int *p,i,a[10];
p=a;
for(i=0;i<10;i++)
scanf("%d",a[i]);
p=a;
sort(p,10)
for(p=a,i=0;i<10;i++)
printf("%d",p++);
}
void sort(int x[],int n)
{
int ,i,j,k,t;
for(i=0;i<n;i++)
{
k=i;
for(j=i+1;j<n;j++)
if(x[i]>x[k])k=j;
if(k!=i)
{
t=x[i];
x[i]=x[k];
x[k]=t;
}
}
}
我们来观察以下规律,从例1到例4,若形参变量相同(这里指都是数组名或都是指针变量,下同),则定义函数的形式相同(指都是通过定义数组形式或是都是定义指针变量形式),若实参变量相同,则输出形式可以相同,但也可以不相同,比如:实参变量都是指针变量,那么输出的形式可以是用数组元素,或用指针变量输出,若形参为指针变量,那么定义函数时也用指针变量,若形参为数组名,那么定义函数时,也用数组名来,总之,形参和定义函数形式有关。
3,多维数组与指针:
设a为一个二维数组的数组名,那么a代表的是a[0]的地址,即,二维数组a第0行的地址,而a[0]代表二维数组a[0][0]的地址,a[0],a[1],a[2]...............既是一维数组名,又代表a[0][0],a[1][0],a[2][0].....的地址,即&a[0][0],&a[1][0],&a[2][0]......,而第0行第1列的元素的地址应该用a[0]+1表示,也等价于*(a+0)+1,同理第一行第二个元素....说到这里就不得不说一下*,&这两个运算符了,&叫做取地址运算符,*叫做指针运算符(或称”间接访问“运算符),取其指向的内容,*,&的优先级别相同,但按自左而右的方向结合,那么*(a+0),&a[i],*(*(a+0)+1)....又是代表什么呢?
下面我来说一下我自己对*,&的理解:
*加上多维中其中一维的地址,那么它就表示紧接着下一维的地址或元素的地址,
*加上数组中一个元素的地址,那么它就表示数组中元素的值,
&加上数组中其中一维的的地址,那么它就表示与它相邻的上一维的地址,
&加数组中元素的地址,那么它就表示它上一维的地址,
&加上数组中元素(注意不是地址),那么它就表示此元素的地址,
&加上数组其中的一维(不是地址如&a[0]),那么它就代表这一维的首地址,
总结一下,如果把*理解为向正方向运算,那么&就可以理解为向反方向运算,(理解,有助于记忆),即,*进&退。
如此来说:
a 是二维数组名,指向一维数组a[0],即0行首地址,
a[0],*(a+0),*a 根据上述,a是0行首地址,那么加上*,就代表0行0列元素的地址,
a+1,&a[1] 根据上述,其代表第一行的首地址,
a[1],*(a+1) 根据上述,(a+1)代表第1行的首地址,那么*(a+1)就”进“一下,代表1行0列元素的地址,
a[1]+2,*(a+1)+2,&a[1][2] 代表1行2列元素的地址,其中,&a[1][2],a[1][2]代表1行2列的元素,根据上述,再加上&,就要退
一步,变为1行2列元素的地址,
*(a[1]+2),*(*(a+1)+2),a[1][2] 有上述可知,代表第一行第二列元素的值。
相关文章推荐
- C 总结——指针和数组是不同的两种东西
- 内存的堆分配和栈分配 & 字符数组,字符指针,Sizeof总结
- 算是自己的第一次总结吧
- 指针数组--------概念、实用、例子(学得东西忘光了 是时候写写了!)
- 自己关于指针在函数中使用的理解和总结
- 指针和数组--小总结
- 字符数组,字符指针,sizeof,strlen总结
- 总结:数组名和指针完全是两码事
- 终于决定对自己学的东西做一个总结
- 字符数组,字符指针,sizeof,strlen总结
- 自己总结点oracle的东西
- 第一次学习写博客。有些激动,希望自己的总结能够帮助到别人,也希望自己日后总结时能够做到提醒自己。
- C++ 数组和指针学习总结
- 内存的堆分配和栈分配 & 字符数组,字符指针,Sizeof总结
- 对指针、数组的总结
- 指针学习总结(数组指针,指针数组)
- PostgreSQL9.3:JSON 功能增强 根据PQ中文论坛francs 给出的东西结合自己的摸索总结下
- 指针与数组名异同比较总结
- C语言中指针和数组的总结
- 指针数组的使用总结