您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
043第八章 指针03(新版) 数组与指针
发布时间:2021-05-03 12:42:33编辑:雪饮阅读()
使用取值运算符进行数组的遍历
#include <stdio.h>
int main()
{
int a[10];
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
printf("\n");
for(i=0;i<10;i++){
printf("%d",*(a+i));
}
}
编译并运行
D:\cproject>gcc main.c -o m
D:\cproject>m.exe
1
2
3
4
5
6
7
8
9
0
1234567890
在这里对a+i进行取值,因为用数组名就相当于数组的第一个元素的地址,所以a+i就是数组元素地址不断向后进行指针的移动,每移动一个单位就是该数组基类型的大小,例如这里数组的基类型是int,所以这里每移动一个单位的大小就是int的大小。
那么下面的这种遍历方式和上面的方式是等同的:
#include <stdio.h>
int main()
{
int a[10];
int i;
int *p;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
printf("\n");
for(p=a;p<a+10;p++){
printf("%d",*p);
}
}
同样编译并运行,没有问题
D:\cproject>gcc main.c -o m
D:\cproject>m.exe
1
2
3
4
5
6
7
8
9
0
1234567890
将数组a中n个整数按相反顺序存放
实现此算法,可以用两种方法,一种是通过数组名:
#include <stdio.h>
/*形参x是数组名*/
void reverse(int x[],int n);
void main()
{
int i, a[10] = {3, 7, 9, 11, 0, 6, 7, 5, 4, 2};
printf("The original array:\n");
for( i=0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
//作用使得数组重新倒序排放
reverse(a, 10);
printf("The array has been inverted:\n");
for( i=0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
/*形参x是数组名*/
void reverse(int x[], int n)
{
int temp, i, j, m;
m = (n-1)/2;
/*
对n个元素进行翻转,则每次求一个中间索引(n-1)/2,并结合i<=m则会有可能会导致左边数量全部翻转完成后,右边可能会多余一个数字需要翻转
因为这里直接相除取整,默认是向下取整,那么多余的那一个数字就可以不用翻转了,不用管是没有问题的
因为如果你要处理右边多余的这个数(从右边开始遍历),则会导致右边最左边的数又没有可以翻转的了
所以没有完美的方案,只能取其中一个方案
*/
for( i=0; i <= m; i++)
{
/*
j指向对应的元素,比如第一个数时,这里i为0,对应就是数组中最后一个元素,即n-1-0即为n-1,
那么同样的第二个元素对应的就是倒数第二个,第n个元素就是倒数第n个,因为索引从0开始,所以减1是必要的
*/
j = n-1-i;
temp = x[i];
x[i] = x[j];
x[j] = temp;
}
}
D:\cproject>gcc main.c -o m
D:\cproject>m.exe
The original array:
3 7 9 11 0 6 7 5 4 2
The array has been inverted:
2 4 5 7 6 0 11 9 7 3
实现方法二,用指针:
#include <stdio.h>
void reserve(int *x, int n); /*形参x为指针变量*/
void main()
{
int i, a[10] = {3, 7, 9, 11, 0, 6, 7, 5, 4, 2};
printf("The original array:\n");
for( i=0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
reserve(a, 10);
printf("The array has benn inverted:\n");
for( i=0; i < 10; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
void reserve(int *x, int n) /*形参x为指针变量*/
{
int *p, temp, *i, *j, m;
m = (n-1)/2;
i = x; //i指向数组的第一个元素
j = x-1+n; //j指向的是数组的最后一个元素(当然x+n-1更好理解,我个人认为)
p = x+m; //指向中间,配对……
/*
从第一个开始向中间数进行遍历,这里和i++和j--的算法比较妙
i++是正向,则每次获取的是正向指针,而同时j++获取的是反向
由于i最大只能是中间值,所以只要左边每次的i的地址和右边每次的j的地址相交换,则就实现了翻转,可能会有右边的最左侧一个数字无法翻转
*/
for( ; i <= p; i++, j--)
{
temp = *i;
*i = *j;
*j = temp;
}
}
D:\cproject>gcc main.c -o m
D:\cproject>m.exe
The original array:
3 7 9 11 0 6 7 5 4 2
The array has benn inverted:
2 4 5 7 6 0 11 9 7 3
以上两个方法都可以,不过对于第一个方法中,每次翻转结束这里要纠正下,它同样是有可能造成右边的最左侧那个数没有办法翻转,那么从右边进行遍历,同样的会导致根据循环的最值条件,应该也是可能导致右边最左侧,或者左边最右侧无法被翻转,这个具体要自己空间想象下,不好描述。
关键字词:指针,数组,翻转