前端Excel热成像数据展示及插值算法

news2024/11/12 21:39:07

在这里插入图片描述

🎬 江城开朗的豌豆:个人主页

 🔥 个人专栏:《 VUE 》 《 javaScript 》

 📝 个人网站 :《 江城开朗的豌豆🫛 》 

⛺️生活的理想,就是为了理想的生活!

目录

📘 前言

📘一、热成像数据的导入与展示

📟 1.数据导入:

📟 2.创建热图:

📟3.数据可视化

📘二、插值算法的应用

📟 1.线性插值:

📟 2.双线性插值:

 📟 3.样条插值:

📘三、实例操作

📘 完整代码展示

📘 写在最后


📘 前言

热成像技术在工业、医学和科学研究中发挥了重要作用,它能够通过捕捉不同物体的温度分布图像来提供宝贵的信息。然而,要有效地展示和分析这些热成像数据,我们需要使用适当的工具和算法。本文将介绍如何使用Excel展示热成像数据,并实现插值算法以增强数据分析的准确性和可视化效果。

 原始图

 转换成功的效果图

📘一、热成像数据的导入与展示

热成像设备通常生成的是包含温度信息的二维数组数据。在Excel中展示这些数据,可以通过以下步骤

📟 1.数据导入

 将热成像数据以CSV或XLSX格式导入Excel。通常,这些数据以矩阵的形式存储,每个单元格代表一个温度值。

📟 2.创建热图

在Excel中,可以使用条件格式来创建热图。选择包含温度数据的单元格区域,应用“条件格式”中的“色阶”功能,以不同的颜色表示不同的温度范围。这种可视化方法能帮助快速识别热图中的热点区域。

📟3.数据可视化

  利用Excel的图表工具,将数据以图表形式展示。例如,可以创建散点图或折线图,帮助分析温度随时间或位置的变化

📘二、插值算法的应用

在热成像数据中,可能存在一些缺失值或数据点稀疏的情况。插值算法可以帮助我们估算这些缺失值,并提高数据的连续性。以下是一些常见的插值算法及其在Excel中的实现方法:

📟 1.线性插值

线性插值是最简单的插值方法,通过连接已知数据点的直线来估算未知点的值。在Excel中,可以通过线性回归或在两个已知数据点之间插入一个新的数据点来实现。

📟 2.双线性插值

双线性插值适用于二维数据,使用已知点形成的矩阵进行插值。你可以在Excel中创建一个新的数据表,通过公式计算每个数据点的插值值。双线性插值公式如下:

 📟 3.样条插值

样条插值是一种更复杂的插值方法,通过多项式拟合数据点,实现平滑的曲线插值。在Excel中,这种方法可以通过插件或VBA代码实现,虽然设置相对复杂,但可以生成更平滑的数据图。

📘三、实例操作

假设我们有一个包含热成像数据的Excel表格,我们可以通过以下步骤进行插值和数据展示:

  1. 创建数据表: 将热成像数据输入Excel,并使用条件格式创建热图。

  2. 应用插值算法: 使用Excel的插值公式填补缺失数据,或通过VBA实现更复杂的插值算法。

  3. 数据分析与优化: 根据插值后的数据,生成更精确的热图和图表。利用Excel的数据分析工具,评估数据的准确性和可靠性。

📘 完整代码展示

        

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Excel Heatmap with Canvas</title>
    <script src="https://cdn.jsdelivr.net/npm/xlsx@0.18.5/dist/xlsx.full.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js"></script>

    <style>
      #heatmapCanvas {
        /* border: 1px solid black; */
      }
    </style>
  </head>
  <body>
    <button onclick="chuNenFx()">储能分析</button>
    <input type="file" id="fileInput" />
    <input type="number" id="reLiNum" placeholder="输入数字" />
    <button onclick="getValue()">获取值</button>  
    <button onclick="showMaxTemperature()">显示最高温度</button>
    <button onclick="showMinTemperature()">显示最低温度</button>
    <br />
    <button onclick="highlightMaxTemperature()">标记最高温度</button>
    <button onclick="highlightMinTemperature()">标记最低温度</button>

    <canvas id="heatmapCanvas"></canvas>
    <script>
      document
        .getElementById("fileInput")
        .addEventListener("change", handleFileSelect, false);
      // 双线性插值算法
      var newData = [];
      function processFile() {
        const fileInput = document.getElementById("fileInput");
        const file = fileInput.files[0];
        const reader = new FileReader();
        reader.onload = function (event) {
          const data = new Uint8Array(event.target.result);
          const workbook = XLSX.read(data, { type: "array" });
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          const csv = XLSX.utils.sheet_to_csv(worksheet);
          const arrayData = csvToArray(csv);
          const interpolatedData = interpolate22(arrayData, 480, 640); // 增加到 240, 320 的分辨率   1440, 1920 --  384, 512
          //   console.log("Interpolated", interpolatedData);
          const szNew = interpolatedData
            .map((row) => row.map((cell) => Math.round(cell)))
            .map(
              (row) => row.filter((cell) => cell !== 0) // 过滤掉值为 0 的元素
            );
          console.log(szNew);
          newData = szNew;
        };
        reader.readAsArrayBuffer(file);
      }

      function interpolate22(data, newRows, newCols) {
        const rows = data.length;
        const cols = data[0].length;
        const interpolatedData = Array.from({ length: newRows }, () =>
          Array(newCols).fill(0)
        );

        for (let i = 0; i < newRows; i++) {
          for (let j = 0; j < newCols; j++) {
            const xRatio = (j / (newCols - 1)) * (cols - 1);
            const yRatio = (i / (newRows - 1)) * (rows - 1);
            const x0 = Math.floor(xRatio);
            const x1 = Math.min(x0 + 1, cols - 1);
            const y0 = Math.floor(yRatio);
            const y1 = Math.min(y0 + 1, rows - 1);

            const q11 = data[y0][x0];
            const q21 = data[y0][x1];
            const q12 = data[y1][x0];
            const q22 = data[y1][x1];

            const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;
            const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;

            interpolatedData[i][j] = (y1 - yRatio) * r1 + (yRatio - y0) * r2;
          }
        }

        return interpolatedData;
      }

      // 最大值

      function getMaxTemperature(data) {
        let maxTemp = -Infinity;
        for (const row of data) {
          for (const temp of row) {
            if (temp > maxTemp) {
              maxTemp = temp;
            }
          }
        }
        return maxTemp;
      }
      //   插值算法封装
      function interpolate(data, newRows, newCols) {
        const rows = data.length;
        const cols = data[0].length;
        const x = Array.from({ length: cols }, (_, i) => i);
        const y = Array.from({ length: rows }, (_, i) => i);

        const interpolatedData = Array.from({ length: newRows }, (_, i) => {
          return Array.from({ length: newCols }, (_, j) => {
            const xRatio = (j / (newCols - 1)) * (cols - 1);
            const yRatio = (i / (newRows - 1)) * (rows - 1);
            const x0 = Math.floor(xRatio);
            const x1 = Math.min(x0 + 1, cols - 1);
            const y0 = Math.floor(yRatio);
            const y1 = Math.min(y0 + 1, rows - 1);

            const q11 = data[y0][x0];
            const q21 = data[y0][x1];
            const q12 = data[y1][x0];
            const q22 = data[y1][x1];

            const r1 = (x1 - xRatio) * q11 + (xRatio - x0) * q21;
            const r2 = (x1 - xRatio) * q12 + (xRatio - x0) * q22;

            return (y1 - yRatio) * r1 + (yRatio - y0) * r2;
          });
        });

        return interpolatedData;
      }
      function csvToArray(text) {
        return text.split("\n").map((row) => row.split(",").map(Number));
      }

      var maxTemperature = [];

      // 最小值
      function getMinTemperature(data) {
        let minTemp = Infinity;
        for (const row of data) {
          for (const temp of row) {
            if (temp < minTemp) {
              minTemp = temp;
            }
          }
        }
        return minTemp;
      }
      // 显示最低温度
      function showMinTemperature() {
        const minTemperature = getMinTemperature(maxTemperature);
        alert(`最低温度是: ${minTemperature / 100}°C`);
      }

      function showMaxTemperature() {
        if (maxTemperature.length > 0) {
          const maxTempe = getMaxTemperature(maxTemperature);
          alert(`最高温度是: ${maxTempe / 100}°C`);
        } else {
          alert(`最高温度是: 请先上传数据`);
        }
      }
      // 封装双线性插值算法
      function bilinearInterpolate(x, y, values) {
        const x1 = Math.floor(x);
        const y1 = Math.floor(y);
        const x2 = Math.ceil(x);
        const y2 = Math.ceil(y);

        const Q11 = values[y1] ? values[y1][x1] : 0;
        const Q12 = values[y1] ? values[y1][x2] : 0;
        const Q21 = values[y2] ? values[y2][x1] : 0;
        const Q22 = values[y2] ? values[y2][x2] : 0;

        const xFraction = x - x1;
        const yFraction = y - y1;

        const R1 = Q11 * (1 - xFraction) + Q12 * xFraction;
        const R2 = Q21 * (1 - xFraction) + Q22 * xFraction;

        return R1 * (1 - yFraction) + R2 * yFraction;
      }
      // 获取excel数据
      async function handleFileSelect(event, json) {
        await processFile();
        const file = event.target.files[0];
        // console.log("=====>>>", file);

        if (!file) return;

        const reader = new FileReader();
        reader.onload = function (e) {
          const data = new Uint8Array(e.target.result);
          const workbook = XLSX.read(data, { type: "array" });

          // Assuming you want to process the first sheet
          const sheetName = workbook.SheetNames[0];
          const worksheet = workbook.Sheets[sheetName];
          //   const json = XLSX.utils.sheet_to_json(worksheet, {
          //     header: 1,
          //     defval: 0,
          //   });
          // Default values for empty cells

          // Convert data to 2D array
          //   console.log("===========json=====================", json);
          const dataArray = newData.map((row) =>
            row.map((cell) => parseFloat(cell) || 0)
          );
          //   console.log("Data Array:", dataArray);
          maxTemperature = dataArray;
          //   console.log("=workbook===" + maxTemperature);

          drawHeatmap(dataArray);
        };
        reader.readAsArrayBuffer(file);
      }

      // 插值算法
      const canvas = document.getElementById("heatmapCanvas");
      //   const cellSize = 10; // 原始单元格大小
      let newCellSize = 1; // 插值后的单元格大小
      function getValue() {
        const inputElement = document.getElementById("reLiNum");
        const value = inputElement.value; // 获取输入的值
        newCellSize = value;
        drawHeatmap(maxTemperature); // 重新绘制热力图
      }
      //   页面跳转
      function chuNenFx() {
        window.location.replace("./boxEchars.html");
      }

      //   绘制热力图
      function drawHeatmap(dataArray) {
        const width = dataArray[0].length;
        const height = dataArray.length;

        // 计算新画布的宽度和高度
        const canvasWidth = width * newCellSize;
        const canvasHeight = height * newCellSize;
        // Adjust canvas size
        canvas.width = canvasWidth; // Scale width
        canvas.height = canvasHeight; // Scale height

        const ctx = canvas.getContext("2d");
        const imageData = ctx.createImageData(canvasWidth, canvasHeight);

        // 查找归一化的最小值和最大值
        let min = Infinity;
        let max = -Infinity;
        dataArray.flat().forEach((value) => {
          if (value < min) min = value;
          if (value > max) max = value;
        });

        // 生成热力图
        for (let y = 0; y < canvasHeight; y++) {
          for (let x = 0; x < canvasWidth; x++) {
            const dataX = x / newCellSize;
            const dataY = y / newCellSize;

            const value = bilinearInterpolate(dataX, dataY, dataArray);

            // const value = dataArray[y][x];
            const normalizedValue = (value - min) / (max - min);
            // for (let dy = 0; dy < cellSize; dy++) {
            //     for (let dx = 0; dx < cellSize; dx++) {
            //         const index = ((y * cellSize + dy) * canvas.width + (x * cellSize + dx)) * 4;
            //         const color = getHeatmapColor(normalizedValue);

            //         imageData.data[index] = color[0];
            //         imageData.data[index + 1] = color[1];
            //         imageData.data[index + 2] = color[2];
            //         imageData.data[index + 3] = 255;
            //     }
            // }

            // // 获取颜色值
            const color = getHeatmapColor(normalizedValue);
            // 设置画布上的像素颜色
            const index = (y * canvasWidth + x) * 4;
            imageData.data[index] = color[0]; // Red
            imageData.data[index + 1] = color[1]; // Green
            imageData.data[index + 2] = color[2]; // Blue
            imageData.data[index + 3] = 255; // Alpha
          }
        }
        // console.log("imageDat", imageData);
        ctx.putImageData(imageData, 0, 0);
      }

      // 找到最高温度及其位置
      function getMaxTemperatureInfo(isMax) {
        let extremeTemp = isMax ? -Infinity : Infinity;
        let position = { row: 0, col: 0 };

        maxTemperature.forEach((row, rowIndex) => {
          row.forEach((temp, colIndex) => {
            if (
              (isMax && temp > extremeTemp) ||
              (!isMax && temp < extremeTemp)
            ) {
              extremeTemp = temp;
              position = { row: rowIndex, col: colIndex };
            }
          });
        });

        return { extremeTemp, position };
      }

      // 找到最高温度及其位置
      //   function getMaxTemperatureInfo() {
      //     let maxTemp = -Infinity;
      //     let position = { row: 0, col: 0 };
      //     maxTemperature.forEach((row, rowIndex) => {
      //       row.forEach((temp, colIndex) => {
      //         if (temp > maxTemp) {
      //           maxTemp = temp;
      //           position = { row: rowIndex, col: colIndex };
      //         }
      //       });
      //     });
      //     return { maxTemp, position };
      //   }

      // 标记最高温度
      function highlightMaxTemperature() {
        const { extremeTemp, position } = getMaxTemperatureInfo(true);
        drawHeatmap(maxTemperature); // 重新绘制热力图
        const ctx = canvas.getContext("2d");

        // 绘制标记
        ctx.strokeStyle = "yellow";
        ctx.lineWidth = 30;
        ctx.beginPath();
        const x = position.col * newCellSize + newCellSize / 2;
        const y = position.row * newCellSize + newCellSize / 2;
        ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = "yellow";
        ctx.fill();
        // alert(`最高温度是: ${extremeTemp/100}°C`);
        // 显示温度值
        ctx.fillStyle = "black";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(`${extremeTemp / 100}°C`, x, y);
      }
      // 标记最低温度
      function highlightMinTemperature() {
        const { extremeTemp, position } = getMaxTemperatureInfo(false);
        drawHeatmap(maxTemperature); // 重新绘制热力图
        const ctx = canvas.getContext("2d");

        // 绘制标记
        ctx.strokeStyle = "green";
        ctx.lineWidth = 30;
        ctx.beginPath();
        const x = position.col * newCellSize + newCellSize / 2;
        const y = position.row * newCellSize + newCellSize / 2;
        ctx.arc(x, y, newCellSize / 4, 0, 2 * Math.PI);
        ctx.stroke();
        ctx.fillStyle = "green";
        ctx.fill();
        // alert(`最低温度是: ${extremeTemp/100}°C`);
        // 显示温度值
        ctx.fillStyle = "white";
        ctx.font = "12px Arial";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(`${extremeTemp / 100}°C`, x, y);
      }

      function getHeatmapColor(value) {
        // 从蓝色到红色的简单热图颜色渐变
        const r = Math.min(255, Math.max(0, Math.floor(255 * value)));
        const g = Math.min(255, Math.max(0, Math.floor(255 * (1 - value))));
        const b = 0;
        return [r, g, b];
      }
    </script>
  </body>
</html>


📘 写在最后

Excel作为一种强大的数据处理工具,可以有效地展示和分析热成像数据。通过合理使用插值算法,可以提升数据的连续性和可视化效果。希望本文能帮助你更好地利用Excel进行热成像数据的展示和分析。如果你有更复杂的数据需求,也可以考虑结合使用专业的数据分析工具和编程语言。

通过掌握这些基本技巧,你将能够更好地理解和利用热成像数据,为你的工作和研究提供有力支持。

感谢大家一如既往对我的点赞与支持,不是我的作品有多好,而是你们的不嫌弃。这世界上有一种爱叫“关注”,感恩遇见、感恩有你~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2125615.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

最受欢迎的10款电脑监控软件大揭秘,员工电脑监控软件真心推荐

随着科技的迅猛发展&#xff0c;越来越多的企业和个人开始关注电脑监控软件的使用。这类软件能够帮助企业管理者更好地了解员工的工作状况&#xff0c;提升工作效率&#xff0c;并确保公司数据安全&#xff1b;个人用户也可以利用这些软件监控电脑活动&#xff0c;保护家人尤其…

电源自动测试系统有哪些原理和优势?

‌电源自动测试系统是一种自动测试设备&#xff0c;用于对各类电源模块进行功能和性能测试。它采用模块化设计&#xff0c;构建了一个方便快捷、功能齐全的电源测试平台&#xff0c;便于后续的检修和维护&#xff0c;减少对企业生产和测试的影响。 电源自动测试系统的工作原理和…

区块链学习笔记3--以太坊

智能合约&#xff1a;跑在以太坊系统中的代码合同&#xff0c;其实质是一段代码。目前已经存在180多万个智能合约。 智能合约能表达&#xff1a;规则明确&#xff0c;不受主观因素影响的业务。 智能合约能表达&#xff1a;规则不轻易修改的业务 如果业务的规则经常变化&#x…

2025第九届数字信号处理国际会议(ICDSP 2025)将在成都召开!

第九届数字信号处理国际会议&#xff08;ICDSP 2025&#xff09;将于2025年2月21-23日在成都召开。ICDSP 2025大会由西南交通大学和西华大学联合主办, 并得到各地高校和机构的技术支持。大会旨在邀请众多国内外学者及产业研发人员齐聚一堂&#xff0c;共同探讨数字信号处理领域…

ABB机械手备份与恢复

ABB机械手备份与恢复 备份恢复系统 备份 ABB机器人数据备份的对象是所有正在系统内存中运行的RAPID程序和系统参数。当机器人系统出现错乱或者重新安装系统以后&#xff0c;可以通过备份快速地把机器人恢复到备份时的状态。 如果导出到U盘需要将U盘插入USB接口&#xff0c;位置…

docker-01 创建一个自己的镜像并运行容器

docker-01 创建一个自己的镜像并运行容器 前言 我们都知道使用Docker的镜像可以快速创建和部署应用&#xff0c;大大的节约了部署的时间。并且Docker 的镜像提供了除内核外完整的运行时环境&#xff0c;确保代码的环境一致性&#xff0c;从而不会在出现这段代码在我机器上没问…

通过mxGraph在ARMxy边缘计算网关上实现工业物联网

在当今的工业4.0时代&#xff0c;工业物联网&#xff08;IIoT&#xff09;已经成为制造业转型升级的关键技术之一。ARMxy边缘计算网关作为工业自动化和物联网的重要组成部分&#xff0c;能够为工厂车间提供实时的数据处理能力和智能化服务。而mxGraph作为一种流行的JavaScript库…

ABB的IO板卡配置

ABB的IO板卡配置 标准IO板卡DSQC651IO板卡的配置数字量输入信号配置数字量输出信号配置组合输入信号配置组合输出信号配置模拟量输出信号配置 标准IO板卡DSQC651 DSQC651可以处理8路输入数字量&#xff0c;8路输出数字量和2路模拟量输出信号。 X1是数字量输出&#xff0c;接线…

agentuniverse快速开始和踩坑

https://github.com/alipay/agentUniverse/tree/mastergithub地址:https://github.com/alipay/agentUniverse/tree/master 老大看了演示demo也想跟着做个agent工具,但踩坑太多,含泪写下博客 前置环节 git clone https://github.com/alipay/agentUniverse.git conda create -n…

轻松发高分的好思路:GNN+时间序列预测!新SOTA效率翻了5倍

在时序预测领域&#xff0c;通过合理构建和应用图结构&#xff0c;GNN能有效捕捉时空数据中的复杂依赖关系&#xff0c;轻松提高预测的准确性。因此GNN时序预测在学术界和工业界都广受欢迎。 最近这个方向出现了很多效果很好的研究&#xff0c;比如GraFITi模型&#xff0c;利用…

[AHK]Listbox with incremental search

可以根据文本框中的输入内容&#xff0c;实时动态从列表中搜索并定位所搜索内容。 AHK V1代码 #Requires AutoHotkey v1.0 Gui Add, Edit, w300 h20 vsearchedString gIncrementalSearch Gui Add, ListBox, vchoice gListBoxClick w300 h250 hscroll vscroll Gui Add, Button, …

Excel怎么截图?快速捕捉工作表的多种方法

大家好&#xff0c;这里是效率办公指南&#xff01; &#x1f4f8; 在日常工作中&#xff0c;我们经常需要对Excel工作表进行截图&#xff0c;无论是为了记录数据、制作演示还是进行数据对比。今天&#xff0c;我们就来学习几种在Excel中截图的方法以及它们的快捷键。 一、使…

迈向智能制造:数字化转型的核心策略与实践

在全球经济不断变革的背景下&#xff0c;制造业正迎来一场深刻的数字化变革。随着技术的快速进步&#xff0c;特别是工业4.0概念的普及&#xff0c;制造企业正在向智能制造方向转型。 智能制造是通过数字化技术的集成和应用&#xff0c;全面提升制造过程的自动化、信息化和智能…

Java项目: 基于SpringBoot+mybatis+maven新闻推荐系统(含源码+数据库+毕业论文)

一、项目简介 本项目是一套基于SpringBootmybatismaven新闻推荐系统 包含&#xff1a;项目源码、数据库脚本等&#xff0c;该项目附带全部源码可作为毕设使用。 项目都经过严格调试&#xff0c;eclipse或者idea 确保可以运行&#xff01; 该系统功能完善、界面美观、操作简单、…

信息安全数学基础(6)整除的进一步性质

1. 传递性 如果 a 能被 b 整除&#xff0c;且 b 能被 c 整除&#xff08;记作 a∣b 和 b∣c&#xff09;&#xff0c;则 a 能被 c 整除&#xff08;记作 a∣c&#xff09;。 2. 线性组合 如果 a∣b 且 a∣c&#xff0c;则对于任意整数 x 和 y&#xff0c;都有 a∣(bxcy)。这个性…

Vue2踩坑记录 - el-input无法接收键盘输入,对响应式对象的深入理解-对象和数组的响应式

今天发现&#xff0c;某对话框打开后&#xff0c;其中的input无法接收键盘输入&#xff0c;我在页面上劈里啪啦敲了一堆&#xff0c;页面输入框空空如也&#xff0c;的确是用了v-model来实现双向绑定。但是显然&#xff0c;它没有实现双向数据传输。那么&#xff0c;双向数据传…

JMeter在Mac下的安装使用

目录 Mac OS Jmeter安装运行1、Jmeter下载2、运行Jmeter3、编写或导入脚本 前言 开发过程中需要对系统进行性能测试&#xff0c;可以选用jemter对接口进行压测&#xff0c;jemter优点如下&#xff1a; 开源许可证&#xff1a;Jmeter完全免费&#xff0c;允许开发者使用源代码…

SM7015非隔离电磁炉/电饭煲电源芯片12V/18V输出

SM7015特点&#xff1a; 拓扑结构支持&#xff1a;低成本 BUCK、BUCK-BOOST 等方案 采用 730V 单芯片集成工艺 85Vac~265Vac 宽电压输入 待机功耗小于 120mW220Vac 集成高压启动电路 集成高压功率开关 60KHz 固定开关频率 内置抖频技术&#xff0c;提升 EMC 性能 电流模式 PWM…

使用designer.exe实现设计ui界面(以及解决遇到的问题)

引言: 若自己构想一个简洁的页面,有个布局的草图,且使用python实现,似乎是可行的,但是若对于比较复杂的界面,且不说每个模块在布局中所在的位置,再说每个模块所对应的功能以及程序的实现,都会是十分繁杂的任务。所以此时就需要寻找更加直观的设计方法。 其实python中的…

指针之旅(5)—— 万能指针与回调函数的搭配:万能排序qsort函数的使用规则及其模拟实现。

目录 1. 回顾&#xff1a;万能指针void* 与 回调函数 的特性 1.1 万能指针void* 1.2 回调函数 2. qsort函数的使用规则 2.1 qsort的头文件和排序方向 2.2 qsort的函数参数表解析 2.3 结构体数组排序举例 3. 冒泡排序模拟万能排序qsort的实现 3.1 冒泡排序的回顾与疑问…