代码在使用char时,在GCC中输出意外/错误的结果。

huangapple go评论53阅读模式
英文:

Code outputs unexpected/wrong results in GCC when using char

问题

我是你的中文翻译,以下是你的代码翻译部分:

我对C语言相当新手,我在使用GCC编译代码时遇到了一些烦人的问题(在Visual Studio上不起作用的代码与GCC上完全相同)。

有时,当我在变量后面使用char时,经过几行代码后,该变量中存储的值会因某种原因更改为0。我花了数小时追踪导致我的代码运行不正确的原因,但无法找出原因。每当我将数据类型从char更改为int时,代码都能按预期工作。值得注意的是,在某些情况下,使用char时:使用volatile或static可以解决问题,在其他情况下,更改变量名称(删除名称中的任何_)可以解决问题,有时删除#include math.lib然后撤消也可以解决问题,而在同一代码中,所有这些更改都停止起作用,结果与预期不同(代码可以运行1次,但在不更改任何内容的情况下再次运行时不起作用)

注意:“u8”代表“unsigned char”,“s8”代表“signed char”。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "...\Projects/type_def.h"
#include "...\Projects/Bitwise_Operations.h"

void continuity();
void Print_Array();
void Scan_Array();
void Sort();
void Binary_Search();
void Binary_Search_For_Duplicates_In_NumberofElements_Below(s8 Below_First_Hit);
void Binary_Search_For_Duplicates_In_NumberofElements_Above(s8 Above_First_Hit);

u8 NumbertoSearchfor, NumberofElements, * array = NULL;

void main() {

    printf("请输入数组元素的数量:");
    scanf("%d", &NumberofElements);

    array = (u8*)malloc(NumberofElements * sizeof(u8));

    //要求用户输入要存储在数组中的值
    printf("请输入要存储在数组中的值:\n");
    Scan_Array(array);

    //对数组进行排序
    Sort(array);

    //要求用户输入要搜索的数字
    printf("\n请输入要搜索的数字");
    scanf("%d", &NumbertoSearchfor);

    //搜索所需的数字
    Binary_Search();

    //释放内存
    continuity();
}

void Print_Array() {
    for (u8 i = 0; i < NumberofElements; i++) {
        printf("%d ", array[i]);
    }
}

void Scan_Array() {
    for (u8 i = 0; i < NumberofElements; i++) {
        scanf("%d", &array[i]);
    }
}

//排序函数
void Sort() {
    for (u8 i = 0; i < (NumberofElements - 1); i++) {
        for (u8 j = 0; j < (NumberofElements - 1) - i; j++) {
            u8 temp;
            if (array[j] > array[j + 1]) {
                temp = array[j];
                array[j] = array[j + 1];
                array[j + 1] = temp;
            }
        }
    }

    //打印排序后的数组
    printf("\n排序后的数组是");
    Print_Array(array);
}

void Binary_Search() {
    u8 start = 0, end = NumberofElements - 1, flag = 0;
    while (start <= end) {
        s8 mid = (start + end) / 2;
        if (NumbertoSearchfor == array[mid]) {
            printf("数字%d在元素%d中找到了", NumbertoSearchfor, mid);
            Binary_Search_For_Duplicates_In_NumberofElements_Below(mid - 1);
            Binary_Search_For_Duplicates_In_NumberofElements_Above(mid + 1);
            flag++;
            break;
        } else if (NumbertoSearchfor > array[mid]) {
            start = mid + 1;
        } else {
            end = mid - 1;
        }
    }
    if (flag == 0) {
        printf("数字%d在此数组中未找到", NumbertoSearchfor);
    }
}

void Binary_Search_For_Duplicates_In_NumberofElements_Below(s8 Below_First_Hit) {
    if ((array[Below_First_Hit] == NumbertoSearchfor) && (Below_First_Hit >= 0)) {
        printf("%d ", Below_First_Hit);
        Binary_Search_For_Duplicates_In_NumberofElements_Below(Below_First_Hit - 1);
    }
}

void Binary_Search_For_Duplicates_In_NumberofElements_Above(s8 Above_First_Hit) {
    if ((array[Above_First_Hit] == NumbertoSearchfor) && (Above_First_Hit < NumberofElements)) {
        printf("%d ", Above_First_Hit);
        Binary_Search_For_Duplicates_In_NumberofElements_Above(Above_First_Hit + 1);
    }
}

void continuity() {
    u8 cont = 0;
    printf("\n是否要继续Y/N\n");
    scanf(" %c", &cont);
    if ((cont == 'Y') || (cont == 'y')) {
        main();
    } else if ((cont == 'N') || (cont == 'n')) {
        printf("感谢使用我们的程序。退出...");
    } else {
        printf("无效的回答。");
        continuity();
    }
}

这是你的完整代码的翻译部分。如果你有任何其他问题或需要进一步的帮助,请随时告诉我。

英文:

I'm fairly new to C and I've been facing some annoying problems while compiling code with GCC (The same exact code that doesn't work on GCC works on visual studio).

Sometimes when I use char with my variables after a few lines of code the value stored in that variable is changed to 0 for some reason. I spent hours tracing what causes my code to run incorrectly and couldn't figure out the reason. Whenever I changed my data type from char to int the code worked as intended. Worth to note that in some instances when I was using char: using volatile or static solved the issue and in other instances changing the variable name (Removing any _ in the name) solved the issue and sometimes deleting #include math.lib and then undo solved the issue and other times in the same code all these changes just stopped working and the outcome was not as expected (the code could work 1 time but when I run it again without changing anything it wouldn't work)

Note: u8 is unsigned char and s8 is signed char.

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "...\Projects/type_def.h"
#include "...\Projects/Bitwise_Operations.h"
void continuity();
void Print_Array();
void Scan_Array();
void Sort();
void Binary_Search();
void Binary_Search_For_Duplicates_In_NumberofElements_Below(s8 Below_First_Hit);
void Binary_Search_For_Duplicates_In_NumberofElements_Above(s8 Above_First_Hit);
u8 NumbertoSearchfor, NumberofElements, * array = NULL;
void main() {
printf("Please enter the number of elements for the array: ");
scanf("%d", &NumberofElements);
array = (u8*)malloc(NumberofElements * sizeof(u8));
//Asking the user to enter the values to be stored in the array
printf("Please enter the values stored in the array:\n");
Scan_Array(array);
//Sorting the array
Sort(array);
//Asking the user to enter the number he wants to search for
printf("\nPlease enter the number you want to search for: ");
scanf("%d", &NumbertoSearchfor);
//Searching for the required number
Binary_Search();
//free((void*) arr);
continuity();
}
void Print_Array() {
for (u8 i = 0; i < NumberofElements; i++) {
printf("%d ", array[i]);
}
}
void Scan_Array() {
for (u8 i = 0; i < NumberofElements; i++) {
scanf("%d", &array[i]);
}
}
//Sorting function
void Sort() {
for (u8 i = 0; i < (NumberofElements - 1); i++) {
for (u8 j = 0; j < (NumberofElements - 1) - i; j++) {
u8 temp;
if (array[j] > array[j + 1]) {
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
// Printing the sorted array
printf("\nThe sorted array is: ");
Print_Array(array);
}
void Binary_Search() {
u8 start = 0, end = NumberofElements - 1, flag = 0;
while (start <= end) {
s8  mid = (start + end) / 2;
if (NumbertoSearchfor == array[mid]) {
printf("The number %d was found in elements %d ", NumbertoSearchfor, mid);
Binary_Search_For_Duplicates_In_NumberofElements_Below(mid - 1);
Binary_Search_For_Duplicates_In_NumberofElements_Above(mid + 1);
flag++;
break;
}
else if (NumbertoSearchfor > array[mid]) {
start = mid + 1;
}
else {
end = mid - 1;
}
}
if (flag == 0) {
printf("The number %d was not found in this array", NumbertoSearchfor);
}
}
void Binary_Search_For_Duplicates_In_NumberofElements_Below(s8 Below_First_Hit) {
if ((array[Below_First_Hit] == NumbertoSearchfor) && (Below_First_Hit >= 0)) {
printf("%d ", Below_First_Hit);
Binary_Search_For_Duplicates_In_NumberofElements_Below(Below_First_Hit - 1);
}
}
void Binary_Search_For_Duplicates_In_NumberofElements_Above(s8 Above_First_Hit) {
if ((array[Above_First_Hit] == NumbertoSearchfor) && (Above_First_Hit < NumberofElements)) {
printf("%d ", Above_First_Hit);
Binary_Search_For_Duplicates_In_NumberofElements_Above(Above_First_Hit + 1);
}
}
void continuity() {
u8 cont = 0;
printf("\nDo you want to continue? Y/N\n");
scanf(" %c", &cont);
if ((cont == 'Y') || (cont == 'y')) {
main();
}
else if ((cont == 'N') || (cont == 'n')) {
printf("Thanks for using our program. Exiting ...");
}
else {
printf("Invalid answer.");
continuity();
}
}

This is my full code. It's supposed to take in the Number of elements for an array from the user then use malloc to dynamically allocate the number of bytes needed to make that array then sort the array and used binary search to find a number that a user entered and print the element it was found in. There is 2 other functions to search if the number was found multiple times plus Continuity function is just to check if the user want to re-do the whole thing.

After using multiple printf to trace the problem I found that after this line:

scanf("%d", &NumbertoSearchfor);

the value in NumberofElements is changed to 0 and so the search function outputs incorrect results.

Note: All values I use are from 0-255 for u8 and only use negative with s8 (small numbers that don't even reach 50 or -50)

答案1

得分: 2

在你提到的这行代码中:

scanf("%d", &NumbertoSearchfor);

scanf 中的 %d 格式说明符期望一个 int *,但你实际上传入了一个 char *。使用不匹配的格式说明符会触发未定义行为

实际上,最有可能发生的情况是,由于一个 char 占用1个字节,而一个 int(很可能)占用4个字节,scanf 会在给定地址写入4个字节的数据,超出了相关变量的边界,影响了附近的变量。

如果你想让 scanf 读取一个值并将其放入一个 char 中,你应该使用 %hhd

scanf("%hhd", &NumbertoSearchfor);

在代码的其他地方也存在类似的错误。

英文:

On the line you mentioned:

scanf("%d", &NumbertoSearchfor);

The %d format specifier to scanf is expecting an int * but you're instead passing in a char *. Using a mismatched format specifier triggers undefined behavior.

What is most likely happening in practice is that since a char is 1 byte and an int is (most likely) 4 bytes, scanf is writing 4 bytes worth of data at the given address, writing past the bounds of the variable in question into nearby variables.

You should instead use %hhd if you want scanf to read a value and put it in a char.

scanf("%hhd", &NumbertoSearchfor);

There are similar errors elsewhere in the code.

huangapple
  • 本文由 发表于 2023年6月22日 03:32:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/76526571.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定