Неверный вывод при печати целочисленного массива - PullRequest
0 голосов
/ 25 апреля 2019

Я хотел создать общую функцию массива печати. Эта функция печатает элементы массива в зависимости от типа данных.

#include "utilities.h"

//type : 0 ->int
//     : 1->char
void print_array(void *arr, int length, int type){
    int i = 0;

    for(i=0;i<length;i++){
        switch(type) {
            case 0:
                printf("Integer %d  %d\n", (int*)(arr+i));
                break;
            case 1:
               printf("%c \n", (char*)(arr+i));
               break;
            case 2:
                printf("%s \n", (char*)(arr+i));
                break;
            case 3:
                printf("%x \n", (int*)(arr+i));
                break;
            default:
                printf("Format not supported yet. %d \n",type);
                return;

        }
    }
}


void test_print_array(){
    int int_arr[3] = {0,1,2};
    print_array(int_arr,3,0);

}

int main(){
    test_print_array();
    return 0;
}

Я получаю вывод

Целое число -486474964

Целое число -486474963

Целое число -486474962

Вместо 0,1,2

Я также попытался использовать arr [i] вместо (int *) (arr + i), но при этом получаю ошибки компилятора.

Ответы [ 2 ]

3 голосов
/ 25 апреля 2019

Вы используете арифметику указателей для типа void*, размер которого неизвестен.Вы должны привести указатель до , выполнив арифметику, но в любом случае использовать обозначение массива будет более понятно.

#include <stdio.h>

void print_array(void *arr, int length, int type){
    int i = 0;

    for(i=0;i<length;i++){
        switch(type) {
            case 0:
                printf("int %d\n", ((int*)arr)[i]);
                break;
            case 1:
                printf("char %c\n", ((char*)arr)[i]);
                break;
            case 2:
                printf("string %s \n", ((char**)arr)[i]);
                break;
            case 3:
                printf("hex %X\n", ((unsigned*)arr)[i]);
                break;
            default:
                printf("Format not supported yet. %d \n",type);
                return;

        }
    }
}

void test_int_array(){
    int int_arr[3] = {0, 1, 2};
    print_array(int_arr, 3, 0);

}

void test_char_array(){
    char char_arr[3] = {'x', 'y', 'z'};
    print_array(char_arr, 3, 1);

}

void test_str_array(){
    char *str_arr[3] = {"one", "two", "three"};
    print_array(str_arr, 3, 2);

}

void test_uns_array(){
    unsigned uns_arr[3] = {26, 27, 28};
    print_array(uns_arr, 3, 3);

}

int main(){
    test_int_array();
    test_char_array();
    test_str_array();
    test_uns_array();
    return 0;
}

Вывод программы:

int 0
int 1
int 2
char x
char y
char z
string one 
string two 
string three 
hex 1A
hex 1B
hex 1C
0 голосов
/ 25 апреля 2019

Общая функция массива печати склонна к неопределенному поведению (UB), если ссылка на данные не выровнена правильно и не имеет допустимого значения.

Сказав это, попробуйте

//printf("Integer %d  %d\n", (int*)(arr+i));
//              vv-------- print a `%`
printf("Integer %%d  %d\n", ((int*)arr)[i]);
//                          ^---------^ form a `int *` and then use [i]

Добавление i к void* - это UB. Приведите указатель void * сначала к нужному типу указателя, затем используйте индекс [i].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...