一、引例 - 牛客网OJ题
为了更好地说明这个问题,我们以一道牛客网的题目作引例。题目链接贴在这里
题目难度不大,可以让新手对数组有一定的初步认识,同时是一道介绍循环数组+scanf函数输入的极佳例题,下面是笔者对该题的尝试解答。
二、解答
例题解答一
思路
利用for循环与scanf函数将分数存放在score[ ]数组中,再历遍数组中所有项后,利用 i f 语句将max与min的初值进行对比 ,将最大值赋给max,将最小值赋给min,最后利用printf 函数输出最大值与最小值的差值,即,max-min的值。
代码
#include <stdio.h>
int main() {
int i=0;
int num=0;
int max=0,min=100;//分值为0-100
scanf("%d",&num);
int score[num];
for(i=0;i<num;i++)
{
scanf("%d",&score[i]);
if(max<=score[i])
max=score[i]; //将比max大的数赋值给max,保证max最大
if(min>=score[i])
min=score[i]; //将比min小的数赋值给min,保证min最小
}
printf("%d ",max-min);
return 0;
}
解答二是在解答一的基础上进行了适当修改,利用三目操作符代替 i f 语句,使代码更加精简,
接下来让我们看一看笔者敝帚自珍的创意供大家批判。
例题解答二
代码
#include <stdio.h>
int main() {
int i=0;
int num=0;
scanf("%d",&num);
int score[num];
int max=0;
int min=100;
for(i=0;i<num;i++)
{
scanf("%d",&score[i]);
max=(max>score[i]?max:score[i]);
min=(min<score[i])?min:score[i]);
}
printf("%d ",max-min);
return 0;
}
代码二与代码一的思路基本一致,在这里笔者就不过多赘述。不过,接下来笔者想和各位简单的聊一聊三目操作符。
三目操作符的初步介绍
三目运算符,又称条件运算符,是计算机语言(C
,C++,Java
等)的重要组成部分。它是唯一有 3 个操作数的运算符,所以有时又称为三元运算符,其实三目运算符和 if / else 条件判断类似。
三目运算符的书写:
//三目运算符
<表达式1> ? <表达式2> : <表达式3>;
返回值:先求表达式 1 的值,如果为真,则执行表达式 2,并返回表达式 2 的结果;如果表达式 1 的值为假,则执行表达式 3,并返回表达式 3 的结果。
举个例子:对于条件表达式 b ? x : y,先判断条件 b 真假,如果 b 的值为 true ,那么返回表达式 x 的计算结果;否则,计算 y 的值,返回表达式 y 的计算结果。
详情见:
三、数组存放的四种方式
方式一
#include<stdio.h>
int main()
{
int a[5],i;
for(i=0;i<5;i++)
scanf("%d",&a[i]);
for(i=0;i<5;i++)
printf("%d ",a[i]);
return 0;
}
方式一是数组输入的众多方式里最为常用的一个,他几乎是所有程序人员进行数组输入过程的首选方式,简单,好用,通俗易懂是他备受程序员青睐的原因。
方式二
#include<stdio.h>
int main()
{
int a[5],i;
for(i=0;i<5;i++)
scanf("%d",a+i);
for(i=0;i<5;i++)
printf("%d ",*(a+i));
return 0;
}
如果想要深刻理解方式二我们就要回顾一些有关数组的基本概念,我们一起跟随笔者的步伐,来回顾一下这些小知识吧!
数组知识点回顾
数组是按顺序存储的一系列类型相同的值,如10个 char 类型的字符或10个 int 类型的值。整个数组有一个数组名,通过整数下标访问数组中单独的项或元素,并且数组名所表示的为是首元素的地址。
详情见:
指针初步了解
指针是数据在内存中的地址,标示了一个占据存储空间的实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组,函数等占据存储空间的实体。
详情见:
了解到数组名就是数组的首元素地址,我们可以知道我们可以利用指针的方式进行,因为数组在内存中是连续存在的,for 循环与 a+i 结合,可以在地址层面将数组进行储存。而*(a+i)操作则是按照地址寻回该地址存放的数字,并利用printf 函数将其打印出来。可以理解为指针是人的身份证号码,而姓名则是指针所指向的变量,姓名可以去民政局更改,也会有很多人重名,但身份证号码则是永远一一对应,且伴随终身的。
方式三和方法四
#include<stdio.h>
int main()
{
int a[5],i;
int* p=a;
for(i=0;i<5;i++)
scanf("%d",p+i);
for(i=0;i<5;i++)
printf("%d ",*(p+i));
return 0;
}
#include<stdio.h>
int main()
{
int a[5],i;
int* p=NULL; //为了防止生成野指针,因此初始化为空指针
for(p=a;p<a+5;p++)
scanf("%d",p);
for(p=a;p<a+5;p++)
printf("%d ",p);
return 0;
}
方法三、四的底层逻辑基本一致,都是引入一个指针变量 p,并且将数组的首元素地址赋给变量p,然后根据指针特性——指针的一个步长代表一个元素,分别利用(a+i )和 p++的方式,将数组内容依次更改。这种方式的优点在于 ,利用指针可以在地址层面将数组元素进行输入,是彻底的,因此,这两种方式常用于定义函数时数组传参时使用,这样不会再受限于传递数组时只传递数组首元素地址的特性,可以在调用函数时将数组元素完成改变。