用指针访问一维数组


顺序查找

  • 要求用指针实现:在整数集合r中顺序查找与给定值key相等的元素。
  • 用一维整型数组a[n]存储整数集合,顺序查找从数组的第一个元素开始,依次比较每一个元素,直至找到key为止,如果数组的全部元素都比较完,说明查找失败

数组方式实现

#include <stdio.h>
#define N 6
int main()
{
	int a[N] = { 2,4,8,6,5,3 }, i, key, index = 0;
	key = 8;
	for(i=0;i<N;i++)
		if (a[i] == key)
		{
			index = i;
			break;
		}
	if (i == N)
		index = -1;	//没找到
	if (index == -1)
		printf("查找失败!\n");
	else
		printf("查找成功,元素%d在集合中的序号是%d\n", key, index);
	return 0;
}

指针实现方式

#include <stdio.h>
#define N 6
int main()
{
	int a[N] = { 2,4,8,6,5,3 }, i, key, index = 0;
	int* p = a;
	key = 8;
	for (; p < a + N; p++)
		if (*p == key) {
			index = p - a;
			break;
		}
	if (p == a + N)
		index = -1;
	if (index == -1)
		printf("查找失败!\n");
	else
		printf("查找成功,元素%d在集合中的序号是%d\n", key, index);
	return 0;
}

对一位数组元素的访问有三种方式

  • 1、通过下标访问数组元素:
int a[10];
for (int i = 0;i < 10;i++)
    a[i] = i;
  • 2、通过地址访问数组元素
int a[10];
for (int i = 0;i < 10; i++)
    *(a+i) = i;				//a+i是第i个元素
  • 3、通过指针访问数组元素:
int a[10];
int *p=a;
for (int i = 0;i < 10; i++)
    *(p+i)=i;		//*(p+i)可以用p[i]代替

(a+i)和(p+i)是不一样的。a不可以移动,p可以移动用p++ a是保存了数组的首地址,常量指针


p++自增运算要比p+i算术运算快得多,因此其执行效率比地址方式高

int a[10];
int *p = a;
for (int i = 0; p < (a+10); i++,p++)			//表达式3是逗号表达式
    *p=i;

因为数组占用一段连续的内存空间,因此,指针的算术运算通常用于数组。

int num,a[5]={1,2,3,4,5};
int *p=a,*q;				//指针p指向元素a[0]
q=p+4;						//相当于q = p + 4 × sizeof(int), 将q指向a[4]
num=q-p;					//指针q和p之间的元素个数,值为4
num=(int)q-(int)p;			//指针q和p之间的字节数,值为16(这种很少用)

指针变量的关系运算

同类型的指针之间进行比较运算。

不同类型的指针之间、指针与非0整数之间的关系运算没有实际意义。

假设p和q是两个同类型的指针变量,则

  • p == q:判断指针p和q是否指向同一存储单元
  • p > q :指针p所指存储单元在指针q所指存储单元的后面
  • p != NULL :判断指针p是否为空指针

引例

输入10个整数,将其中最小的数与第一个数交换,把最大的数与最后一个数交换。

  • 程序运行结果范例(蓝色字体表示输入):
  • 请输入10个整数:2 3 4 23 5 78 0 1 6 12
  • 交换后的结果为:0 3 4 23 5 12 2 1 5 78
  • 请输入10个整数:1 25 7 40 5 6 12 8 30 19
  • 交换后的结果为:1 25 7 19 5 6 12 8 30 40

用数组即数组传参方式实现上述程序。

写3个函数:(1)输入10个数;(2)进行处理;(3)输出10个数。

这个程序使用数组和指针两种方法实现。

数组实现方式
//一般情况下我们很少直接传一个数组参数,往往要传两个参数,传的是数组,第二个传输组多长
void process(int arr[],int num)
{
    int temp;
    int maxNum = arr[0];
    int minNum = arr[0];
    int maxPos = 0;
    int minPos = 0;
    for (int i=1; i<num; i++)
    {
        if (arr[i] < minNum)
        {
            minNum = arr[i];
            minPos = i;
        }
        if (arr[i] > maxNum)
        {
            maxNum = arr[i];
            maxPos = i;
        }
    }
    //若最小数不是第一个数,将最小数和第一个数交换
    if (minPos != 0)
        swap(&arr[0],&arr[minPos]);
    //若最大数不是最后一个数,最大数和最后的数交换
    if (maxPos != num-1)
    	swap(&arr[num-1],&arr[maxPos]);
}

主函数
int main()
{
    int a[10];
    inputArray(a,10);
    process(a,10);
    outputArray(a,10);
    return 0;
}

指针实现方式
void process(int *arr,int num)
{
    int temp;
    int *p;					//p指针向后移动扫描数组
    int *min,*max;			//min和max指针记录最小和最大数的地址
    p=max=min=arr;			//p,max,min均指向数组第一个数
   	for (; p<arr+num ; p++)
    {
        if (*p<*min)
            min = p;
        if (*p>*max)
            max = p;
    }
    if (min != arr)
    	swap(arr,min);
    if (max != arr+num-1)
        swap((arr+num-1),max);
}

主函数
//调用语句
process(a,10);

一维数组作为函数的参数

一维数组的座位参数的特点是:形参数组和实参数组是同一个数组。

也就是说,主程序和子程序分别同不同的名字,共用了同一块空间。因此在子程序中,通过arr【i】对数组的任何改变,都会相应地影响到对应的实参a【i】


实际应用

描述

一个句子中有多个连续空格,过滤多余空格,只留下一个空格。

输入

一行,一个字符串(长度不超过200),句子的头和尾都没有空格

输出

过滤之后的句子

样例输入:

Hello world.This is c language.

样例输出

Hello world.This is c language.

str1:Thisisclanguage\0
str2:Thisisclanguage\0
void operate(char *p1,char *p2)
{
    while (*p1)
    {
        if (*p1!=' ')
        {
            *p2++=*p1++;		//*的优先级要高
        }
        else
        {
            *p2++ = ' ';
            while(*p1 == ' ')
                p1++;
            /*
            也可以写为
            while (*p1++ == ' ')
            	;
            */
        }
    }
    *p2 = '\0';		//把str2初始化为'\0'就不需要写这个了,考虑到会用到其他情况,可能不会初始化,加上这个会很保险
}
int mian()
{
    char str1[201]={0};
    char str2[201]={0};
    gets(str1);
    operate(str1,str2);
    printf("%s",str2);
}
  • 12
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 100
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 100
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值