顺序查找
- 要求用指针实现:在整数集合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: | T | h | i | s | i | s | c | l | a | n | g | u | a | g | e | \0 |
---|
str2: | T | h | i | s | i | s | c | l | a | n | g | u | a | g | e | \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);
}