C 中的 Int 变量在未调用时更改
Int Variable in C Changing When Not Called
提前致歉,我对此很陌生。
我正在尝试根据具有关联分值的 POINTS
数组对“拼字游戏”进行评分。
- 我先得到
word1
的字符串长度。
- 然后我创建一个
for
循环,将小写字母的值减去 97(得到 0 索引)并将其添加到数组中。
您可以忽略其余代码,因为这是问题所在。虽然 stringlength
变量只定义了一次,但我发现它在 for
循环的第二个循环中以某种方式发生了变化。一个四字母单词最初的 stringlength
为 4
,但是 for
循环在第二个 运行 上将其更改为 1
。
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
// Points assigned to each letter of the alphabet
int POINTS[] = { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 };
int main(void) {
// Get input words from both players
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
int stringlength = strlen(word1);
int array[] = {};
int array2[] = {};
//Create an array with each letter
for (int index = 0; index < stringlength; index++) {
//THE BELOW LINE IS WHERE "STRINGLENGTH" CHANGES TO "1" ON THE SECOND LOOP
array[index] = word1[index] - 97;
array2[index] = POINTS[array[index]];
}
int score = 0;
for (int index2 = 0; index2 < stringlength; index2++)
score += array2[index2];
printf("%i", stringlength);
printf("\n");
}
我知道我可以创建一个辅助 stringlength
变量,但我知道这是糟糕的编程,我很想知道我做错了什么。
如有任何帮助,我们将不胜感激。谢谢!
代码中存在多个问题:
int array[] = {};
是语法错误。数组定义必须至少有一个初始值设定项。在您的情况下,您必须定义长度为 stringlength
的 array
以及:
int array[stringlength];
你的编译器似乎接受了这个定义并创建了一个空数组,它的长度不足以存储字母分数:你在两个 for
循环中都有未定义的行为,访问数组元素超出了它们的边界。未定义的行为意味着任何事情都可能发生,包括您观察到的。
在word1[index] - 97
中,你硬编码了'a'
的ASCII值。这是不好的做法,您应该这样写:
word1[index] - 'a'
但是请注意,您在此表达式中还做了 2 个更多的无声假设:
- 你假设
word1
只包含小写字母,应该测试小写字母,因为用户可以键入任何字符串。
- 您假设小写字母形式在执行字符集中是连续的,这对于 ASCII 是正确的,但 C 标准不保证。因为所有现代系统都使用 ASCII 作为标准字符,所以这个假设是可以的。
printf("%i", stringlength);
输出字符串长度,而不是分数。
这里是没有附加数组的修改版本:
#include <cs50.h>
#include <stdio.h>
// Points assigned to each letter of the alphabet
int POINTS[] = { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 };
int main(void) {
// Get input words from both players
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
//Compute the score for player 1
int score1 = 0;
for (int index = 0; word1[index] != '[=12=]'; index++) {
unsigned char c = word1[index];
if (c >= 'a' && c <= 'z') {
// assuming ASCII character set
score1 += POINTS[c - 'a'];
}
}
//Compute the score for player 2
int score2 = 0;
for (int index = 0; word2[index] != '[=12=]'; index++) {
unsigned char c = word2[index];
if (c >= 'a' && c <= 'z') {
// assuming ASCII character set
score2 += POINTS[c - 'a'];
}
}
printf("Player 1: %d\n", score1);
printf("Player 2: %d\n", score2);
return 0;
}
如果你了解函数,你可以写一个函数int compute_score(const char *word)
来避免重复代码并提高可读性。
提前致歉,我对此很陌生。
我正在尝试根据具有关联分值的 POINTS
数组对“拼字游戏”进行评分。
- 我先得到
word1
的字符串长度。 - 然后我创建一个
for
循环,将小写字母的值减去 97(得到 0 索引)并将其添加到数组中。
您可以忽略其余代码,因为这是问题所在。虽然 stringlength
变量只定义了一次,但我发现它在 for
循环的第二个循环中以某种方式发生了变化。一个四字母单词最初的 stringlength
为 4
,但是 for
循环在第二个 运行 上将其更改为 1
。
#include <ctype.h>
#include <cs50.h>
#include <stdio.h>
#include <string.h>
// Points assigned to each letter of the alphabet
int POINTS[] = { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 };
int main(void) {
// Get input words from both players
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
int stringlength = strlen(word1);
int array[] = {};
int array2[] = {};
//Create an array with each letter
for (int index = 0; index < stringlength; index++) {
//THE BELOW LINE IS WHERE "STRINGLENGTH" CHANGES TO "1" ON THE SECOND LOOP
array[index] = word1[index] - 97;
array2[index] = POINTS[array[index]];
}
int score = 0;
for (int index2 = 0; index2 < stringlength; index2++)
score += array2[index2];
printf("%i", stringlength);
printf("\n");
}
我知道我可以创建一个辅助 stringlength
变量,但我知道这是糟糕的编程,我很想知道我做错了什么。
如有任何帮助,我们将不胜感激。谢谢!
代码中存在多个问题:
int array[] = {};
是语法错误。数组定义必须至少有一个初始值设定项。在您的情况下,您必须定义长度为stringlength
的array
以及:int array[stringlength];
你的编译器似乎接受了这个定义并创建了一个空数组,它的长度不足以存储字母分数:你在两个
for
循环中都有未定义的行为,访问数组元素超出了它们的边界。未定义的行为意味着任何事情都可能发生,包括您观察到的。在
word1[index] - 97
中,你硬编码了'a'
的ASCII值。这是不好的做法,您应该这样写:word1[index] - 'a'
但是请注意,您在此表达式中还做了 2 个更多的无声假设:
- 你假设
word1
只包含小写字母,应该测试小写字母,因为用户可以键入任何字符串。 - 您假设小写字母形式在执行字符集中是连续的,这对于 ASCII 是正确的,但 C 标准不保证。因为所有现代系统都使用 ASCII 作为标准字符,所以这个假设是可以的。
- 你假设
printf("%i", stringlength);
输出字符串长度,而不是分数。
这里是没有附加数组的修改版本:
#include <cs50.h>
#include <stdio.h>
// Points assigned to each letter of the alphabet
int POINTS[] = { 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10 };
int main(void) {
// Get input words from both players
string word1 = get_string("Player 1: ");
string word2 = get_string("Player 2: ");
//Compute the score for player 1
int score1 = 0;
for (int index = 0; word1[index] != '[=12=]'; index++) {
unsigned char c = word1[index];
if (c >= 'a' && c <= 'z') {
// assuming ASCII character set
score1 += POINTS[c - 'a'];
}
}
//Compute the score for player 2
int score2 = 0;
for (int index = 0; word2[index] != '[=12=]'; index++) {
unsigned char c = word2[index];
if (c >= 'a' && c <= 'z') {
// assuming ASCII character set
score2 += POINTS[c - 'a'];
}
}
printf("Player 1: %d\n", score1);
printf("Player 2: %d\n", score2);
return 0;
}
如果你了解函数,你可以写一个函数int compute_score(const char *word)
来避免重复代码并提高可读性。