浅谈牛客网题目之利用循环scanf函数将数值存放到数组的四种方式

一、引例 - 牛客网OJ题

 为了更好地说明这个问题,我们以一道牛客网的题目作引例。题目链接贴在这里

最高分与最低分之差_牛客题霸_牛客网输入n个成绩,换行输出n个成绩中最高分数和最低分数的差。。题目来自【牛客题霸】icon-default.png?t=N7T8https://www.nowcoder.com/practice/e0e4f81dcd55408a8973f8033bbeb1d2?tpId=290&tqId=352868&ru=%2Fpractice%2F99dba043761e43c2a6f931e2c5c247c7&qru=%2Fta%2Fbeginner-programmers%2Fquestion-ranking&sourceUrl=%2Fexam%2Foj%3Fpage%3D1%26tab%3D%25E8%25AF%25AD%25E6%25B3%2595%25E7%25AF%2587%26topicId%3D290题干如下:

题目难度不大,可以让新手对数组有一定的初步认识,同时是一道介绍循环数组+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 的计算结果。

详情见:

C语言三目运算符-猿说编程C语言三目运算符 - 返回值:先求表达式 1 的值,如果为真,则执行表达式 2,并返回表达式 2 的结果;如果表达式 1 的值为假,则执行表达式 3,并返回表达式 3 的结果。 举个例子:对于条件表达式 b ? x : y,先判断条件 b 真假,如果 b 的值为 true ,那么返回表达式x的计算结果;否则,计算 y 的值,返回表达式 y 的计算结果。1.不管是C或者C++中,false 和 0 两者等价,true 和 1两者等价;2.字符串占位符是 %s ,整形占位符是 %d ,icon-default.png?t=N7T8https://www.codersrc.com/archives/7558.html

 三、数组存放的四种方式

方式一
#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语言(三):数组 - 知乎(四)数组 1、什么是数组、如何定义数组? 数组就是存储一批同类型数据的地方。 C语言是不允许在程序运行过程中去修改数组空间大小的!就是数组不能动态定义! 2、如何访问数组中的元素? a[0]; 表示访问数组a中…icon-default.png?t=N7T8https://zhuanlan.zhihu.com/p/631262275

指针初步了解

指针是数据在内存中的地址,标示了一个占据存储空间实体,在这一段空间起始位置的相对距离值。在 C/C++语言中,指针一般被认为是指针变量,指针变量的内容存储的是其指向的对象的首地址,指向的对象可以是变量(指针变量也是变量),数组函数等占据存储空间的实体。

详情见:

【C语言进阶】⑥函数指针详解-CSDN博客文章浏览阅读5.3w次,点赞248次,收藏846次。一、函数指针1.概念函数指针:首先它是一个指针,一个指向函数的指针,在内存空间中存放的是函数的地址;请看示例:int main(){int a = 10;int*pa = &a;char ch = 'c';char* pc = &ch;int arr[10] = {0};int (*parr)[10] = &arr;//取出数组的地址return 0;}解析:parr是一个指向数组的指针,存放的是数组的地址;所以:数组指针 —存放数组地址的指针_函数指针https://blog.csdn.net/m0_46569169/article/details/124318184?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170214640716800182150714%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170214640716800182150714&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-2-124318184-null-null.142^v96^control&utm_term=%E5%87%BD%E6%95%B0%E6%8C%87%E9%92%88&spm=1018.2226.3001.4187

了解到数组名就是数组的首元素地址,我们可以知道我们可以利用指针的方式进行,因为数组在内存中是连续存在的,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++的方式,将数组内容依次更改。这种方式的优点在于 ,利用指针可以在地址层面将数组元素进行输入,是彻底的,因此,这两种方式常用于定义函数时数组传参时使用,这样不会再受限于传递数组时只传递数组首元素地址的特性,可以在调用函数时将数组元素完成改变。

  • 45
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值