Тип данных String

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Тип данных String

Сообщение Diamock » 10.04.2011 (Вс) 19:25

Здравствуёте Уважаемые!
При объявлении строковой переменной постоянного размера
Код: Выделить всё
Dim Variable As String*60

объём занимаемой памяти у переменной равен 1 байту на символ.
При обявлении строковой переменной непостоянного размера:
Код: Выделить всё
Dim Variable As String

Занимаемый объём памяти 10 байт + 1 байт на символ.

Что за информацию хранят в себе эти 10 байт?

С уважением...
In der Beschrankung zeigt sich erst der Meister
Графоманю...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 10.04.2011 (Вс) 19:29

Откуда ты взял все эти числа? Они все неправильны.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 10.04.2011 (Вс) 19:41

Хакер писал(а):Откуда ты взял все эти числа? Они все неправильны.

Ну, выдумать, я их сам не мог :D - нарыл где-то.
Но хочеться знать, какой размер памяти занимает тип String фиксированного и переменного размера?
In der Beschrankung zeigt sich erst der Meister
Графоманю...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 10.04.2011 (Вс) 19:47

Diamock писал(а):Ну, выдумать, я их сам не мог :D - нарыл где-то.

Вычерки источник этих чисел, пометив его как источник бреда.

Обычная String переменная занимает 4 байта и хранит указатель на BSTR-строку. Занимает в стеке или секции данных.
BSTR-строка занимает в памяти 4 + (N+1)*2 байтов, где N — длина хранимой строки. Занимает в OLE-шной строковой куче.

Не надо путать String-переменную и BSTR-строку. Первая — это собственно переменная, и она есть всегда. Второе — значение, и его может не существовать.

Со строкой фиксированного размера разницы практически нет, за исключением того, что значение всегда есть и оно фиксированной длины.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 10.04.2011 (Вс) 19:50

Огромаднейшее спасибо!!!
Всё ясно и доступно изложено.
In der Beschrankung zeigt sich erst der Meister
Графоманю...

iGrok
Артефакт VBStreets
Артефакт VBStreets
 
Сообщения: 4272
Зарегистрирован: 10.05.2007 (Чт) 16:11
Откуда: Сетевое сознание

Re: Тип данных String

Сообщение iGrok » 10.04.2011 (Вс) 20:52

Я, кажется, догадываюсь, откуда он это взял.
Точнее, откуда это взял тот, у кого он это взял. :)

Если сделать вот так:
Код: Выделить всё
Type xx
  a As String
  b As Long
  c As String * 10
  d As Long
  e() As Byte
End Type

Sub test()
Dim s As String
Dim x As xx
Dim f As Long
  s = "abcdef" + ChrW(&H6DE)

  x.a = s
  x.b = -1
  x.c = s
  x.d = -1
  x.e = s
 
  f = FreeFile
  Open "c:\testfile" For Binary As f
  Put #f, , x
  Close f 
End Sub


То получим в файле весьма любопытный результат:
x.a будет выглядеть вот так (hex): 07 00 61 62 63 64 65 66 3F
x.c - вот так: 61 62 63 64 65 66 3F 20 20 20
А x.e - вот так: 01 00 0E 00 00 00 00 00 00 00 61 00 62 00 63 00 64 00 65 00 66 00 DE 06

Т.е. x.a записался как ansi, при этом в самое начало добавилась двухбайтовая длина строки.
x.c - тоже как ansi, и недостающая часть строки заполнилась пробелами.
А x.e - как массив байт (логично, в общем-то), составляющих эту строку, предварённый неким заголовком, размером ровненько в 10 байт.

Впрочем, как это всё связано с тем, как vb хранит строки в памяти - не представляю.
label:
cli
jmp label

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 10.04.2011 (Вс) 21:48

Ну так при сохранении в файл происходит какая-никакая серализация (кстати корнями уходящая в обратную совместимость с древними версиями VB, в которых использовались ANSI-строки), которая, да, мало общего имеет с заниманием места в памяти.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 02.05.2011 (Пн) 16:12

Ещё раз пропустив мимо ушей, сказанное Хакером, у меня кое-что зацепилось за мозг :) .
Объявим две переменных типа String:

Код: Выделить всё
Dim strExemple_1 As String
Dim strExemple_2 As String*10

Предположим, что мы загружаем в переменные текст из файла txtExemple.txt, размером 20 кб.

Размер strExemple_1 составляет 4 байта и содержит указатель на BSTR-строку размером 4+(20*1024+1)*2=40 966 (байт).
Размер strExemple_2 составляет 4 байта и содержит указатель на BSTR-строку размером 4+(10+1)*2=26 (байт)

Очень надеюсь, что зацепилось правильно и в нужном порядке :D . Если нет, прошу поправить.
In der Beschrankung zeigt sich erst der Meister
Графоманю...

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 11:49

Что такое 4 в последнем выражении? Размер указателя? Строка хранится в wchar_t и занимает количество символов + zt * sizeof(wchar_t). Указатель считать, а тем более, умножать на два -- совершенно не нужно
Тебе будет полезно ознакомиться: http://forum.sources.ru/index.php?showtopic=166377
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 11:53

BV писал(а):Что такое 4 в последнем выражении?

Длина строки, забывчивый наш, хранимая перед началом строки.

BV писал(а):а тем более, умножать на два

Размер WCHAR — 2 байта, так что нужно.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 11:57

Хакер, ты, оказывается, еще более невнимателен, чем я. У автора нет умножения. У него просто некорректно построены предложения

Added
На всякий случай поясню: мне показалось, что 4 в скобках. И эта 4 уже была второй после упоминания размера префикса
Последний раз редактировалось BV 05.05.2011 (Чт) 12:01, всего редактировалось 1 раз.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 11:59

BV писал(а):У него просто некорректно построены предложения

Где?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 12:02

Только что выше отписался
Хакер писал(а):Где?


Размер strExemple_2 составляет 4 байта и содержит указатель на BSTR-строку размером 4+(10+1)*2=26 (байт)
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 12:11

Всё верно здесь.
Переменная strExample2 фактически является указателем, и её размер равен 4 байтам вне всякой зависимости от значения строки. Там может быть NULL, ни на что не указывающий, но размер переменной-указателя при этом останется 4 байта. И эти 4 байта будут заниматься либо на стеке (локальная переменная), либо в секции данных (глобальная переменная), либо в TLS (глобальная переменная в ActiveX-проекте с Apartament Threading), либо в куче (элемент массива).

Так вот этот указатель может указывать либо вникуда (NULL), если строка не инициализированна, либо в OLE-шную строковую кучу на блок байтов. Размер этого блока всегда будет вычислять по форуме 4+(L+1)*2, где L — длина строки в символах.

Всё правильно у него написано.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 12:43

С этим кто-нибудь спорит? Кому ты это рассказал?

Чувствую, все равно придется разъяснять:
Размер указателя не имеет никакого отношения к размеру строки, на которую он указывает. Это во-первых. Во-вторых, предложение у автора построено так, что возникает неоднозначность, к какому слову относится цифра 4, к "указатель" или к "BSTR-строке". Я так думаю, автор имел ввиду именно строку. Ты почему-то, как и я сначала, посчитал, что указатель, но интерпретировал как-то по-своему.

На будущее автору советую писать предложения без множественных толкований
Последний раз редактировалось BV 05.05.2011 (Чт) 12:48, всего редактировалось 1 раз.
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 12:45

BV писал(а):С этим кто-нибудь спорит?


Я понял, что выделения некоторых слов полужирным и подчёркиванием, это твой способ указать на неправильность с твоей точки зрения этих слов.

Если нет, в чём смысл особого форматирования в этом посте:
BV писал(а):
Размер strExemple_2 составляет 4 байта и содержит указатель на BSTR-строку размером 4+(10+1)*2=26 (байт)

:?:
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 12:50

Хакер писал(а):Если нет, в чём смысл особого форматирования в этом посте:

В неоднозначности фразы. Читай выше. Ты отвечаешь быстрее, чем я успеваю вносить дополнения в посты
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 12:55

BV писал(а):Размер указателя не имеет никакого отношения к размеру строки, на которую он указывает. Это во-первых.

Заметь, что никто из нас (ни Diamock, ни я) не делали в точности такого заявления. Везде речь идёт либо о занимаемой памяти (а указатель вносит свой вклад в процесс занимания), либо о размере переменной (а она фактически является указателем).

BV писал(а):Во-вторых, предложение у автора построено так, что возникает неоднозначность, к какому слову относится цифра 4, к "указатель" или к "BSTR-строке".

Какое именно? Если те два, после которых идёт твой пост, то у автора в каждом из этих предложений есть две четвёрки. Первая из них относится к указателю, вторая — к BSTR-строке. Так что я не вижу неоднозначности.

P.S. Давай закончим на этом.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

BV
Thinker
Thinker
Аватара пользователя
 
Сообщения: 3987
Зарегистрирован: 12.09.2004 (Вс) 0:55
Откуда: Молдавия, г. Кишинёв

Re: Тип данных String

Сообщение BV » 05.05.2011 (Чт) 13:15

Хакер писал(а):Заметь, что никто из нас (ни Diamock, ни я) не делали в точности такого заявления.

Я нигде не замечал, что ты делал такое заявление. Похоже, ты тоже как-то не так читаешь мои посты, ведь этот момент я отметил в контексте другой, неправильной интерпретации
Хакер писал(а):Первая из них относится к указателю, вторая — к BSTR-строке.

Ага, то есть, ты все понял сразу, но не понял мой ответ? Замечательно, на этом согласен закончить
const char *out = "|*0>78-,+<|"; size_t cc = char_traits<char>::length(out);
for (size_t i=0;i<cc;i++){cout<<static_cast<char>((out[i]^89));}cout<<endl;

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 05.05.2011 (Чт) 18:27

В своих поисках я наткнулся на следующее:
Это у нас на форуме, и в MSDN.
О тех же 10 байтах в размере типа String.
Хотелось бы услышать комментарии.
In der Beschrankung zeigt sich erst der Meister
Графоманю...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 05.05.2011 (Чт) 18:55

Diamock писал(а):О тех же 10 байтах в размере типа String.

Если опуститься до того, чтобы смешивать мух с котлетами и вазелином, то размер указателя в сумме с размером с полем с длинной в сумме размера нуль-терминатора даст число 10.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 05.05.2011 (Чт) 19:29

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

String.png
String.png (1.75 Кб) Просмотров: 3508

P.S. А котлеты я люблю в шоколаде, с начинкой из варёной сгущёнки :) .
Последний раз редактировалось Diamock 07.05.2011 (Сб) 16:31, всего редактировалось 1 раз.
In der Beschrankung zeigt sich erst der Meister
Графоманю...

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Re: Тип данных String

Сообщение NashRus » 06.05.2011 (Пт) 2:35

Я один в танке?
Откуда у BSTR нуль терминаторы и, главное, зачем они там, строка однозначно идентифицируется по размеру в заголовке.

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 06.05.2011 (Пт) 8:29

NashRus писал(а):Я один в танке?

Угу.

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

Надо полагать для совместимости и возможности оптимизации в тех случаях, когда хранение нуль-символа посреди строки не предполагается, я обход строки — ага (чтобы иметь возможность как-то наткнуться на конец).
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

NashRus
Постоялец
Постоялец
 
Сообщения: 388
Зарегистрирован: 18.03.2006 (Сб) 1:16

Re: Тип данных String

Сообщение NashRus » 06.05.2011 (Пт) 13:25

Да, подзабыл я эти моменты.

Вот статья хорошая по строкам на MSDN: http://msdn.microsoft.com/ru-ru/library/ms811463.aspx

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 06.05.2011 (Пт) 13:36

NashRus писал(а):Вот статья хорошая по строкам на MSDN: http://msdn.microsoft.com/ru-ru/library/ms811463.aspx

Да, выглядит неплохо. Сохраните, что ли, у себя где-нибудь, а то MS может устранить с формулировкой «out-of-date stuff», чтобы освободить место под какой-нибудь гламурный Azure.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 08.05.2011 (Вс) 16:36

Из всего вышесказанного, у меня сформировалось следующее:
Объявим в модуле два UDT и их переменные.

Код: Выделить всё
Option Explicit

Public Type MyCustomType_01
    varFixedString As String * 10
    varString As String
End Type

Public Type MyCustomType_02
    varString_01 As String
    varString_02 As String
End Type

Public MyCustomer_01 As MyCustomType_01
Public MyCustomer_02 As MyCustomType_02

Для кнопки напишем код:
Код: Выделить всё
Private Sub Command1_Click()
    Debug.Print "Размер MyCustomer_01 в байтах:" & vbTab & LenB(MyCustomer_01)
    Debug.Print "Размер MyCustomer_02 в байтах:" & vbTab & LenB(MyCustomer_02)
End Sub

И получаем:
Immediate писал(а):Размер MyCustomer_01 в байтах: 24
Размер MyCustomer_02 в байтах: 8

Значит, размер MyCustomer_01 состоит из размера поля MyCustomer_01.varFixedString 10*2=20 (байт) и размера указателя на BSTR-строку поля MyCustomer_01.varString 4 байта, что в сумме составляет 24 байта.
Соответственно размер MyCustomer_02 состоит из суммы указателей его полей: 8 байт.

Ну и в заключении:
При объявлении переменной типа String фиксированного размера, в памяти она занимает: SizeVariable*2 (байт).

  • SizeVariable - размер переменной
  • 2 - в UNICODE, символ занимает размер в 2 байта
При объявлении переменной типа String, в памяти она занимает 4 байта, что есть указатель на BSTR-строку в которой содержатся (или нет) данные.

Так?
In der Beschrankung zeigt sich erst der Meister
Графоманю...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 08.05.2011 (Вс) 16:58

Не совсем.
Во-первых, избавься наконец от фразы «занимает в памяти».

Во-вторых, объявленное As String*N действительно занимает 2L байт, но толку от этого мало: каким бы образом ты не образался к фиксед-стринг-переменной или фиксед-стринг полю, оно никогда не предстанет перед тобой в истиннов виде. Всегда будет создаваться обычная BSTR-копия.

То есть, если ты передаёшь фиксированную строку по ссылке, то передаётся ссылка не на фиксированную строку-буфер, а на BSTR-указатель, то есть на обычную строку.

Единственный бонус: указатель на буфер фиксированного размера всё-таки можно получить, если строка объявлена в рамках структуры, получив адрес структуры и прибавив к нему смещения поля-буфера. Просто получать адрес поля-буфера с помощью VarPtr не получится из-за конвертации.

Как следствие, можно передавать адрес структуры в какие-нибудь функции, для которых принимающая сторона ожидает увидеть поле типа WCHAR Field[N];.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Diamock
Постоялец
Постоялец
Аватара пользователя
 
Сообщения: 388
Зарегистрирован: 26.10.2009 (Пн) 4:19
Откуда: Кемерово

Re: Тип данных String

Сообщение Diamock » 08.05.2011 (Вс) 17:10

Ох-ох! :?
Меня не покидает стойкое ощущение, что бы разобраться с типами VB, надо заглянуть в дебри COM и OLE Automation, а может и глубже.
Хакер, не подскажешь что почитать на эту тему?
In der Beschrankung zeigt sich erst der Meister
Графоманю...

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Тип данных String

Сообщение Хакер » 08.05.2011 (Вс) 17:40

Фиксированных строк, подобных VB, афаик, нет в COM.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

След.

Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 59

    TopList  
cron