12-3_Qt 5.9 C++开发指南_创建和使用静态链接库
第12章中的静态链接库和动态链接库介绍,都是以UI操作的方式进行,真正在实践中,可以参考UI操作产生的代码来实现同样的功能。
文章目录
- 1. 创建静态链接库
- 1.1 创建静态链接库过程
- 1.2 静态链接库代码
- 1.2.1 静态链接库可视化UI设计框架
- 1.2.2 qwdialogpen.h
- 1.2.3 qwdialogpen.cpp
- 2. 静态链接库的使用
- 2.1 静态链接库的使用过程
- 2.2 代码
- 2.2.1 可视化UI设计框架
- 2.2.2 LibUser.pro
- 2.2.3 mainwindow.h
- 2.2.4 mainwindow.cpp
1. 创建静态链接库
1.1 创建静态链接库过程
创建一个静态链接库项目,设计各种需要导出的类,包括具有 UI 的窗体类、对话框类,编译后可以生成一个 lib 文件(MSVC 编译器生成后缀为“.lib”的文件,,MinGW编译器生成后缀为“.a”的文件),在另一个应用程序里使用这个 lib文件和类的头文件(不需要 cpp 源文件,就可以静态编译到应用程序里。
这种方式适合于在小组开发时,每个人负责自己的部分,使用其他人设计的代码时只能使用而不能看到或修改源代码,便于项目代码的管理。
创建静态链接库项目,单击 Qt Creator 的“File”->“New File or Project”菜单项,在出现的“New File or Project”对话框中选择 Projects 组里的 Library,在右侧的具体类别中再选择 C++ Library,单击“Choose…”按钮后出现如图 下图所示的向导对话框。

在此对话框的 Type 下拉列表框里选择“Statically Linked Library”,并给项目命名,例如myStaticLib,再选择项目保存目录。单击“Next”按钮后选择编译器,再下一步选择需要包含的Qt 模块,再下一步是类定义页面(见下图),在其中输入类的名称。

本实例将 9.3 节设计的一个 QPen 属性设置对话框 QWDialogPen 作为静态库的导出类,所以在上图的类定义界面上输入的类名称为 QWDialogPen,头文件和源程序文件名会自动生成。 单击“Next”按钮,再下一步结束即可。
这样生成的静态库项目 myStaticLib 包括 3个文件:myStaticLib.pro、qwdialogpen.h 和qwdialogpen.cpp。
我们希望将 9.3 节设计的一个 QPen 属性设置对话框 QWDialogPen 作为静态库的类,为此将9.3 节QWDialogPen 类相关的 3 个文件 qwdialogpen.h、qwdialogpen.cpp 和 qwdialogpen.ui 复制到 myStaticLib 项目的源文件目录下,覆盖自动生成的两个文件,并且将 qwdialogpen.ui 添加到项目中。
QWDialogPen 类相关的 3 个文件在9.3 节有详细介绍,添加到静态库项目 myStaticLib 之后无需做任何修改,所以其内容不再详述。
项目配置文件myStaticLib.pro 是对本项目的设置,其内容如下:
QT += widgetsTARGET = myStaticLibTEMPLATE = lib
CONFIG += staticlibDEFINES += QT_DEPRECATED_WARNINGSSOURCES += \qwdialogpen.cppHEADERS += \qwdialogpen.h
unix {target.path = /usr/libINSTALLS += target
}FORMS += \qwdialogpen.ui
TEMPLATE = lib定义项目模板是库,而不是应用程序。
CONFIG += staticlib 配置项目为静态库。
TARGET = myStaticLib定义项目编译后生成的目标文件名称为myStaticLib。
注意:静态库项目可以使用 MinGW或MSVC 编译器编译,但是项目编译生成的文件与使用的编译器有关。若使用 MSVC 编译,编译后会生成一个库文件 myStaticLib.lib; 若使用 MiGW 编译,编译后会生成一个库文件libmyStaticLib.a。
release 和 debug 模式下编译生成的都是相同的文件名,并不会为 debug 版本自动添加一个字母“d”,但是在 release 和 debug 模式下编译应用程序时,需要使用相应版本的库文件。
1.2 静态链接库代码
1.2.1 静态链接库可视化UI设计框架

1.2.2 qwdialogpen.h
#ifndef QWDIALOGPEN_H
#define QWDIALOGPEN_H#include <QDialog>
#include <QPen>
//#include "sharedlib_global.h"namespace Ui {
class QWDialogPen;
}class QWDialogPen : public QDialog
{ //QPen属性设置对话框Q_OBJECT
private:QPen m_pen; //成员变量
public:explicit QWDialogPen(QWidget *parent = 0);~QWDialogPen();void setPen(QPen pen); //设置QPen,用于对话框的界面显示QPen getPen(); //获取对话框设置的QPen的属性static QPen getPen(QPen iniPen, bool &ok); //静态函数private slots:void on_btnColor_clicked();
private:Ui::QWDialogPen *ui;
};#endif // QWDIALOGPEN_H
1.2.3 qwdialogpen.cpp
#include "qwdialogpen.h"
#include "ui_qwdialogpen.h"#include <QColorDialog>QWDialogPen::QWDialogPen(QWidget *parent) :QDialog(parent),ui(new Ui::QWDialogPen)
{ui->setupUi(this);//“线型”ComboBox的选择项设置ui->comboPenStyle->clear();ui->comboPenStyle->addItem("NoPen",0);ui->comboPenStyle->addItem("SolidLine",1);ui->comboPenStyle->addItem("DashLine",2);ui->comboPenStyle->addItem("DotLine",3);ui->comboPenStyle->addItem("DashDotLine",4);ui->comboPenStyle->addItem("DashDotDotLine",5);ui->comboPenStyle->addItem("CustomDashLine",6);ui->comboPenStyle->setCurrentIndex(1);
}QWDialogPen::~QWDialogPen()
{delete ui;
}void QWDialogPen::setPen(QPen pen)
{ //设置QPen,并刷新显示界面m_pen=pen;ui->spinWidth->setValue(pen.width()); //线宽int i=static_cast<int>(pen.style()); //枚举类型转换为整型ui->comboPenStyle->setCurrentIndex(i);QColor color=pen.color();ui->btnColor->setAutoFillBackground(true); //设置颜色按钮的背景色QString str=QString::asprintf("background-color: rgb(%d, %d, %d);",color.red(),color.green(),color.blue());ui->btnColor->setStyleSheet(str);
}QPen QWDialogPen::getPen()
{//获得设置的属性m_pen.setStyle(Qt::PenStyle(ui->comboPenStyle->currentIndex())); //线型m_pen.setWidth(ui->spinWidth->value()); //线宽QColor color;color=ui->btnColor->palette().color(QPalette::Button);m_pen.setColor(color); //颜色return m_pen;
}QPen QWDialogPen::getPen(QPen iniPen,bool &ok)
{ //静态函数,获取QPenQWDialogPen *Dlg=new QWDialogPen; //创建一个对话框Dlg->setPen(iniPen); //设置初始化QPenQPen pen;int ret=Dlg->exec(); //弹出对话框if (ret==QDialog::Accepted){pen=Dlg->getPen(); //获取ok=true; }else{pen=iniPen;ok=false; }delete Dlg; //删除对话框对象return pen; //返回设置的QPen对象
}void QWDialogPen::on_btnColor_clicked()
{//设置颜色QColor color=QColorDialog::getColor();if (color.isValid()){ //用样式表设置QPushButton的背景色QString str=QString::asprintf("background-color: rgb(%d, %d, %d);",color.red(),color.green(),color.blue());ui->btnColor->setStyleSheet(str);}
}
2. 静态链接库的使用
2.1 静态链接库的使用过程
创建一个基于 QMainWindow 的应用程序 LibUser,在项目源程序目录下新建一个include 目录,根据使用的编译器复制不同的文件。
-
若使用MSVC 编译器,将静态库项目 myStaticLib 下的 qwdialogpen.h 和 release 版本的myStaticLib.lib 复制到这个 include 目录下,将 debug 版本的 myStaticLib.lib 更名为myStaticLibd.lib 复制到这个 include 目录下。
-
若使用 MinGW 编译器,就将 libmyStaticLib.a 和 libmyStaticLibd.a (debug 版本)复制到include目录里。

在项目管理目录树里右键单击 LibUser 项目,在快捷菜单里单击“Add Library…”菜单项,在出现的向导对话框里首先选择添加的库类型为“Extermal Library”,在向导第二步设置需要导入的静态库文件(见下图)。

首先选择需要导入的库文件 myStaticLib.lib,连接类型里必须选择 Static,因为这是静态库勾选Add“d”sufix for debug version,使得在 debug 模式下编译应用程序时将自动调用 debug 版本的库文件 myStaticLibd.lib。
设置完成后,Qt Creator 将自动更改项目配置文件 LibUser.pro,增加以下的内容,主要是设置了包含文件和依赖项的路径,增加了 LIBS 设置。
win32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ -lmyStaticLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ -lmyStaticLibdINCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/includewin32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/libmyStaticLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/libmyStaticLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/myStaticLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/myStaticLibd.lib
编译应用程序 LibUser,使用 MSVC 或MinGW 编译器,在 release 或 debug 模式下都可以编译,运行程序效果下图 所示。单击“设置 Pe”按可以设置划线的 Pen 属性,并在主窗体上绘制一个矩形框。

主体程序比较简单,MainWindow类中新增的定义如下:
private:QPen mPen;protected:void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;
paintEvent()事件在窗体上绘制一个矩形,使用了QPen类型的私有变量mPen作为绘图的画笔action_Pen 的响应代码调用静态库里的 QWDialogPen 的静态函数getPen 设置画笔属性。
void MainWindow::paintEvent(QPaintEvent *event)
{//绘图Q_UNUSED(event);QPainter painter(this);QRect rect(0,0,width(),height()); //viewport矩形区painter.setViewport(rect);//设置Viewportpainter.setWindow(0,0,100,50); // 设置窗口大小,逻辑坐标painter.setRenderHint(QPainter::Antialiasing);painter.setRenderHint(QPainter::TextAntialiasing);painter.setPen(mPen);painter.drawRect(10,10,80,30);
}void MainWindow::on_action_Pen_triggered()
{//设置Penbool ok=false;QPen pen=QWDialogPen::getPen(mPen,ok);if (ok){mPen=pen;this->repaint();}
}
本实例将一个可视化设计的对话框 QWDialogPen 封装到一个静态库里,也可以将任何 C++类、函数封装到静态库,其实现方法是一样的。
2.2 代码
2.2.1 可视化UI设计框架

2.2.2 LibUser.pro
#-------------------------------------------------
#
# Project created by QtCreator 2017-04-05T00:25:31
#
#-------------------------------------------------QT += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = LibUser
TEMPLATE = app# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0SOURCES += main.cpp\mainwindow.cppHEADERS += mainwindow.hFORMS += mainwindow.uiwin32:CONFIG(release, debug|release): LIBS += -L$$PWD/include/ -lmyStaticLib
else:win32:CONFIG(debug, debug|release): LIBS += -L$$PWD/include/ -lmyStaticLibdINCLUDEPATH += $$PWD/include
DEPENDPATH += $$PWD/includewin32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/libmyStaticLib.a
else:win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/libmyStaticLibd.a
else:win32:!win32-g++:CONFIG(release, debug|release): PRE_TARGETDEPS += $$PWD/include/myStaticLib.lib
else:win32:!win32-g++:CONFIG(debug, debug|release): PRE_TARGETDEPS += $$PWD/include/myStaticLibd.lib
2.2.3 mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>#include <QPen>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTprivate:QPen mPen;protected:void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE;public:explicit MainWindow(QWidget *parent = 0);~MainWindow();private slots:
// void on_pushButton_clicked();void on_action_Pen_triggered();private:Ui::MainWindow *ui;
};#endif // MAINWINDOW_H
2.2.4 mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"#include "qwdialogpen.h"
#include <QPainter>MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::paintEvent(QPaintEvent *event)
{//绘图Q_UNUSED(event);QPainter painter(this);QRect rect(0,0,width(),height()); //viewport矩形区painter.setViewport(rect);//设置Viewportpainter.setWindow(0,0,100,50); // 设置窗口大小,逻辑坐标painter.setRenderHint(QPainter::Antialiasing);painter.setRenderHint(QPainter::TextAntialiasing);painter.setPen(mPen);painter.drawRect(10,10,80,30);
}void MainWindow::on_action_Pen_triggered()
{//设置Penbool ok=false;QPen pen=QWDialogPen::getPen(mPen,ok);if (ok){mPen=pen;this->repaint();}
}相关文章:
12-3_Qt 5.9 C++开发指南_创建和使用静态链接库
第12章中的静态链接库和动态链接库介绍,都是以UI操作的方式进行,真正在实践中,可以参考UI操作产生的代码来实现同样的功能。 文章目录 1. 创建静态链接库1.1 创建静态链接库过程1.2 静态链接库代码1.2.1 静态链接库可视化UI设计框架1.2.2 qw…...
conda模式安装paddlepaddle2.4.2版本
conda模式安装paddlepaddle2.4.2版本 一、下载anaconda 2022.10 window-x86-x64.exe 清华镜像源Index of /anaconda/archive/ | 清华大学开源软件镜像站 | Tsinghua Open Source Mirror,进去后根据自己的需要选择对应的版本下载 下载安装到磁盘空闲空间要大的D:\Pr…...
英语疑问句
文章目录 一般疑问句特殊疑问句 一般疑问句 英语肯定句怎么改成一般疑问句? 1.假如句子中有"情态动词、助动词、be动词"则直接提前。2.假如句子,只有实义动词,就要借助"do,does,did"放在句子前面,并将实义动词改为"…...
k8s证书更新,kubeadm安装的K8S证书过期后无法使用后证书更新方法
k8s证书更新 1. 查看证书过期时间 #通过文件查看证书过期时间 for item in find /etc/kubernetes/pki -maxdepth 2 -name "*.crt";do openssl x509 -in $item -text -noout| grep Not;echo $item;done #通过命令查看证书过期时间 kubeadm certs check-expirationk8…...
java实现日期拆分的方法
java实现日期拆分的方法 本文实例讲述了java实现日期拆分的方法。分享给大家供大家参考。具体如下: 如:计算6-1至6-5之间的日期天数及具体日期,预期的结果是得到: 6-1 6-2 6-3 6-4 6-5 以下是我利用java 日历类做的实现&am…...
Ansible之playbook剧本编写
一、playbook的相关知识 1.playbook简介 playbook是 一个不同于使用Ansible命令行执行方式的模式,其功能更强大灵活。简单来说,playbook是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复…...
【ChatGPT辅助学Rust | 基础系列 | Hello, Rust】编写并运行第一个Rust程序
文章目录 前言一,创建项目二,两种编译方式1. 使用rustc编译器编译2. 使用Cargo编译 总结 前言 在开始学习任何一门新的编程语言时,都会从编写一个简单的 “Hello, World!” 程序开始。在这一章节中,将会介绍如何在Rust中编写并运…...
自监督去噪:Noise2Noise原理及实现(Pytorch)
文章地址:https://arxiv.org/abs/1803.04189 ICML github 代码: https://github.com/NVlabs/noise2noise 本文整理和参考代码: https://github.com/shivamsaboo17/Deep-Restore-PyTorch 文章目录 1. 理论背景2. 实验结果3. 代码实现(1) 网络结构(2) 数据加载(3) 网络…...
BES2700 SDK绝对时间获取方法
1 代码 2 实验 log 需要换算下...
Closure Table-树形多级关系数据库设计(MySql)
一般树形多级关系数据库设计,比较普遍的就是四种方法:(具体见 SQL Anti-patterns这本书) Adjacency List:每一条记录存parent_id Path Enumerations:每一条记录存整个tree path经过的node枚举(…...
【SQL应知应会】表分区(一)• MySQL版
欢迎来到爱书不爱输的程序猿的博客, 本博客致力于知识分享,与更多的人进行学习交流 本文收录于SQL应知应会专栏,本专栏主要用于记录对于数据库的一些学习,有基础也有进阶,有MySQL也有Oracle 分区表 • MySQL版 一、分区表1.非分区表2.分区表2…...
java语法基础-- 变量、标识符、关键字
学习目标 教学目标重点难点1.掌握变量的相关概念。2.掌握Java中数据类型的划分。3.掌握8种基本数据类型的使用。4.掌握数据类型的转换方式。5.掌握各个运算符,表达式的作用。6.可以编写简单的Java应用程序。1.对变量的理解。2.基本数据类型的相关信息的记忆。3.数据…...
[STL]stack和queue模拟实现
[STL]stack和queue模拟实现 文章目录 [STL]stack和queue模拟实现stack模拟实现queue模拟实现 stack模拟实现 stack是一种容器适配器,标准容器vector、deque、list都可以作为实现stack的底层数据结构,因为它们都具备以下功能: empty…...
汽车销售企业消费税,增值税高怎么合理解决?
《税筹顾问》专注于园区招商、企业税务筹划,合理合规助力企业节税! 汽车行业一直处于炙手可热的阶段,这是因为个人或者家庭用车的需求在不断攀升,同时随着新能源的技术进一步应用到汽车领域,一度实现了汽车销量的翻倍。…...
flask数据库操作
本文将详细介绍在Flask Web应用中如何设计数据库模型,并使用Flask-SQLAlchemy等扩展进行数据库操作的最佳实践。内容涵盖数据模型设计,ORM使用,关系映射,查询方法,事务处理等方面。通过本文,您可以掌握Flask数据库应用的基本知识。 Flask作为一个流行的Python Web框架,提供了高…...
【C++】 哈希
一、哈希的概念及其性质 1.哈希概念 在顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查找一个元素时,必须要经过关键码的多次比较。比如顺序表需要从第一个元素依次向后进行查找,顺序查找时间复杂度为…...
TCP三次握手和四次挥手以及11种状态(二)
11种状态 1、一开始,建立连接之前服务器和客户端的状态都为CLOSED; 2、服务器创建socket后开始监听,变为LISTEN状态; 3、客户端请求建立连接,向服务器发送SYN报文,客户端的状态变味SYN_SENT; 4、…...
【华为OD】运维日志排序
题目描述: 运维工程师采集到某产品线网运行一天产生的日志n条,现需根据日志时间先后顺序对日志进行排序,日志时间格式为H:M:S.N。 H表示小时(0~23) M表示分钟(0~59) S表示秒(0~59) N表示毫秒(0~999) 时间可能并没有补全,也就是说&…...
Mag-Fluo-4 AM,镁离子荧光探针,是一种有用的细胞内镁离子指示剂
资料编辑|陕西新研博美生物科技有限公司小编MISSwu PART1----产品描述: 镁离子荧光探针Mag-Fluo-4 AM,具细胞膜渗透性,对镁离子(Mg2) 和钙离子(Ca2)的 Kd 值分别是 4.7mM 和 22mM,…...
与 ChatGPT 进行有效交互的几种策略
在这篇文章中,您将了解即时工程。尤其, 如何在提示中提供对响应影响最大的信息什么是角色、正面和负面提示、零样本提示等如何迭代使用提示来利用 ChatGPT 的对话性质 废话不多说直接开始吧!!! 提示原则 快速工程是有…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
【Java学习笔记】Arrays类
Arrays 类 1. 导入包:import java.util.Arrays 2. 常用方法一览表 方法描述Arrays.toString()返回数组的字符串形式Arrays.sort()排序(自然排序和定制排序)Arrays.binarySearch()通过二分搜索法进行查找(前提:数组是…...
《从零掌握MIPI CSI-2: 协议精解与FPGA摄像头开发实战》-- CSI-2 协议详细解析 (一)
CSI-2 协议详细解析 (一) 1. CSI-2层定义(CSI-2 Layer Definitions) 分层结构 :CSI-2协议分为6层: 物理层(PHY Layer) : 定义电气特性、时钟机制和传输介质(导线&#…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
基于IDIG-GAN的小样本电机轴承故障诊断
目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) 梯度归一化(Gradient Normalization) (2) 判别器梯度间隙正则化(Discriminator Gradient Gap Regularization) (3) 自注意力机制(Self-Attention) 3. 完整损失函数 二…...
[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
C# 表达式和运算符(求值顺序)
求值顺序 表达式可以由许多嵌套的子表达式构成。子表达式的求值顺序可以使表达式的最终值发生 变化。 例如,已知表达式3*52,依照子表达式的求值顺序,有两种可能的结果,如图9-3所示。 如果乘法先执行,结果是17。如果5…...
