LINUX.ORG.RU

[C] long long int и int


0

0

Как(можно ли вообще) правильно передавать в функцию указатель на массив из элементов как long long int, так и int?
Чую надо определять формальный параметр с типом (void *)?

1) А чего не С++? Шаблон сюда бы...

2) Что нужно делать с массивом-то? Может, просто перегрузить эту функцию и все?

3) Можно передавать указатель на void и тип данных, что по этому указателю лежат, а потом if'ами все разрулить. Или, например, union для тех же целей:

typedef enum IntType
{
  INT,
  LONG_LONG_INT
} IntType;

struct UniversalInt
{
  IntType type;
  union
  {
    int i;
    long long int lli;
  } value;
};

kulti ★★ ()

потом придется передавать параметр, чтобы узнать тип, и приводить к нему. может лучше две функции

lfunc(long long *ll)  и func(int *i)

rg-400 ()
Ответ на: комментарий от Zodd

ммм.. наверное я неправильно выразился например есть такой код:

#include <stdio.h>

void func(long long int *arr);

int main() {
	int a[6] = { 1, 2, 3, 4, 4, 6 };

	func((long long int*) a);
	printf("%i\n", a[3]);
	return 0;
}


void func(long long int *arr) {
	arr[1] = 100;
}

func должна принимать как (int *), так и (long long int *). Но данный код работает неправильно, т.к long long int имеет размер 8 байт, а int - 4. Тем самым значение 100 записывается не в a[1], а в a[2]. Я так понимаю, надо дополнительно передавать размер элемента массива

sol_linux ★★ ()

Здесь надо исходить от абстракции указанной функции. Либо тип + void *, либо две функции, как уже сказали предыдущие ораторы.

bk_ ★★ ()
Ответ на: комментарий от sol_linux

1. Через шаблоны

template <class T> func(T* i)
{
...
}

2. Перегрузка функции

func(int* i){...};

func((long long int*) i){...};

3. Создать разные функции как уже сказали

lfunc(long long *ll)  и func(int *i)

Zodd ★★★★★ ()
Ответ на: комментарий от sol_linux

Дык, я ж перед предложением шаблонов про плюсы не зря, наверно, спросил? ;) А про перегрузку, да, подзабыл С =) Две функции, в данном случае, своего рода перегрузка - именно это и имелось в виду. Удачи.

kulti ★★ ()
Ответ на: комментарий от sol_linux
enum {
        INT = 1,
        LL = 2
} typedef typeInt;

void
lfunc (long long * p, int size)
{
        int i;
        for(i = 0; i < size; i++) {
                printf("%lld\n", p[i]);
        }
}
void
ifunc (int *p, int size)
{
        int i;
        for(i = 0; i < size; i++) {
                printf("%d\n", p[i]);
        }
}
void 
func (void *p, typeInt t, int size)
{      

        switch (t) {
                case LL:
                       lfunc((long long *)p, size);
                       break;
                case INT: 
                       ifunc((int *)p, size);
                       break;
                default:
                       printf("err");
        }   
}
rg-400 ()
Ответ на: комментарий от kulti

1) А чего не С++? Шаблон сюда бы...

В плюсах уже есть long long?

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

> Еще раз, в С++ уже есть long long?

в gcc/msvc/icc есть как расширение( т.е. можно использовать ), если говорить про стандарт - будет в С++0х

ahonimous ()
Ответ на: комментарий от anonymous

частично поддерживаемые целочисленные типы

Как это пониать? И да, цитату из стандарта пожалуйста.

Dudraug ★★★★★ ()
Ответ на: комментарий от ahonimous

Ну когда будет тогда посмотрим, а расширение - это все же не стандарт.

Dudraug ★★★★★ ()

Первый способ:

#define my_func(ptr)                                 \
({                                                   \
     switch(sizeof(*ptr)) {                          \
         case(sizeof(int))  : func_int(ptr);  break; \
         case(sizeof(long)) : func_long(ptr); break; \
     }                                               \
})

Второй способ:

     my_func(int *, long *);

Но я бы одну функцию для двух типов делать бы не стал, потому что это запутывает код программы.

ttnl ★★★★★ ()
Ответ на: комментарий от Dudraug

>>Ещё один BDSM-программист.

Обоснуй.

Обоснования нет. Просто интуиция мне подсказывает что этот long long int ему не нужен. Редко используемые вещи лучше использовать редко^W^W вообще не использовать. Скорее всего тут что-то одно из двух, либо ТС не понял как решить свою задачу без long long int, либо этот топик тупо для троллинга.

pathfinder ★★★★ ()
Ответ на: комментарий от pathfinder

Использование типа из стандарта не нужно? Ну толсто же, ну.

Dudraug ★★★★★ ()
Ответ на: комментарий от pathfinder

Просто интуиция мне подсказывает что этот long long int ему не нужен.

А если это - смещение в файле или его размер?

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от Eddy_Em

Ну например смещение можно поизголяться и уложиться в int, если несколько смещений подряд делать и запоминать в массиве, если его запоминать надо. С размером уже сложнее, да.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

смещение можно поизголяться и уложиться в int, если несколько смещений подряд делать и запоминать в массиве

Приведу простой пример: парсер логов сквида (будем считать, что этот лог не ротируется для возможности доступа к самым старым данным по статистике). Для ускорения поиска по датам производится элементарное кэширование - в отдельном файле запоминаются позиции начала каждого дня. И потом проще один раз сделать fseek с SEEK_SET, чем сотни раз делать fseek с SEEK_CUR.

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от pathfinder

Я здесь не вижу long long int

А off_t по-вашему что? На 64-битных машинах по умолчанию он и есть long long, на 32-битных - зависит от define'ов (_LARGEFILE64_SOURCE и т.п.).

Eddy_Em ☆☆☆☆☆ ()
Ответ на: комментарий от pathfinder

Ммм.. возможно вы и правы. У меня есть структура, есть поле содержащее 13 значный штрихкод. Конечно можно было использовать массив символов, но я почему то выбрал unisgned long long int

sol_linux ★★ ()
Ответ на: комментарий от sol_linux

>У меня есть структура, есть поле содержащее 13 значный штрихкод.

Конечно можно было использовать массив символов, но я почему то

выбрал unisgned long long int



Выбери тогда переносимый тип с фиксированным размеров. uint64_t, например

ttnl ★★★★★ ()
Ответ на: комментарий от Eddy_Em

>А off_t по-вашему что? На 64-битных машинах по умолчанию...

Да какая разница. off_t == long long - это твое предположение, не более того. Вся эта чехарда типами данных на разных платформах может привести к тому, что ты напутаешь что-нибудь и не заметишь этого. Потом будешь долго искать ошибку.

Если написано, что переменная принимает тип off_t. То лучше работать именно с типом off_t и не делать лишних предположений.

pathfinder ★★★★ ()
Ответ на: комментарий от ttnl

>Выбери тогда переносимый тип с фиксированным размеров. uint64_t, например

А вот это здравая мысль. Одобряю. :)

pathfinder ★★★★ ()
Ответ на: комментарий от sol_linux

зачем тогда нужен был массив int.

есть структура, есть поле содержащее 13 значный штрихкод


использовать тип этого поля

rg-400 ()
Ответ на: комментарий от ttnl

Выбери тогда переносимый тип с фиксированным размеров. uint64_t, например

long long на сколько я знаю имеет фиксированный размер.

Dudraug ★★★★★ ()
Ответ на: комментарий от Dudraug

>long long на сколько я знаю имеет фиксированный размер.

Оно вроде бы так, но uint64_t очень трудно понять как-то иначе. А вот с этими префиксами long и short какая-то неразбериха. Никто не гарантирует, что в будущем какую-нибудь креативную личность не посетит светлая идея.

Я вот заходил на википедию http://en.wikipedia.org/wiki/64-bit там в разделе «Specific C-language data models» есть таблица. По ней видно, что даже в рамках 64 бит нет единства.

pathfinder ★★★★ ()
Ответ на: комментарий от pathfinder

Никто не гарантирует, что в будущем какую-нибудь креативную личность не посетит светлая идея.

Размер long long вроде как закреплен в с99, хотя могу ошибаться.

Dudraug ★★★★★ ()
Ответ на: комментарий от rg-400

ниасилил

Искал, но так и не нашел в стандарте упоминание про фиксированный размер long long int в n-байт. Может Dudraug сможет найти.

pathfinder ★★★★ ()
Ответ на: комментарий от LamerOk

Школоте не понять. © )))

Да дело в нешколоте, просто не ожидал, что на винде и линуксах в 64битных системах i386 long разные.

Dudraug ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.