Initial commit: C++ courseware
This commit is contained in:
commit
4a4ee7c287
1789 files changed
+373489
No files matched your search
@@ -0,0 +1,277 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>C++ 嵌套循环单步可视化</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
background-color: #f4f7f6;
|
||||
color: #333;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
.container {
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
background: white;
|
||||
padding: 20px;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
|
||||
width: 1000px; /* 稍微增加了总宽度 */
|
||||
max-width: 95%;
|
||||
}
|
||||
/* 左侧代码区 */
|
||||
.code-panel {
|
||||
flex: 1.3; /* 给代码区分配更多空间 */
|
||||
background: #1e1e1e;
|
||||
color: #d4d4d4;
|
||||
padding: 20px;
|
||||
border-radius: 8px;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
font-size: 16px;
|
||||
line-height: 1.6;
|
||||
overflow-x: auto; /* 内容超出时显示水平滚动条 */
|
||||
}
|
||||
.code-line {
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
margin: 2px 0;
|
||||
border-left: 4px solid transparent;
|
||||
transition: all 0.3s;
|
||||
white-space: pre; /* 关键修改:强制不换行,保持代码在一行显示 */
|
||||
}
|
||||
.code-line.active {
|
||||
background-color: #063f4c;
|
||||
border-left: 4px solid #4fc1ff;
|
||||
color: #fff;
|
||||
}
|
||||
.keyword { color: #569cd6; }
|
||||
.type { color: #4ec9b0; }
|
||||
.string { color: #ce9178; }
|
||||
|
||||
/* 右侧面板 */
|
||||
.side-panel {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 15px;
|
||||
}
|
||||
/* 状态与控制台 */
|
||||
.panel-box {
|
||||
background: #f8f9fa;
|
||||
border: 1px solid #dee2e6;
|
||||
border-radius: 8px;
|
||||
padding: 15px;
|
||||
flex: 1;
|
||||
}
|
||||
.panel-title {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
color: #6c757d;
|
||||
margin-bottom: 10px;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 1px;
|
||||
}
|
||||
.vars {
|
||||
font-size: 24px;
|
||||
font-family: monospace;
|
||||
font-weight: bold;
|
||||
}
|
||||
.vars span {
|
||||
color: #e83e8c;
|
||||
background: #fdf3f7;
|
||||
padding: 2px 8px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
.status-msg {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
color: #0056b3;
|
||||
background: #cce5ff;
|
||||
padding: 8px;
|
||||
border-radius: 4px;
|
||||
line-height: 1.5;
|
||||
}
|
||||
.console-output {
|
||||
background: #000;
|
||||
color: #0f0;
|
||||
font-family: 'Courier New', Courier, monospace;
|
||||
padding: 10px;
|
||||
border-radius: 4px;
|
||||
height: 120px;
|
||||
white-space: pre-wrap;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
/* 控制按钮 */
|
||||
.controls {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
justify-content: center;
|
||||
margin-top: 10px;
|
||||
}
|
||||
button {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
cursor: pointer;
|
||||
border: none;
|
||||
border-radius: 6px;
|
||||
font-weight: bold;
|
||||
transition: 0.2s;
|
||||
}
|
||||
.btn-prev { background: #6c757d; color: white; }
|
||||
.btn-prev:hover { background: #5a6268; }
|
||||
.btn-next { background: #007bff; color: white; }
|
||||
.btn-next:hover { background: #0056b3; }
|
||||
.btn-reset { background: #dc3545; color: white; }
|
||||
.btn-reset:hover { background: #c82333; }
|
||||
button:disabled { background: #cccccc; cursor: not-allowed; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<!-- 代码区 -->
|
||||
<div class="code-panel">
|
||||
<div id="line-1" class="code-line"><span class="keyword">for</span> (<span class="type">int</span> i = 1; i <= 3; i++) {</div>
|
||||
<div id="line-2" class="code-line"> <span class="keyword">for</span> (<span class="type">int</span> j = 1; j <= 2; j++) {</div>
|
||||
<div id="line-3" class="code-line"> cout << <span class="string">"("</span> << i << <span class="string">", "</span> << j << <span class="string">") "</span>;</div>
|
||||
<div id="line-4" class="code-line"> }</div>
|
||||
<div id="line-5" class="code-line"> cout << endl;</div>
|
||||
<div id="line-6" class="code-line">}</div>
|
||||
</div>
|
||||
|
||||
<!-- 状态与控制区 -->
|
||||
<div class="side-panel">
|
||||
<div class="panel-box">
|
||||
<div class="panel-title">内存中的变量状态</div>
|
||||
<div class="vars">
|
||||
i = <span id="var-i">?</span><br><br>
|
||||
j = <span id="var-j">?</span>
|
||||
</div>
|
||||
<div class="status-msg" id="status-msg">点击“下一步”开始执行程序</div>
|
||||
</div>
|
||||
|
||||
<div class="panel-box">
|
||||
<div class="panel-title">控制台输出 (Console)</div>
|
||||
<div class="console-output" id="console"></div>
|
||||
</div>
|
||||
|
||||
<div class="controls">
|
||||
<button class="btn-prev" id="btn-prev" onclick="prevStep()" disabled>上一步</button>
|
||||
<button class="btn-next" id="btn-next" onclick="nextStep()">下一步</button>
|
||||
<button class="btn-reset" onclick="reset()">重置</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
// 预定义所有执行步骤的状态机
|
||||
const steps = [
|
||||
{ line: null, i: '?', j: '?', out: '', msg: '程序准备就绪,等待外层循环启动。' },
|
||||
|
||||
// i = 1
|
||||
{ line: 1, i: 1, j: '?', out: '', msg: '进入外层循环。初始化 i = 1。' },
|
||||
{ line: 2, i: 1, j: 1, out: '', msg: '外层触发内层!创建全新变量 j,初始化 j = 1。' },
|
||||
{ line: 3, i: 1, j: 1, out: '(1, 1) ', msg: '打印当前 i 和 j 的值。' },
|
||||
{ line: 4, i: 1, j: 1, out: '(1, 1) ', msg: '内层循环一轮结束,准备 j++ 回到行2判断。' },
|
||||
{ line: 2, i: 1, j: 2, out: '(1, 1) ', msg: 'j 增加到 2,满足 j<=2,继续内层。' },
|
||||
{ line: 3, i: 1, j: 2, out: '(1, 1) (1, 2) ', msg: '打印当前 i 和 j 的值。' },
|
||||
{ line: 4, i: 1, j: 2, out: '(1, 1) (1, 2) ', msg: '内层循环一轮结束,准备 j++。' },
|
||||
{ line: 2, i: 1, j: 3, out: '(1, 1) (1, 2) ', msg: 'j 增加到 3,不满足 j<=2,内层循环终止!' },
|
||||
{ line: 5, i: 1, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n', msg: '退出内层大括号,j 被彻底销毁!执行换行。' },
|
||||
{ line: 6, i: 1, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n', msg: '外层第一轮结束,准备 i++ 回到行1判断。' },
|
||||
|
||||
// i = 2
|
||||
{ line: 1, i: 2, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n', msg: 'i 增加到 2,满足 i<=3,进入外层第二轮。' },
|
||||
{ line: 2, i: 2, j: 1, out: '(1, 1) (1, 2) \n', msg: '再次遇到内层循环,重新孕育一个全新的 j = 1!' },
|
||||
{ line: 3, i: 2, j: 1, out: '(1, 1) (1, 2) \n(2, 1) ', msg: '打印当前 i 和 j 的值。' },
|
||||
{ line: 4, i: 2, j: 1, out: '(1, 1) (1, 2) \n(2, 1) ', msg: '内层循环一轮结束,准备 j++。' },
|
||||
{ line: 2, i: 2, j: 2, out: '(1, 1) (1, 2) \n(2, 1) ', msg: 'j 增加到 2,满足 j<=2。' },
|
||||
{ line: 3, i: 2, j: 2, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) ', msg: '打印当前 i 和 j 的值。' },
|
||||
{ line: 4, i: 2, j: 2, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) ', msg: '内层循环一轮结束,准备 j++。' },
|
||||
{ line: 2, i: 2, j: 3, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) ', msg: 'j 增加到 3,不满足 j<=2,内层循环终止!' },
|
||||
{ line: 5, i: 2, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n', msg: '退出内层,j 再次被彻底销毁!执行换行。' },
|
||||
{ line: 6, i: 2, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n', msg: '外层第二轮结束,准备 i++ 回到行1判断。' },
|
||||
|
||||
// i = 3
|
||||
{ line: 1, i: 3, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n', msg: 'i 增加到 3,满足 i<=3,进入外层最后一轮。' },
|
||||
{ line: 2, i: 3, j: 1, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n', msg: '第三次触发内层循环,重新初始化新 j = 1。' },
|
||||
{ line: 3, i: 3, j: 1, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) ', msg: '打印当前 i 和 j 的值。' },
|
||||
{ line: 4, i: 3, j: 1, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) ', msg: '内层循环一轮结束。' },
|
||||
{ line: 2, i: 3, j: 2, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) ', msg: 'j 增加到 2,满足 j<=2。' },
|
||||
{ line: 3, i: 3, j: 2, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) ', msg: '打印最后的值。' },
|
||||
{ line: 4, i: 3, j: 2, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) ', msg: '内层循环一轮结束。' },
|
||||
{ line: 2, i: 3, j: 3, out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) ', msg: 'j 增加到 3,内层循环最后一次终止!' },
|
||||
{ line: 5, i: 3, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) \n', msg: 'j 被销毁。执行最后一次换行。' },
|
||||
{ line: 6, i: 3, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) \n', msg: '外层循环体全部执行完毕。' },
|
||||
|
||||
// 结束
|
||||
{ line: 1, i: 4, j: '销毁 (死亡)', out: '(1, 1) (1, 2) \n(2, 1) (2, 2) \n(3, 1) (3, 2) \n', msg: 'i 增加到 4,不满足 i<=3。外层循环结束!程序完成。' }
|
||||
];
|
||||
|
||||
let currentStep = 0;
|
||||
|
||||
function renderState() {
|
||||
const state = steps[currentStep];
|
||||
|
||||
// 1. 清除所有高亮,设置当前高亮
|
||||
document.querySelectorAll('.code-line').forEach(el => el.classList.remove('active'));
|
||||
if (state.line !== null) {
|
||||
document.getElementById('line-' + state.line).classList.add('active');
|
||||
}
|
||||
|
||||
// 2. 更新变量面板,带有颜色区分销毁状态
|
||||
document.getElementById('var-i').innerText = state.i;
|
||||
const varJ = document.getElementById('var-j');
|
||||
varJ.innerText = state.j;
|
||||
if (state.j === '销毁 (死亡)') {
|
||||
varJ.style.color = '#dc3545';
|
||||
varJ.style.background = '#f8d7da';
|
||||
} else {
|
||||
varJ.style.color = '#e83e8c';
|
||||
varJ.style.background = '#fdf3f7';
|
||||
}
|
||||
|
||||
// 3. 更新控制台和提示信息
|
||||
document.getElementById('console').innerText = state.out;
|
||||
document.getElementById('status-msg').innerText = state.msg;
|
||||
|
||||
// 4. 更新按钮状态
|
||||
document.getElementById('btn-prev').disabled = currentStep === 0;
|
||||
document.getElementById('btn-next').disabled = currentStep === steps.length - 1;
|
||||
|
||||
// 控制台自动滚动到底部
|
||||
const consoleEl = document.getElementById('console');
|
||||
consoleEl.scrollTop = consoleEl.scrollHeight;
|
||||
}
|
||||
|
||||
function nextStep() {
|
||||
if (currentStep < steps.length - 1) {
|
||||
currentStep++;
|
||||
renderState();
|
||||
}
|
||||
}
|
||||
|
||||
function prevStep() {
|
||||
if (currentStep > 0) {
|
||||
currentStep--;
|
||||
renderState();
|
||||
}
|
||||
}
|
||||
|
||||
function reset() {
|
||||
currentStep = 0;
|
||||
renderState();
|
||||
}
|
||||
|
||||
// 初始化渲染
|
||||
renderState();
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user