{ }codelper
返回值定义函数P0402

指针出不了刻度的温度计

教室里的温度计只有从 lo 度到 hi 度的刻度。
实际气温低于 lo 时温度计指向 lo,高于 hi 时指向 hi。
其余情况下指向实际气温本身。
第一行给出 lo 和 hi,用一个空格隔开。
第二行给出测量气温的次数 n。
接下来的 n 行,每行给出一个实际气温 t。
请按测量的顺序,每行一个,输出温度计指向的值。
最后一行输出温度计指向的这 n 个值的总和。
请写一个接收实际气温和 lo、hi 并返回温度计所指的值的函数,把返回的值同时用在输出和总和上。
评分只看输出。

输入
-100 ≤ lo ≤ hi ≤ 100,1 ≤ n ≤ 100,-1,000 ≤ t ≤ 1,000(均为整数)
输出
n + 1 行。
前 n 行是温度计指向的值,最后一行是它们的总和
样例 1 · stdin
-5 30
4
12
-9
30
41
stdout
12
-5
30
30
67
main.py
输入(stdin)

运行时这些行会依次作为 input()/标准输入传入(运行中不会等待输入)。

$ 就绪

请在电脑上打开以编写和运行代码。在手机上可以查看题目和题解。

其他语言怎么写?查看各语言题解 · 8 种语言题解

定义函数的写法因语言而异。
Python 写 def shown(t, lo, hi):,JS 写 function shown(t, lo, hi),都不写类型。
TS 写成 function shown(t: number, lo: number, hi: number): number,在括号后面写返回值的类型。
Java 和 C# 写 static int shown(int t, int lo, int hi)(C# 通常写 Shown),C、C++ 写 int shown(int t, int lo, int hi),返回类型写在名字前面。
Craykon 只写名字和括号,如 名字(t, lo, hi) { … },用 返回 t; 把值返回。
一遇到 return 函数就立刻结束,所以 if (t < lo) return lo; 下面不必写 else。
函数放的位置也不一样。
Python 要求在调用的那一行之前 def 已经执行过,放在下面就会因 NameError 停止。
C++ 中调用处上方没有这个函数就是编译错误,C(gcc 11)只给出警告并照常编译。
JS、TS 的 function 声明、Java 和 C# 的方法、Craykon 的函数都可以放在调用处的下面。
陷阱一:漏掉刻度以内时最后的 return t;。
Python 函数没有 return 就结束时返回 None,所以在样例中第一行输出 None,并在累加总和的那一行因 TypeError 停止。
JS 返回 undefined,而像题解那样用 join 连接时 undefined 会变成空字符串,所以样例的输出是空行、-5、空行、30、NaN。
Java 以 "missing return statement"、C# 以 CS0161 拒绝编译,TS 如果写了 : number 也会用 TS2366 拦住。
C 和 C++ 在评测机的 gcc 11(-Wall)下只给出警告并照常编译,之后的行为没有定义。
陷阱二:在函数里把值输出,却不返回。
输出到屏幕上的值不会回到调用的一方。
在 Craykon 中用 控制台.输出(t) 代替 返回,样例中只输出 12 一行,然后在累加总和的那一行提示不能用空来计算并停止。
陷阱三:只写 shown(t, lo, hi); 调用,却不接收返回的值。
八种语言中整数都是复制一份值传进去的,所以在函数里改了 t,调用方的 t 仍然不变。
在 C 中这样写不会有警告就能编译,样例的输出是 12、-9、30、41、74。
像 v = shown(t, lo, hi) 这样把返回的值放进一个名字里,才能在输出和总和中用两次。

Pythonmain.py · 17 行
def shown(t, lo, hi):    # 온도계가 가리키는 값을 돌려준다. return을 만나면 함수는 바로 끝난다    if t < lo:        return lo    if t > hi:        return hi    return t  lo, hi = map(int, input().split())n = int(input())total = 0for _ in range(n):    v = shown(int(input()), lo, hi)  # 돌려받은 값을 이름에 담아 두 번 쓴다    print(v)    total += vprint(total)
JavaScriptmain.js · 19 行
// 온도계가 가리키는 값을 돌려준다. return을 만나면 함수는 바로 끝난다function shown(t, lo, hi) {  if (t < lo) return lo;  if (t > hi) return hi;  return t;} const lines = require("fs").readFileSync(0, "utf8").split("\n");const [lo, hi] = lines[0].trim().split(/\s+/).map(Number);const n = Number(lines[1]);const out = [];let total = 0;for (let i = 0; i < n; i++) {  const v = shown(Number(lines[2 + i]), lo, hi); // 돌려받은 값을 이름에 담아 두 번 쓴다  out.push(v);  total += v;}out.push(total);console.log(out.join("\n"));
TypeScriptmain.ts · 21 行
import { readFileSync } from "node:fs"; // 온도계가 가리키는 값을 돌려준다. 괄호 뒤의 `: number`가 돌려주는 값의 타입이다function shown(t: number, lo: number, hi: number): number {  if (t < lo) return lo;  if (t > hi) return hi;  return t;} const lines: string[] = readFileSync(0, "utf8").split("\n");const [lo, hi]: number[] = lines[0].trim().split(/\s+/).map(Number);const n: number = Number(lines[1]);const out: number[] = [];let total = 0;for (let i = 0; i < n; i++) {  const v: number = shown(Number(lines[2 + i]), lo, hi); // 돌려받은 값을 이름에 담아 두 번 쓴다  out.push(v);  total += v;}out.push(total);console.log(out.join("\n"));
JavaMain.java · 25 行
import java.util.Scanner; public class Main {    // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다    static int shown(int t, int lo, int hi) {        if (t < lo) return lo;        if (t > hi) return hi;        return t;    }     public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int lo = sc.nextInt(), hi = sc.nextInt();        int n = sc.nextInt();        int total = 0;        StringBuilder out = new StringBuilder();        for (int i = 0; i < n; i++) {            int v = shown(sc.nextInt(), lo, hi); // 돌려받은 값을 변수에 담아 두 번 쓴다            out.append(v).append('\n');            total += v;        }        out.append(total).append('\n');        System.out.print(out);    }}
C#Main.cs · 27 行
using System; class Program{    // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다    static int Shown(int t, int lo, int hi)    {        if (t < lo) return lo;        if (t > hi) return hi;        return t;    }     static void Main()    {        string[] first = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries);        int lo = int.Parse(first[0]), hi = int.Parse(first[1]);        int n = int.Parse(Console.ReadLine());        int total = 0;        for (int i = 0; i < n; i++)        {            int v = Shown(int.Parse(Console.ReadLine()), lo, hi); // 돌려받은 값을 변수에 담아 두 번 쓴다            Console.WriteLine(v);            total += v;        }        Console.WriteLine(total);    }}
C++main.cpp · 22 行
#include <iostream> // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다int shown(int t, int lo, int hi) {    if (t < lo) return lo;    if (t > hi) return hi;    return t;} int main() {    int lo, hi, n;    std::cin >> lo >> hi >> n;    int total = 0;    for (int i = 0; i < n; i++) {        int t;        std::cin >> t;        int v = shown(t, lo, hi);  // 돌려받은 값을 변수에 담아 두 번 쓴다        std::cout << v << '\n';        total += v;    }    std::cout << total << '\n';}
Cmain.c · 23 行
#include <stdio.h> // 온도계가 가리키는 값을 돌려준다. 이름 앞의 int가 돌려주는 값의 타입이다int shown(int t, int lo, int hi) {    if (t < lo) return lo;    if (t > hi) return hi;    return t;} int main(void) {    int lo, hi, n;    if (scanf("%d %d %d", &lo, &hi, &n) != 3) return 0;    int total = 0;    for (int i = 0; i < n; i++) {        int t;        if (scanf("%d", &t) != 1) return 0;        int v = shown(t, lo, hi);  // 돌려받은 값을 변수에 담아 두 번 쓴다        printf("%d\n", v);        total += v;    }    printf("%d\n", total);    return 0;}
Craykonmain.cray · 27 行
// 온도계가 가리키는 값을 돌려준다. 돌려주기를 만나면 함수는 바로 끝난다가리킨값(t, lo, hi){    如果 (t < lo)    {        返回 lo;    }    如果 (t > hi)    {        返回 hi;    }    返回 t;} ends = 控制台.读数字();lo = ends[0];hi = ends[1];n = 控制台.读行().转数字();total = 0;循环 (i = 0; i < n; i++){    // 돌려받은 값을 이름에 담아 두 번 쓴다    v = 가리킨값(控制台.读行().转数字(), lo, hi);    控制台.输出(v);    total = total + v;}控制台.输出(total);