如何在C++中打破初始化循环并确保初始化函数仅执行一次?
解决方案
一、让初始化逻辑仅执行一次
你当前代码的核心问题是initialized是函数内的局部变量,每次调用initialize时都会被重置为0,导致每次调用都会执行嵌套循环。要让整个初始化逻辑只运行一次,只需把initialized改为静态局部变量:
void initialize(double weightType) { static int initialized = 0; // 改为静态变量,值会在函数调用间保留 std::cout << initialized << std::endl; if (initialized < 1) { std::cout << initialized << std::endl; for (int wl = 0; wl < layersWeights.size(); wl++) { for (int r = 0; r < layersWeights[wl].size(); r++) { for (int c = 0; c < layersWeights[wl][r].size(); c++) { layersWeights[wl][r][c] = setRandom(); std::cout << layersWeights[wl][r][c] << std::endl; } } } initialized = 1; } }
静态变量只会在第一次调用函数时初始化,后续调用时会沿用之前的值。第一次执行完循环后initialized被设为1,之后再调用initialize就会直接跳过if块,达到仅执行一次的目的。
二、中途打破嵌套循环并终止初始化
如果需要在循环过程中(比如满足某个条件时)直接跳出所有嵌套循环并设置initialized=1,可以用以下两种方式:
方式1:使用标志位
void initialize(double weightType) { static int initialized = 0; std::cout << initialized << std::endl; if (initialized < 1) { std::cout << initialized << std::endl; bool shouldBreak = false; for (int wl = 0; wl < layersWeights.size() && !shouldBreak; wl++) { for (int r = 0; r < layersWeights[wl].size() && !shouldBreak; r++) { for (int c = 0; c < layersWeights[wl][r].size(); c++) { layersWeights[wl][r][c] = setRandom(); std::cout << layersWeights[wl][r][c] << std::endl; // 这里添加终止条件,比如随机值超过阈值 if (layersWeights[wl][r][c] > 0.9) { shouldBreak = true; break; // 跳出最内层循环 } } } } initialized = 1; } }
每层循环都检查shouldBreak标志,一旦标志为true就停止后续循环。
方式2:使用goto(嵌套循环跳出的实用方案)
虽然goto常被诟病,但在嵌套循环中直接跳出到指定位置是它的合理使用场景:
void initialize(double weightType) { static int initialized = 0; std::cout << initialized << std::endl; if (initialized < 1) { std::cout << initialized << std::endl; for (int wl = 0; wl < layersWeights.size(); wl++) { for (int r = 0; r < layersWeights[wl].size(); r++) { for (int c = 0; c < layersWeights[wl][r].size(); c++) { layersWeights[wl][r][c] = setRandom(); std::cout << layersWeights[wl][r][c] << std::endl; // 满足条件时直接跳出所有循环 if (layersWeights[wl][r][c] > 0.9) { goto end_initialization; // 跳转到循环外的标签位置 } } } } end_initialization: initialized = 1; } }
当触发终止条件时,通过goto直接跳转到循环外的end_initialization标签处,然后设置initialized=1,完成终止。
内容的提问来源于stack exchange,提问作者user19618953
相关产品推荐
相关产品推荐

