【发布时间】:2018-02-07 06:49:33
【问题描述】:
这有点奇怪,imo,我有一个用于比较的 for 循环 使用函数的返回值。
for (size_t i = 0; i < func(val); i++) {
printf("Value from array modified in func = %u", values[i]);
}
问题是循环似乎在函数完成之前运行,如果在被调用函数中有一个 printf,则在循环输出之前会出现一些输出,这是预期的,有些是在预期之后,而不是预期的。该函数仅在 for 循环比较中调用,因此输出应该全部发生在 for 循环的输出之前。如果我使用 var 代替,例如:
size_t temp = func(val);
for (size_t i = 0; i < temp; i++) {
printf("Value from array modified in func = %u", values[i]);
}
然后一切正常,这对我来说很奇怪,我没有使用线程所以这应该都是同步的吧?那么为什么循环不等待 func(val) 返回呢?
这是原始代码(剪掉一堆cmets):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdlib.h>
#define SUITS 4
#define FACES 13
#define CARDS 52
#define HAND 5
typedef struct {
unsigned int suit;
unsigned int face;
} card;
size_t checkX(card hand[HAND], unsigned int faces[HAND], unsigned int num);
int main() {
card hand[HAND] = {{1,1},{1,7},{1,1},{1,4},{1,7}};
const char *suit[SUITS] = {"Hearts", "Diamonds", "Clubs", "Spades"};
const char *face[FACES] = {"Ace", "Deuce", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Jack", "Queen", "King"};
unsigned int matchingFaces[HAND] = {0};
for (size_t i = 0; i < checkX(hand, matchingFaces, 2); ++i) {
printf("Pair of %s%s\n", face[matchingFaces[i]], matchingFaces[i] == 5 ? "es" : "s");
}
}
size_t checkX(card hand[HAND], unsigned int faces[HAND], unsigned int num) {
size_t facePos = 0;
for (size_t i = 0; i < HAND - 1; i++) {
size_t count = 1;
for (size_t j = i + 1; j < HAND; j++) {
printf("%u == %u && %u != %u\n", hand[i].face, hand[j].face, hand[i].face, faces[facePos]);
if (hand[i].face == hand[j].face && hand[i].face != faces[facePos]) count++;
}
faces[facePos] = hand[i].face;
if (count == num) facePos++;
}
return facePos;
}
其中一些不是我的代码,我得到了一个基本的洗牌类型的程序,并告诉我修改它以处理一手牌并检查一对/三类。就像我说的那样,当我将 checkX 的返回值设置为变量然后将 i 与其进行比较而不是直接进行比较时,这确实有效,我只是不知道为什么。我已经尝试禁用 gcc 优化,但似乎没有什么不同。
直接函数比较的输出:
1 == 7 && 1 != 0
1 == 1 && 1 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
7 == 1 && 7 != 0
7 == 4 && 7 != 0
7 == 7 && 7 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
4 == 7 && 4 != 1
Pair of Deuces
1 == 7 && 1 != 1
1 == 1 && 1 != 1
1 == 4 && 1 != 1
1 == 7 && 1 != 1
7 == 1 && 7 != 1
7 == 4 && 7 != 1
7 == 7 && 7 != 1
1 == 4 && 1 != 7
1 == 7 && 1 != 7
4 == 7 && 4 != 1
使用变量间接比较func的输出:
1 == 7 && 1 != 0
1 == 1 && 1 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
7 == 1 && 7 != 0
7 == 4 && 7 != 0
7 == 7 && 7 != 0
1 == 4 && 1 != 0
1 == 7 && 1 != 0
4 == 7 && 4 != 1
Pair of Deuces
Pair of Eights
我知道这段代码不是最好的,但我必须使用给定的代码,只需要让它工作,所以这个问题只是出于好奇。
【问题讨论】:
-
你意识到
func()每次都通过循环被调用?如果它是一个常量值,那么只使用 var 会更有效... -
在无关紧要的注意事项上,始终记得在调用函数之前声明函数原型。如果没有声明函数,编译器将不得不猜测,而且并不总是能够正确猜测。
-
我愿意,我只是把它放在这里,因为它并不重要。不过我现在会添加它。
-
目前尚不清楚您认为此输出到底有什么问题。在每次循环迭代时调用该函数,并在每次迭代时打印输出。在某些迭代中,循环体也会打印一些东西。您是否希望所有检查都在循环体的所有执行之前、之后或其他什么时候发生?
-
哦...这更有意义,我认为 checkX() 将被评估一次并且循环将运行。我不知道每次运行循环都会调用 checkX() 。感谢大家为我解决这个问题。