PDA

Просмотр полной версии : нид хелп по С


olesy
16.05.2010, 22:42
народ оч нада срочно помогите с заданием :

1)в динамическом массиве лент определить количество лент, которые не содержат ни одной цифры

2)в целочисленного массиве каждый его элемент изменить, оставив значимыми лишь четыре младшие биты его двоичного представления (остальные битов нулевые)

sn0w
16.05.2010, 22:51
каких лент? чето я не знаю че это такое

olesy
16.05.2010, 23:12
ну ето перевод с укринского если без перевода то лента назыветса "стрічка", можна назвать "строки"

Ra$cal
16.05.2010, 23:16
ай лолд. вы вообще на пары то ходили? из двух вариантов перевода (лента и строка) по программированию выбрать ленту... А вообще раздел специальный есть - повыше висит, прилепленный.

olesy
16.05.2010, 23:19
если ето сюда (https://forum.antichat.ru/thread122076.html) то незаметил сразу

d_x
16.05.2010, 23:40
Первое задание на чистом Си:


#include "stdio.h"
#include "string.h"

int main()
{
int count = 5;
int good = 0;
int i, j, len, num = 0;

char** arr = malloc(sizeof(char*) * count);

arr[0] = "string 1";
arr[1] = "string 2";
arr[2] = "string without numbers";
arr[3] = "also, no numbers";
arr[4] = "str 5";

printf("Strings that do not contain any numbers:\n");

for(i=0; i<count; i++)
{
good = 1;

for(j=0, len = strlen(arr[i]); j < len; j++)
{
if(arr[i][j] >= 48 && arr[i][j] <= 57)
{
good = 0;
break;
}
}

if(good)
{
num++;
printf("\n%s", arr[i]);
}
}

printf("\n\nTotal number: %u", num);

free(arr);
return 0;
}

d_x
16.05.2010, 23:49
Второе задание на Си:


#include "stdio.h"

int main()
{
int arr[] = { 1, 2, 3, 100, 500, 10000, 123 };
int i, len;

for(i = 0, len = sizeof(arr)/sizeof(int); i < len; i++)
{
arr[i] &= 0xF;
printf("%u\n", arr[i]);
}

free(arr);
return 0;
}

olesy
17.05.2010, 01:01
спасибо помог

greki_hoy
17.05.2010, 03:53
Второе задание на Си:


#include "stdio.h"

int main()
{
int arr[] = { 1, 2, 3, 100, 500, 10000, 123 };
int i, len;

for(i = 0, len = sizeof(arr)/sizeof(int); i < len; i++)
{
arr[i] &= 0xF;
printf("%u\n", arr[i]);
}

free(arr);
return 0;
}


освобождаете массив в стеке сильно :)
sizeof(arr)/sizeof(int) плохо
sizeof(arr)/sizeof(arr[0]) хорошо
sizeof(arr)/sizeof(arr[0]) вернет size_t 32 битное значение в x32 системе и 64 битное в x64 но из за присваивания его переменной len типа int
потеряете 32 старших бита в x64 системе не сможете обрабатывать большие массивы
так как int и в x32 и в x64 32 бита в отличии от size_t
результата операции sizeof которая на x32 32 бита а на x64 64 бита :)
в первом задании у Вас тоже ахтунг с типами :)

d_x
17.05.2010, 10:41
За поправки спасибо. На си вообще никогда не программировал практически, поэтому руководствовался правилом "нет предупреждений и программа работает - хорошо".

освобождаете массив в стеке сильно
Почему-то подумалось, что это динамическая память.

sizeof(arr)/sizeof(int) плохо
sizeof(arr)/sizeof(arr[0]) хорошо
sizeof(arr)/sizeof(arr[0]) вернет size_t 32 битное значение в x32 системе и 64 битное в x64 но из за присваивания его переменной len типа int
потеряете 32 старших бита в x64 системе не сможете обрабатывать большие массивы
так как int и в x32 и в x64 32 бита в отличии от size_t
А в чем тут проблема, если int у нас в любой системе 32 бита, судя по Вашим словам, то как sizeof(arr[0]) может вернуть 64 бита, ведь arr - массив int'ов?

У меня система x64, sizeof(arr[0]) возвращает 4, и sizeof(int) - также 4, не вижу тут проблем. Попробовал в VS2008 и gcc.

greki_hoy
17.05.2010, 12:54
2 d_x

int i, len;
for(i = 0, len = sizeof(arr)/sizeof(arr[0]); i < len; i++)
//...
sizeof(arr)/sizeof(arr[0]) это выражение после вычисления
на x64 имеет размер 64 значащих бита потом
в результате присваивания
len = sizeof(arr)/sizeof(arr[0])
обрезаются старшие 32 бита результат будет неверный в len
но на 32 битной системе с этим проблем не будет
но могут быть другие :)
sizeof(arr)/sizeof(arr[0]) вернет 32 значащих бита рассмариваемых
как беззнаковое число но у Вас в len может оказатся
отрицательное число после присваивания (если 31 бит включен
будет он рассматривается как знак в len) так как у Вас len знаковая
переменная то это условие i < len никогда не выполнится
не будет ни одной итерации цикла :)

d_x
17.05.2010, 13:53
sizeof(arr)/sizeof(arr[0]) вернет 32 значащих бита рассмариваемых
как беззнаковое число но у Вас в len может оказатся
отрицательное число после присваивания (если 31 бит включен
будет он рассматривается как знак в len) так как у Вас len знаковая
переменная то это условие i < len никогда не выполнится
Я так понимаю, что такое может произойти, если в массиве будет очень много элементов только, больше 2147483647.
sizeof(arr)/sizeof(arr[0]) это выражение после вычисления
на x64 имеет размер 64 значащих бита потом
в результате присваивания
len = sizeof(arr)/sizeof(arr[0])
обрезаются старшие 32 бита результат будет неверный в len
А это - когда еще больше.

Эта ситуация в рамках данной задачи нереальна по-моему. Если бы здесь была возможна такая ситуация, я бы использовал unsigned int.

greki_hoy
17.05.2010, 15:03
вот что бы об этом потом не думать и не рафакторить код под x64
можно сразу написать так
size_t i, len;
for(i = 0, len = sizeof(arr)/sizeof(arr[0]); i < len; i++)
в зависимости от платформы меняет разрядность плюс беззнаковый :)

greki_hoy
17.05.2010, 15:39
2 d_x табличка пригодится


Тип Размерностьтипа наплатформеx32 / x64 Примечание
int 32 / 32 Базовый тип. На 64-битных системах остался 32-битным.
long 32 / 32 Базовый тип. На 64-битных Windows системах остался 32-битным. Учтите, что в 64-битных Linux системах этот тип был расширен до 64-бит. Не забывайте об этом если разрабатываете код, который должен работать компилироваться для Windows и для Linux систем.
size_t 32 / 64 Базовый беззнаковый тип. Размер типа выбирается таким образом, чтобы в него можно было записать максимальный размер теоретически возможного массива. В тип size_t может быть безопасно помещен указатель (исключение составляют указатели на функции классов, но это особенный случай).
ptrdiff_t 32 / 64 Аналогичен типу size_t, но является знаковым. Результат выражения, где один указатель вычитается из другого (ptr1-ptr2), как раз будет иметь тип ptrdiff_t.
Указатель 32 / 64 Размер указателя напрямую зависит от разрядности платформы. Будьте аккуратны при приведении укзателей к другим типам.
__int64 64 / 64 Знаковый 64-битный тип.
DWORD 32 / 32 32-битный беззнаковый тип. Объявлен в WinDef.h как:typedef unsigned long DWORD;
DWORDLONG 64 / 64 64-битный беззнаковый тип. Объявлен в WinNT.h как:typedef ULONGLONG DWORDLONG;
DWORD_PTR 32 / 64 Беззнаковый тип, в который можно помещать указатель. Объявлен в BaseTsd.h как:typedef ULONG_PTR DWORD_PTR;
DWORD32 32 / 32 32-битный беззнаковый тип. Объявлен в BaseTsd.h как:typedef unsigned int DWORD32;
DWORD64 64 / 64 64-битный беззнаковый тип. Объявлен в BaseTsd.h как:typedef unsigned __int64 DWORD64;
HALF_PTR 16 / 32 Половина указателя. Объявлен в Basetsd.h как:#ifdef _WIN64 typedef int HALF_PTR;#else typedef short HALF_PTR;#endif
INT_PTR 32 / 64 Знаковый тип, в который можно помещать указатель. Объявлен в BaseTsd.h как:#if defined(_WIN64) typedef __int64 INT_PTR; #else typedef int INT_PTR;#endif
LONG 32 / 32 Знаковый тип, который остался 32-битным. Поэтому во многих случаях теперь следует использовать LONG_PTR. Объявлен в WinNT.h как:typedef long LONG;
LONG_PTR 32 / 64 Знаковый тип, в который можно помещать указатель. Объявлен в BaseTsd.h как:#if defined(_WIN64) typedef __int64 LONG_PTR; #else typedef long LONG_PTR;#endif
LPARAM 32 / 64 Параметр для посылки сообщений. Объявлен в WinNT.h как:typedef LONG_PTR LPARAM;
SIZE_T 32 / 64 Аналог типа size_t. Объявлен в BaseTsd.h как:typedef ULONG_PTR SIZE_T;
SSIZE_T 32 / 64 Аналог типа ptrdiff_t. Объявлен в BaseTsd.h как:typedef LONG_PTR SSIZE_T;
ULONG_PTR 32 / 64 Беззнаковый тип, в который можно помещать указатель. Объявлен в BaseTsd.h как:#if defined(_WIN64) typedef unsigned __int64 ULONG_PTR;#else typedef unsigned long ULONG_PTR;#endif
WORD 16 / 16 Беззнаковый 16-битный тип. Объявлен в WinDef.h как:typedef unsigned short WORD;
WPARAM 32 / 64 Параметр для посылки сообщений. Объявлен в WinDef.h как:typedef UINT_PTR WPARAM;