LINUX.ORG.RU

[баян]Указатели в С/С++


0

1

Допустим дано

uint16_t var=258;
uint16_t *p;
p=&var;
printf("%.2x\n", (??????)&0xff );

Подскажите, как правильно отобразить второй байт исходного числа пользуясь только указателем p ?

★★★★★

Ответ на: комментарий от Legioner

и это старший байт ? или младший ? неизвестно

*((unsigned char *) p + 1)
тогда уж так
*p >> 8 & 0xff
точно старший байт на любом ендиане

osox ()
Ответ на: комментарий от Lee_Noox

&char[0] будет указывать на 0 байт, а &char[0] + 1 — на 2 байт char.

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

Двухбайтовый char? Мне на linuxforum'е (ещё) доходчиво объяснили, что sizeof(char)==1 всегда. А для уникода - wchar_t.

ЗЫ. Если уж перестраховаться, то в исходном комментарии s/unsigned char/u_int8_t/

Delirium_veritas ()

какой смысл получать доступ к второму байту числа (подчеркиваю не к старшему/младшему а именно второму) ? на разных машинах он будет иметь разное значение при одном значении в переменной из за ендиана или вам все таки надо было старший/младший байт вытащить?

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

Никакого %) Но всеравно в пределах х86 эндианы не меняются :)

Было интересно увидеть как это правильно реализовать, именно обращение... А то я что-то крутил крутил...

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

>Двухбайтовый char? Мне на linuxforum'е (ещё) доходчиво объяснили, что sizeof(char)==1 всегда. А для уникода - wchar_t.

Я тоже так думал и в некоторых местах такое читал, но вот буквально совсем недавно читал стандарт C99, и там есть гарантия лишь, что размер char достаточный (то есть не меньше 1 байт).

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

6.5.3.4 The sizeof operator
.....
2) The sizeof operator yields the size (in bytes) of its operand

соединяя пункты 2) и 3), получаем, что размер char всегда равен 1 байту в C99.

cy ()
Ответ на: комментарий от osox

скобки не нужны (хотя это дело вкуса)

Лучше везде их ставить, чем удивляться, почему получается странный результат (в случае неоднозначных приоритетов).

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

> и там есть гарантия лишь, что размер char достаточный

для кодирование 127 символов таблицы ASCI

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

> соединяя пункты 2) и 3), получаем, что размер char всегда равен 1 байту в C99.

Ой блин. Раньше было: sizeof возращает в кол-ве char'ов

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

Ну язык C стандартом C99 не ограничиваеться. Существуют архитектуры на которых char может быть больше 1 байта. Компиляторов и платформ существует большое множество. Пример : NXP Coolflux DSP - sizeof(char) == 3 байта.

Лучше всего не полагаться на подобные вещи и знать свои инструменты.

recon88 ()
Ответ на: комментарий от cy

> получаем, что размер char всегда равен 1 байту в C99

Не байту, а storage unit, блджад!

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

>> Мне на linuxforum'е (ещё) доходчиво объяснили, что sizeof(char)==1 всегда.

идем читать стандарт


И видим, что ему объяснили всё правильно.

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

> Двухбайтовый char?

char всегда 1 байт. Но 1 байт не обязательно 8 бит.

ISO/IEC 9899:1999

3.6 byte addressable unit of data storage large enough to hold any member of the basic character set of the execution environment <...> NOTE 2 A byte is composed of a contiguous sequence of bits, the number of which is implementation-defined.

The New C Standard: An Economic and Cultural Commentary

On most implementations a byte occupies 8 bits. The POSIX Standard requires that CHAR_BIT have a value of 8. The Digital DEC 10 and Honeywell/Multics[180] used a 36-bit word with the underlying storage organization based on 9-bit bytes. Some DSP chips have a 16- or 32-bit character type (this often has more to do with addressability issues than character set sizes).

ntp ()
Ответ на: комментарий от cy

> Their implementation-defined values shall be equal or greater in magnitude (absolute value) to those shown, with the same sign.

Да, проглядел эту фразу.

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

Точнее будет так

highbyte = (*p >> CHAR_BIT) & UCHAR_MAX; 
lowbyte  = *p & UCHAR_MAX;

cy ()
Ответ на: комментарий от osox

> скобки не нужны (хотя это дело вкуса)

Скобки нужны и это не дело вкуса. Это дело корпоративного Coding Style и привычки написания программ в которых сможет после вас разобраться средний быдлокодер.

ntp ()
/*
   avidump.c

   simple format dump utility for avi movies

   Copyright (C) 2004 Ralph Giles. All rights reserved.

   Distributed under the terms of the GNU GPL.
   See http://www.gnu.org/ for details.
*/

/* read a 16 bit little-endian integer */
void read16(FILE *in, uint16_t *p)
{
	unsigned char q[2];
	fread(q, 1, 2, in);
	*p = q[0] | q[1] << 8;
	return;
}

/* read a 32 bit little-endian integer */
void read32(FILE *in, uint32_t *p)
{
	unsigned char q[4];
	fread(q, 1, 4, in);
	*p = q[0] | q[1] << 8 | q[2] << 16 | q[3] << 24;
	return;
}

/* write a 16 bit little-endian integer */
void write16(FILE *out, uint16_t p)
{
	unsigned char q[2];
	q[0] = p & 0xFF;
	q[1] = (p >> 8) & 0xFF;
	fwrite(q, 1, 2, out);
	return;
}

/* write an 8 bit integer */
void write8(FILE *out, unsigned char p)
{
	fwrite(&p, 1, 1, out);
	return;
}

/* write a 32 bit little-endian integer */
void write32(FILE *out, uint32_t p)
{
	unsigned char q[4];
	q[0] = p & 0xFF;
	q[1] = (p >> 8) & 0xFF;
	q[2] = (p >> 16) & 0xFF;
	q[3] = (p >> 24) & 0xFF;
	fwrite(q, 1, 4, out);
	return;
}

/* write a 32 bit big-endian integer */
void write_be32(FILE *out, uint32_t p)
{
	unsigned char q[4];
	q[0] = (p >> 24) & 0xFF;
	q[1] = (p >> 16) & 0xFF;
	q[2] = (p >> 8) & 0xFF;
	q[3] = p & 0xFF;
	fwrite(q, 1, 4, out);
	return;
}

/* insert a 32 bit big-endian integer into a buffer */
void put_be32(unsigned char *p, uint32_t q)
{
	p[0] = (q >> 24) & 0xFF;
	p[1] = (q >> 16) & 0xFF;
	p[2] = (q >> 8) & 0xFF;
	p[3] = q & 0xFF;
	return;
}
osox ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.