|
Указатели на строку в С |
|
|
|
Jan 24 2016, 08:04
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
В Си есть два способа определения строки: Код char str[] = "string"; void* p1= str; void* p2=&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3);
$ a.out 0xbfaa14c5 0xbfaa14c5 0xbfaa14c5
char* str = "string"; void* p1= str; void* p2=&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3);
$ a.out 0x80488bc 0xbfc25c78 0x80488bc В первом случае p1 равен p2. Почему так?
|
|
|
|
|
 |
Ответов
(1 - 75)
|
Jan 24 2016, 10:32
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(psL @ Jan 24 2016, 10:04)  В Си есть два способа определения строки: Да, но они другие. Эти способы - "abcd" и { 'a', 'b', 'c', 'd','\0'}. Вы же объявили строку одним и тем же способом, более того - в обоих случаях вы продемонстрировали неявное приведение массива к указателю на его первый элемент. Просто во втором случае вы это приведение сделали при объявлении переменной str, а в первом - при объявлении указателей px. В первом случае у вас str - это массив. Во втором случае у вас массив имени не имеет, но существует переменная str, хранящая указатель на его первый элемент.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 24 2016, 10:35
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (amaora @ Jan 24 2016, 12:17)  В первом случае нет переменных хранящих адрес массива, чтобы получить &str как во втором случае эту переменную пришлось бы создать и выдать ее адрес. Потому, что в первом примере определена строка, а во втором УКАЗАТЕЛЬ на строку. А вопрос-то был о другом. Все три выражения в первом случае это есть одно и тоже, поскольку имя переменной это есть ее адрес, то указание взятия адреса есть масло маслянное. Для масивов адрес массива есть адрес его нулевого элемента, посему допронительное указание взять адрес именно нулевого есть уже масло маслянное для масла маслянного.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2016, 11:26
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(Сергей Борщ @ Jan 24 2016, 13:32)  Да, но они другие. Эти способы - "abcd" и { 'a', 'b', 'c', 'd','\0'}. чем отличается = { 'a', 'b', 'c', 'd','\0'} от = "abcd" ? пмсм: ничем. Код const char str[] = { 's','t','r','i','n','g', 0 }; void* p1= str; void* p2=&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3); $a.out 0xbff1a729 0xbff1a729 0xbff1a729 Почему указатель на начало массива p1 и указатель на этот указатель имеют одно и тоже значение? Почему не вот так работает? Код const char str[] = { 's','t','r','i','n','g', 0 }; void* p1= str; void* p2=&p1; //&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3); $a.out 0xbf88cc09 0xbf88cc04 0xbf88cc09 Цитата(_Ivan_33 @ Jan 24 2016, 14:10)  а почему 2? а строковый литерал типа #define MSG "BLA BLA BLA" ? ну может и больше. Интересуют эти 2. В вашем примере строка не будет создаваться программой вплоть до char* str=MSG , например Цитата(amaora @ Jan 24 2016, 13:17)  В первом случае нет переменных хранящих адрес массива, чтобы получить &str как во втором случае эту переменную пришлось бы создать и выдать ее адрес. разве имя массива без индекса не является указателем на первый член этого массива? непонятно.
|
|
|
|
|
Jan 24 2016, 11:34
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (psL @ Jan 24 2016, 13:26)  Почему указатель на начало массива p1 и указатель на этот указатель одно и тоже число? С какого бодуна? Вы сами-же на себя написали опровержение: QUOTE CODE void* p1= str; void* p2=&p1; //&str; void* p3=&str[0];
printf("%p\n%p\n%p\n",p1,p2,p3); $a.out 0xbf88cc09 0xbf88cc04 0xbf88cc09 В этом Вашем-же примере p1 это "указатель на начало массива"? А p2 "указатель на этот указатель". Соответственно это два РАЗНЫХ объекта и имеют "разные числа", что и видно в Вашей-же распечатке. Начните с чтения K&R. Ну ОЧЕНЬ помогает. Аминь.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2016, 11:36
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(psL @ Jan 24 2016, 18:26)  чем отличается = { 'a', 'b', 'c', 'd','\0'} от = "abcd" ? пмсм: ничем. Таки отличается. Код void foo1( char* s ); void foo2( char c );
void foo3( int i ) { foo1( "1234"); foo2( "ABCD"[i] ); } а вот с { 'a', 'b', 'c', 'd','\0'} такой фокус не проходит.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Jan 24 2016, 11:51
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (psL @ Jan 24 2016, 13:42) * Без K&R обьяснить можете? laughing.gif Могу. Вот Вам УЖЕ был дан ответ: QUOTE Все три выражения в первом случае это есть одно и тоже, поскольку имя переменной это есть ее адрес, то указание взятия адреса есть масло маслянное. Для масивов адрес массива есть адрес его нулевого элемента, посему допронительное указание взять адрес именно нулевого есть уже масло маслянное для масла маслянного. Но, очевидно, что для понимания Вам придется начать с букваря для первого класса и вообще научится читать. После чего уже сможете читать в том числе и K&R и уже подумать и понять что делает операнд '=' и что делает операнд '&' получив адрес обьекта.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2016, 12:13
|
Местный
  
Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778

|
Цитата(psL @ Jan 24 2016, 14:26)  разве имя массива без индекса не является указателем на первый член этого массива? непонятно. Выражение "имя массива без индекса" имеет тип указателя на элемент массива, значение соответствует адресу первого члена. Но это не переменная-указатель, собственного адреса у этого выражения нет. В таблице символов компилятора есть только переменная "массив", со своим адресом, а вы хотите получить адрес переменной где хранится указатель на "массив", такого нигде нет. Может стоит разобраться как этот код в памяти располагается, если есть непонимание.
|
|
|
|
|
Jan 24 2016, 12:46
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 5-08-05
Пользователь №: 7 390

|
Цитата(zltigo @ Jan 24 2016, 14:51)  Все три выражения в первом случае это есть одно и тоже, поскольку имя переменной это есть ее адрес, то указание взятия адреса есть масло маслянное. Для масивов адрес массива есть адрес его нулевого элемента, посему допронительное указание взять адрес именно нулевого есть уже масло маслянное для масла маслянного. Но, очевидно, что для понимания Вам придется начать с букваря для первого класса и вообще научится читать... да это какая-то петросянщина маслом масляная. Можете кратко и грамотно безграмотному мне обьяснить? Без букваря, петросяна и тд ? Код char s[]="abc"; void* p1 = s; void* p2 = &s; void* p3 = &p1; Почему равны p1 и p2? Почему не равны p2 и p3? Цитата(amaora @ Jan 24 2016, 15:13)  Выражение "имя массива без индекса" имеет тип указателя на элемент массива, значение соответствует адресу первого члена. Но это не переменная-указатель, собственного адреса у этого выражения нет. В таблице символов компилятора есть только переменная "массив", со своим адресом, а вы хотите получить адрес переменной где хранится указатель на "массив", такого нигде нет. Спасибо. Более-менее понятно.
|
|
|
|
|
Jan 24 2016, 12:54
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Wow! Индекс разрешили применять к rvalue? Цитата(SSerge @ Jan 24 2016, 15:36)  Таки отличается. Код void foo1( char* s ); void foo2( char c );
void foo3( int i ) { foo1( "1234"); foo2( "ABCD"[i] ); } Какой компилятор так умеет извращаться?
Сообщение отредактировал GetSmart - Jan 24 2016, 13:06
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 13:03
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
Цитата(psL @ Jan 24 2016, 15:46)  Можете кратко и грамотно безграмотному мне обьяснить? Без букваря, петросяна и тд ? Код char s[]="abc"; void* p1 = s; void* p2 = &s; void* p3 = &p1; Почему равны p1 и p2? Почему не равны p2 и p3? Вы присваиваете УКАЗАТЕЛЮ p1 ЗНАЧЕНИЕ массива символов s - поэтому происходит неявное преобразование имени массива s в ссылку на него, то есть в &s. В случае p2 это написано явно. Поэтому значения p1 и p2 равны. А p3 содержит АДРЕС переменной p1, поэтому никакого отношения к ЗНАЧЕНИЮ переменной p1 не имеет.
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Jan 24 2016, 13:51
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (GetSmart @ Jan 24 2016, 15:17)  То есть по стандарту индекс можно применять к rvalue? Причем тут все это? Просто foo2( "ABCD"[i] ); это, естественным образом, абсолютно тоже самое, что char str[] = "ABCD"; foo2( str[i] ); Смотрится, конечно, страновато, но законно.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2016, 14:05
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(zltigo @ Jan 24 2016, 17:51)  Смотрится, конечно, страновато, но законно. Незаконно. Классификация lvalue/rvalue (ака переменная/значение) не позволяет такие вольности. По логике, это как взять адрес от значения. Бред. Компилятор должен ругаться на этапе компиляции. Цитата(Сергей Борщ @ Jan 24 2016, 17:55)  Строковый литерал неявно приводится к указателю на char const В стандарте чёрным по белому написано, что прямо внутри разбора выражения? Логично когда оно преобразуется после завершения выражения. Как и с приведением имени массива. Применение амперсанда к массиву естественно, по аналогии со всеми остальными переменными.
Сообщение отредактировал GetSmart - Jan 24 2016, 14:08
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 14:22
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(gerber @ Jan 24 2016, 18:16)  "ABCD" не является rvalue, строго говоря. Это константа, для которой отведено место в памяти, значит и адрес можно брать, и индекс. А rvalue не видны за пределами выражения, в котором они используются. И сложение rvalue-строк на этапе компиляции отменили? Цитата(krux @ Jan 24 2016, 18:20)  покажите каким образом "ABCD" по-вашему является rvalue, со ссылкой-цитатой на стандарт. Вообще-то очевидно, что оно есть rvalue. А вот когда происходят неявные преобразования это другой вопрос. Оно не может происходить сразу по завершающим кавычкам. По аналогии с массивом, применение индекса к имени массива не вызывает неявное преобразование. Не видно оснований почему к строке оно должно вызывать.
Сообщение отредактировал GetSmart - Jan 24 2016, 14:26
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 14:23
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
Цитата(GetSmart @ Jan 24 2016, 17:22)  Цитата покажите каким образом "ABCD" по-вашему является rvalue, со ссылкой-цитатой на стандарт. Вообще-то очевидно, что оно есть rvalue. нет.
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
Jan 24 2016, 14:38
|
Профессионал
    
Группа: Свой
Сообщений: 1 700
Регистрация: 2-07-12
Из: дефолт-сити
Пользователь №: 72 596

|
Цитата(GetSmart @ Jan 24 2016, 17:22)  Вообще-то очевидно, что оно есть rvalue. А вот когда происходят неявные преобразования это другой вопрос. Оно не может происходить сразу по завершающим кавычкам. По аналогии с массивом, применение индекса к имени массива не вызывает неявное преобразование. Не видно оснований почему к строке оно должно вызывать. Цитата(GetSmart @ Jan 24 2016, 17:27)  Дополнил конец пред поста. разницы не вижу. ни ссылок, ни цитат, зато бушует подмена стандарта вашими "понятиями", "аналогиями" и якобы "очевидностями".
--------------------
провоцируем неудовлетворенных провокаторов с удовольствием.
|
|
|
|
|
Jan 24 2016, 14:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 24 2016, 16:05)  В стандарте чёрным по белому написано, что прямо внутри разбора выражения? Да, как и все остальные неявные приведения типов. Цитата(GetSmart @ Jan 24 2016, 16:22)  И сложение rvalue-строк на этапе компиляции отменили? Это как?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 24 2016, 15:02
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата Это как? foo2( "ABCD" + "XYZ" ); Неявное преобразование происходит строго после полного завершения выражения - первого аргумента функции.
Сообщение отредактировал GetSmart - Jan 24 2016, 15:32
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 15:24
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (GetSmart @ Jan 24 2016, 17:02)  foo2( "ABCD" + "XYZ" );
Неявное преобразование происходит строго после полного завершения выражения - первого аргумента функции. C дуба рухнули? Здесь Вам не Паскаль. Здесь, если хочется, то foo2( "ABCD" "XYZ" ); И это из другой оперы.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 24 2016, 15:28
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 24 2016, 17:02)  foo2( "ABCD" + "XYZ" ); Я даже скомпилил от неожиданности. Не, все нормально: Код char const * a = "ab" + "cd";
Compiling: test.c test.c:2:23: error: invalid operands to binary + (have 'char *' and 'char *') char const * a = "ab" + "cd"; ^ Вы в следующий раз проверяйте перед тем как писать.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 24 2016, 15:55
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Тогда есть отличия с взятием адреса массива через амперсанд и взятием адреса строки. Имя массива амперсанд неявно не преобразует к адресу первого элемента, а к строке амперсанд делает неявное преобразование и создаёт или находит уже готовое lvalue, от которого и берёт адрес. Причём взятие адреса массива мне кажется естественным и явно аналогично взятию адреса любой переменной. А вот амперсанд со строкой до сих пор не видел в текстах, которые читал. Цитата(krux @ Jan 24 2016, 18:38)  ни ссылок, ни цитат, зато бушует подмена стандарта вашими "понятиями", "аналогиями" и якобы "очевидностями". Признаю ошибку. Строка (в кавычках) в Си не есть обычное rvalue. Паскаль меня попутал. Я копал не столько стандарт, сколько конфликты и обоснованность семантики. Тема реально похожа на разбор семантики слов и предложений обычного языка. -------------- Видел где-то объявление массивов в аргументах функций при их вызове. Всё ли там чисто.
Сообщение отредактировал GetSmart - Jan 24 2016, 17:11
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 17:28
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 24 2016, 17:55)  Если речь идет о записи "строковый литерал"[индекс], то да - это чистый, как слеза Си. Строковый литерал неявно приводится к указателю на char const, а для указателя определены индексные операции, которые есть адресная арифметика. Отсюда в чистом как слеза Си возможно и такая запись: i["abcdef"]. Конец цитаты точно верный? В индексировании строки будет аж два подряд неявных преобразования. На этом стандарт должен акцентировать внимание. Сперва строка создаст lvalue и значение превратится в указатель, а потом указатель должен неявно превратиться переменную, к которой применим индекс. Т.к. такое выражение полнейшая экзотика, то какие-то компиляторописатели могли бы встать на грабли, если в стандарте нет подсказки. Т.к. неявное преобразование строки происходит в указатель на char, то таки одно неявное преобразование. Индексирование указателя на массив и указателя на другой не пустой тип происходит по-разному. Опять в свой огород закинул.
Сообщение отредактировал GetSmart - Jan 25 2016, 04:22
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 24 2016, 18:45
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 24 2016, 19:28)  Конец цитаты точно верный? Точно. Зуб даю. Ну слегка опечатался: должно было быть "возможна". Цитата(GetSmart @ Jan 24 2016, 19:28)  а потом указатель должен неявно превратиться переменную, к которой применим индекс. Откройте стандарт и почитайте, что делает оператор индекса. Стандарт легко гуглится. Цитата A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))). От перемены мест слагаемых сумма не меняется.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 03:21
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 24 2016, 22:45)  От перемены мест слагаемых сумма не меняется. По поводу выделенного в цитате. Если бы там вместо definition было "действие", то всё было бы корректно к асимметрии взятия элемента массива. Т.к. в предыдущем предложении она обозначена и наследуется следующим предложением. В таком виде как написано толковать его можно как допускающее перемену мест двух выражений у оператора [], если в описании оператора "+" не указана явно зависимость результата от перестановки слагаемых обсуждаемых типов. (насколько это определение старое? в нете коментарии о New C standard) Касательно семантики идеального Си, без всяких плюшек и перегрузок Си++. В сложении чисел перемена мест слагаемых унаследована из математики. Т.к. к указателю удобно применять сложение, то разрешив его логично и наследование правила перемены мест слагаемых, если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число (или адрес или содержимое памяти) когда по соседству у него "третьим" (первые два - число и указатель) будет оператор или операнд, требующий данное неявное преобразование. У понятия взятия элемента массива обычно две составные части выражения исходно разнотипные и это действие семантически несимметричное. Например, как in в Паскале. Оснований делать его симметричным в Си не обозначено, а усложнение читабельности и искажение понятия налицо. Здесь асиметрия сильно увеличивает безопасность. В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне []. Без наличия оснований ввода в стандарт симметрии операндов оператора [] в разделе statement, стандарт будет кривым. Прямо в Си-стандарте, а не в стандарте "соседнего" языка.
Сообщение отредактировал GetSmart - Jan 25 2016, 07:53
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 07:43
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 05:21)  По поводу выделенного в цитате. Если бы там вместо definition было "действие", definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе. Цитата(GetSmart @ Jan 25 2016, 05:21)  если какого-то альтернативного результата не может быть, например из-за (гипотетических) неявных преобразований указателя в число Не надо гипотез. В стандарте все описано. И неявные преобразования, и коммуникативность сложения. Операция разыменования указателя ('*') определена только для указателей, значит результатом суммы должен быть указатель. Сумма дает указатель только если одно из слагаемых указатель, а второе - целое число. Порядок слагаемых не важен. Все описано и ничего выдумывать не нужно. Цитата One of the expressions shall have type ‘‘pointer to object type’’, the other expression shall have integer type, and the result has type ‘‘type’’. Все. "одно из выражений" и "другое выражение". Где из них какое - не сказано и значения не имеет, что следует из отцитированного выше определения (definition). И массив не нужен, нужен указатель. Цитата(GetSmart @ Jan 25 2016, 05:21)  У понятия взятия элемента массива Нет такого понятия. Есть доступ по индексу. Цитата(GetSmart @ Jan 25 2016, 05:21)  В том же стандарте Си наверняка в разделе объявлений переменных (конкретно массивов) указано (например неявно), что нет никакой симметрии и имя массива всегда вне []. Во-первых давайте без "наверняка". Найдите и покажите. Я за вас искать не буду. "Чтение документации из интернета вслух - 100 евро в час". Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи. На этом заканчиваю. Не имею желания опровергать ваши фантазии. Читайте стандарт самостоятельно, там есть ответы на все ваши вопросы. Цитата(GetSmart @ Jan 25 2016, 05:21)  Прямо в Си-стандарте, а не в стандарте "соседнего" языка. Это вообще к чему?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 07:56
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  definition = определение. То есть операция [] определяется и работает именно так, только так и никак иначе. Я так и понял. Весь остальной мой абзац корректен. Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  Это вообще к чему? Предполагал некоторую связь с Си++. Например термин subscript не очень ясен. Слабо похож на русский "взятие элемента массива" или даже "индексирование". Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция взятия субэлемента сложного типа является асимметричной к типу операндов. Плюсование/минусование указателя удобно в языке, но происходит в особом порядке. Компилятор этот случай детектит специально. В этом случае у операций +/- могла быть разрешена симметрия, по желанию разработчиков, из-за симметрии с числовыми операндами. Но можно было бы и жёстко задать: указатель слева, числа справа.
Сообщение отредактировал GetSmart - Jan 25 2016, 08:11
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 08:08
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 09:56)  Предполагал некоторую связь с Си++. В заголовке темы явно указан Си. Далее, вы сами писали о "чистом как слеза Си" и я вам отвечал именно о нем же, даже специально дважды повторил предлженное вами название. Цитата(GetSmart @ Jan 25 2016, 09:56)  Например термин subscript не очень ясен. translate.google.com, технические словари вам в помощь. Цитата(GetSmart @ Jan 25 2016, 09:56)  Обобщая правила в Си, Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 08:16
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 12:08)  Которых вы не читали. Выше добавил в сообщение еще одну цитату из стандарта. Тут хитрость в том, что я не знаю в совершенстве аглицкий. Читать весь стандарт нет смысла. По конкретной теме обсуждения аргументирую конструктивно. Возразите, если есть чем. По поводу нарушения аналогий отношения к агрегатным типам. Гугл-транслейт может завести в такие дебри, что пожалеешь, что запустил  Пользуюсь бумажным словарём. Хорошим и толстым.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 08:54
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 10:16)  По конкретной теме обсуждения аргументирую конструктивно. "возможно", "наверняка", "предполагал" - очень конструктивно, ага. Цитата(GetSmart @ Jan 25 2016, 10:16)  Читать весь стандарт нет смысла Поиск по тексту работает. Цитата(GetSmart @ Jan 25 2016, 10:16)  Возразите, если есть чем. Ага, то есть языка не знаете вы, а возражать должен я? Нет уж, спасибо.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 10:01
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 12:54)  "возможно", "наверняка", "предполагал" - очень конструктивно, ага. Цитата(Сергей Борщ @ Jan 25 2016, 11:43)  Нет такого понятия. Есть доступ по индексу. То есть понятие массива есть. Понятие элемента массива тоже есть. А понятие взятия элемента - нет  Оно есть даже если о нём прямо не говорится в стандарте. Оно может быть объединено/обобщено в новый термин, если он описывает более общий оператор. Этот оператор, кстати, на массивы, указатели на массив и указатели на другой непустой тип действует по-разному. И при таком раскладе обобщённый термин может ввести в заблуждение, рассуждая и корректности терминологии вообще. Цитата A postfix expression followed by an expression in square brackets [] is a subscripted designation of an element of an array object. Что-то здесь не так. "Пост-выражение, идущее после выражения в квадратных скобках есть (термин - непонятные два слова) элемента массива". Не видел такой конструкции в текстах. Вряд ли автор хотел сказать, что "in square brackets" должно относиться к "postfix expression". Если так, то это выражение не относится к взятию элемента массива. И не относится к взятию элемента по индексу, применённому к указателю на не массив.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 10:34
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 12:01)  "Пост-выражение, идущее после выражения в квадратных скобках есть" Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. "Обращением к элементу", а не "взятием элемента". Код char Array[] = "abcdef'; char * Pointer = Array; int Index = 5;
// все эти выражения эквивалентны display(Array[Index]); // неявное преобразование Array к (char *)&Array[0] display(Pointer[Index]); display(Index[Pointer]); display(*(Index + Pointer)); display(*(pointer + Index));
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 10:50
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 14:34)  Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем. Можно контр-пример? Цитата(Сергей Борщ @ Jan 25 2016, 14:34)  "Обращением к элементу", а не "взятием элемента". Напомнило "побочное действие присваивания есть присваивание". В чём разница? В употреблённых мной контекстах. Если напишу так "Обобщая правила в Си, относящиеся к агрегатным типам, всегда операция обращения к его субэлементу является асимметричной к типу операндов." Это понятие обобщает как минимум два более конкретных понятия: взятие адреса элемента и взятие содержимого элемента. Но в каких-то контекстах это обобщение корректно. Цитата Во-вторых, объявление массива и операция доступа по индексу - совершенно разные и никак не связанные между собой вещи. Это утверждение неверно. В обоих случаях есть (будет) объект массив и число (размер или индекс). Оба ключевых признака в тексте на месте. И их позиции относительно оператора [] должны быть одинаковы, если нет весомых оснований отходить от этого. Та выделенная формулировка в цитате необоснованно навязывает допустимости варианта "индекс наизнанку" с аналогией со сложением, хотя сложение с указателем есть особый случай сложения. Если это желание разработчика, то это его личное дело. А если есть глубокие причины такого навязывания, то они должны были быть обозначены.
Сообщение отредактировал GetSmart - Jan 25 2016, 22:53
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 11:47
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(GetSmart @ Jan 25 2016, 10:50)  Постфиксным выражением не может быть имя главного объекта, которое указывается первым левым идентификатором/именем. Ах! Поэзия! Посильнее "Фауста" Гете будет ! А вот что скажут теоретики программирования, пока, правда, не освоившие стандарт языка Ц на такое использование массивов ? CODE static char Foo1(uint32 aIdx) { return "abcdefghijkl"[aIdx]; }
static char Foo2(uint32 aIdx) { return aIdx["abcdefghijkl"]; }
... Это вам не про монадические типы рассуждать...
|
|
|
|
|
Jan 25 2016, 12:19
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Нашёл такую формулировку Цитата A postfix expression (operand followed by the operator) followed by an expression in square brackets [ ] is a subscripted designation of the array element .The definition of the array subscript operator [ ] is that if a is an array and i is an integer then a[i] =*(a+i). В контексте которой есть определение postfix operator. Это индексирование [], передача параметров в функцию, ++ и другие. Соответственно postfix expression означает этот оператор без аргументов, с одним или списком аргументов. Естественно, postfix expression может быть только в комбинации с postfix operator, который применим только к допускающему его объекту слева от postfix-выражения. В этом определении нет разрешения "индекса наизнанку" (в конце определения). Но понять смысл первого предложения невозможно. expression in square brackets [ ] и есть частный случай постфикс-выражения. В определении отсутствует главный объект. Цитата An operator is called a Postfix Operator when the operator follows the operand. Postfix Operators may operate on either one or two operators. There are five postfix operators in C:- 1. Array subscripts 2. Function Call 3. Structure and Union Members 4. Postfix Increment and Decrement Operators 5. Compound Literals Цитата(CrimsonPig @ Jan 25 2016, 15:47)  ... Это вам не про монадические типы рассуждать...  Ключевое слово (return и прочие) не являются именем. В Си имена совпадающие с ключевыми словами запрещены.
Сообщение отредактировал GetSmart - Jan 25 2016, 13:43
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 12:40
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 16:21)  Если бы некоторые писатели еще и читали предыдущие сообщения, они бы увидели, что именно эти примеры мы и пытались обсуждать. Цитата Постфиксное выражение, за которым следует выражение в квадратных скобках, является индексным обращением к элементу массива. "Обращением к элементу", а не "взятием элемента". x = array[index]; Что здесь постфиксное выражение? И какое слово в том определении переводится как обращение? "Указание" на элемент, возможно есть.
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 12:46
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 25 2016, 14:19)  В этом определении нет разрешения "индекса наизнанку" (в конце определения). А никто и не говорит, что можно писать [index]Array. Цитата(GetSmart @ Jan 25 2016, 14:19)  Но понять смысл первого предложения невозможно. expression in square brackets [ ] и есть частный случай постфикс-выражения. В определении отсутствует главный объект. Что-то вас конкретно клинит. Возьмем для простоты Array[index]. Здесь "Array" - postfix expression, (выражение, к которому может быть применен постфиксный оператор). "[]" - это postfix operator. index - expression in square brackets. "Постфиксое выражение (Array) (операнд, за которым следует посфиксный оператор ([])), за которым следует выражение в квадратных скобках ([index]), является индексным обращением к элементу массива. Определение оператора индексного доступа [] таково, что если "a" есть массив и "i" есть целое число, то a[i] тождественно *(a+i)". Вот полный дословный перевод вашей цитаты. Я не знаю, откуда вы ее взяли, я приводил цитату из стандарта ("Это документ между прочим!" голосом Мягкова из "Иронии судьбы"). В стандарте сказано "определение оператора индексного доступа таково, что E1[E2] идентично (*((E1)+(E2)))". Исходя из этого определения в операторе индексного доступа можно перед скобками указывать индекс, а в скобках указывать выражение, неявно приводимое к указателю. Можно, потому что правила языка такое допускают - целое число является постфиксным выражением, а для указателя определена операция сложения с первым аргументом и результат этого сложения имеет тип указателя. И реализация для обоих вариантов Array[index] и index[Array] исходя из определения получается идентичная с точностью до порядка слагаемых. Цитата(GetSmart @ Jan 25 2016, 14:40)  И какое слово в том определении переводится как обращение? "Указание" на элемент, возможно есть. designation - указание, цель. Хорошо, пусть будет указание, что, по сути, и есть обращение. В объявлении массива квадратные скобки являются частью определения, а не оператором индексного доступа, поэтому ваши попытки приплести сюда объявление массива бессмысленны.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 25 2016, 13:08
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 16:21)  Если бы некоторые писатели еще и читали предыдущие сообщения, они бы увидели, что именно эти примеры мы и пытались обсуждать. Общими усилиями удивляемся стандарту. То, что кривыми определениями там разрешена абракатабра. На счёт индексации строки я ошибся, т.к. строка в кавычках это особый тип выражения, а остальные замечания вполне законны. Цитата(Сергей Борщ @ Jan 25 2016, 16:46)  Что-то вас конкретно клинит. Возьмем для простоты Array[index]. Здесь "Array" - postfix expression, (выражение, к которому может быть применен постфиксный оператор). "[]" - это postfix operator. index - expression in square brackets. Чтобы называть Array постфиксным выражением нужно ещё дав определение префиксному выражению и основному (точке отсчёта). Постфиксное выражение вообще-то всегда идёт за главным. Где здесь главное? При такой фривольной интерпретации понятий, явно конфликтующей с общеупотребляемой терминологией должны быть обозначены причины.
Сообщение отредактировал GetSmart - Jan 25 2016, 13:17
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 13:15
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (GetSmart @ Jan 25 2016, 14:19)  Ключевое слово (return и прочие) не являются именем. Это функция  Посему: return(); return( value ); QUOTE (gerber @ Jan 25 2016, 15:12)  Стандарт стандартом, но за работу с элементами массивов в стиле Index["abcd"] 99% заказчиков, заглядывающих в исходники при приемке работы, голову оторвут.  1) Я бы вообще за работу массивами не по указателям в языке Си голову отрывал  2) Все зависит от читабельности. В угоду ей можно поступится и привычностью.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 25 2016, 13:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(CrimsonPig @ Jan 25 2016, 15:47)  Ах! Поэзия! Посильнее "Фауста" Гете будет ! Писал вспешке под тот контекст. Уточняю. Обсуждаемый язык разбирает выражения слева направо. Постфиксным выражением не может быть первое левое lvalue. Если встречается непостфиксный оператор, то за ним (справо) первое lvalue снова считается главным объектом, который не входит в постфиксное выражение. Т.к. выражения не обязаны быть в виде присваивания, то допустимы оба варианта x = Array[index]; Array[index]; И классификация субэлементов выражения Array[index] в этих двух вариантах не должна отличаться. Упд Правило написано для области (места, позиции в тексте) исполняемого кода. В т.ч. в области деклараций при задании начального значения lvalue. В первой части объявления lvalue в декларациях, до задания значения, могут быть нюансы и. какие там основы в принятой терминологии не ясно.
Сообщение отредактировал GetSmart - Jan 25 2016, 23:49
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 15:02
|
Знающий
   
Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088

|
Цитата(zltigo @ Jan 25 2016, 16:27)  Но вообще динамическое выделение памяти это СОВСЕМ неплохо, да и malloc() совсем не мешает "массивной" работе. Как по мне - malloc/free - это принципиально другой подход к хранению и обработке данных, чем статический массив. При грамотном подходе даёт, безусловно, бОльшую свободу действий, но имеет и свои минусы, особенно в embedded и real-time проектах: тут и излишний перерасход памяти, и недетерминированное время выделения/освобождения памяти из "кучи" при её фрагментации и т. п. Но это уже оффтопик.
--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
|
|
|
|
|
Jan 25 2016, 15:39
|

Гуру
     
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244

|
QUOTE (gerber @ Jan 25 2016, 17:02)  Как по мне - malloc/free - это принципиально другой подход к хранению и обработке данных, чем статический массив. Абсолютно такой-же. Все различие в том, что в одном случае указатель есть обязательно, а во втором его может и не быть в явном виде. Все. Ну и free() не сделаешь  . В обшем один вариант частный случай другого и не более того. Общий вариант просто и БЕЗ ВСЯКИХ ПОБОЧНЫХ ЭФФЕКТОВ (кроме расхода памяти на MCB, если в хипе выделяется память) приводистся к частному. Более того, динамическое выделение памяти оно сплошь и рядом - все локальные пеерменные на то они и локальные, что на них выделяется память НЕ статически. И ничего страшного.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
Jan 25 2016, 22:19
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 25 2016, 16:46)  И реализация для обоих вариантов Array[index] и index[Array] исходя из определения получается идентичная с точностью до порядка слагаемых. Пишите тогда уж "исходя из данного определения". Второй вариант навязан, бесполезен и вреден. Оснований таких его последствий как ухудшение читабельности и ослабления безопасности не обозначено. Вред должен искореняться. Цитата В объявлении массива квадратные скобки являются частью определения, а не оператором индексного доступа, поэтому ваши попытки приплести сюда объявление массива бессмысленны. Осмысленно, осмысленно. Есть такое понятие как читабельность. Которое обязано быть всегда в приоритете у разработчиков. И она ни с чем в данном вопросе не конфликтует. Цитата(zltigo @ Jan 25 2016, 18:33)  Разумеется нет. Порядок "разборки" вообще никакого значения не имеет к языку. Важен порядок вычисления выражений, который идет в соответствии с приоритетом операций и формами записей. Я написал компилятор разбирает выражения, а не код/таргет исполняет. Это значит компилятор просматривает текст слева направо и согласно этому определена терминология.
Сообщение отредактировал GetSmart - Jan 25 2016, 22:21
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 25 2016, 23:46
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 26 2016, 03:06)  Определение дано в стандарте языка. Не нравится - "обратитесь во всемирную в Лигу сексуальных реформ". С какой формулировкой обратиться? Версий стандартов много. Я спрашивал какого, вы не ответили. В стандарте могут быть нюансы, "задевающие" это определение. Уже указывал. В Америке в последнее время всякую неестественность разрешают. Чудаки.
Сообщение отредактировал GetSmart - Jan 26 2016, 00:33
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 26 2016, 00:31
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 26 2016, 01:46)  С какой формулировкой обратиться? Вам виднее. Цитата(GetSmart @ Jan 26 2016, 01:46)  Версий стандартов много. Я спрашивал какого, вы не ответили. Во всех трех (C89/90, C99 и C11) формулировка идентична. Выбирайте любой.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 26 2016, 00:39
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(Сергей Борщ @ Jan 26 2016, 04:31)  Вам виднее. Напомнило контекст фразы "если ты не знаешь, я тебе не скажу". Цитата(Сергей Борщ @ Jan 26 2016, 04:31)  Во всех трех (C89/90, C99 и C11) формулировка идентична. Выбирайте любой. Остановлюсь на найденной мной. В преамбуле источника есть "fundamentals of C".
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Jan 26 2016, 08:41
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(GetSmart @ Jan 26 2016, 02:39)  Напомнило контекст фразы "если ты не знаешь, я тебе не скажу". Это же вам не нравится определение из стандарта. Ваше право жаловаться куда угодно на принявший его комитет. И вы спрашиваете у меня, как сформулировать вашу жалобу? Цитата(GetSmart @ Jan 26 2016, 02:39)  Остановлюсь на найденной мной. В преамбуле источника есть "fundamentals of C". -Слышал я вашего Карузо, полная фигня! -Великий Карузо выступал в Одессе? -Нет, мне Мойша напел. Вам осталось найти компилятор, который будет написан по вашему источнику, а не по стандарту. А я откланиваюсь.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jan 26 2016, 11:53
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата(zltigo @ Jan 26 2016, 11:30)  Как разбирать выражения компилятору - вдоль, поперек, слева....это его интимное дело НИКАК не регламентируемое стандартами. Влияет на терминологию и определения. В определениях нет ни лева ни права, но используется "идёт за" и постфикс. Постфикс и постфиксное выражение тоже по-своему трактуется? Или строго правее основного в тексте? Где читал не увидел вообще определение постфиксного выражения. Мы с вами, те, которые стандартизаторы, и вообще большинство читают слева направо. В общеупотребляемой терминологии подобные умолчания подразумеваются. И в определениях их умалчивание считается вариантом нормы, если оно влияет. Удивляет вообще "их" терминология. Казнить нельзя помиловать в нагрузку к стандарту. Цитата(krux @ Jan 24 2016, 18:23)  Цитата(GetSmart) Вообще-то очевидно, что оно есть rvalue. нет. Вы не могли бы прояснить отличие от данной версии. Я признал, что к строке можно применить индекс и амперсанд. Хотя к обычным rvalue такое неприменимо. К строке это применимо, если считать что она rvalue с возможностью неявного преобразования , когда к ней применяется индекс, амперсанд и в некоторых других случаях. Можно назвать её rvalue-строка. Если за строкой без всяких операторов идёт ещё одна строка, то они состыковываются и образуют одно rvalue. Что для rvalue-строк пусть будет применимо. К rvalue склоняюсь потому, что это тоже тип "значение", пока оно в компиляторе обрабатывается в состоянии до неявного преобразования. А не объект с адресом. А уж если индексируется по rvalue-константе, то никакого lvalue там создавать не нужно. И в определении глобального lvalue она тоже не доходит до неявного преобразования (в котором компилятор для неё должен выделять место или найти аналогичное ранее созданное lvalue), а берётся её чистое значение (ака rvalue) и помещается в конкретно заданную область. Неявное преобразование rvalue-строки особенно тем, что есть два варианта. Можно сказать две стадии. Зависит от типа получателя или применённого оператора. Первая стадия: находится или создаётся lvalue в области памяти констант, а тип текущего выражения становится lvalue - char const. Применяя к строке амперсанд неявным будет этот вариант, т.о. вместе с амперсандом тип выражения будет rvalue - char const *. Передавая строку в качестве аргумента функции , в дополнение к первому будет вторая стадия: неявное взятие адреса данного lvalue - char const. После неё будет rvalue - char const *. Вторая стадия эквивалентна действию амперсанда. Cразу на этапе компиляции выражение *(&"abc") даст первый символ, а не исходное rvalue. Не знаю как стандарт применяет амперсанд к строке, если допускает. И как толкует предыдущее выражение. Выделение места в области памяти констант для содержимого строки будет не сразу. Компилируя выражение, если строка превращается в rvalue-char в описанных ранее случаях, то поиска/создания lvalue не происходит. Строки именно с кавычками, т.к. о них было несогласие. Допускает ли стандарт наличие скобок между строками при их соединении на этапе компиляции, тоже не знаю. rvalue и lvalue это классификация объектов при разборе выражений в процессе компиляции. В итоге: содержимое строки (массив символов) по сути одинаковое и в процессе разбора компилятором, и в области памяти констант, если считать с добавочным нулём. Данное содержимое логично называть rvalue (полностью: rvalue-строка). В процессе неявных преобразований тип rvalue-строка превращается в другой, а обратного преобразования не существует. Конфликта нет. Но если бы было обратное, то зависило бы от реализации. \0' должен так же выдаваться компилятором, если во время компиляции из строки берётся элемент с номером/индексом равном длине строки. Если номер больше, то ошибка компиляции. Применимость sizeof - по желанию.
Сообщение отредактировал GetSmart - Jan 27 2016, 07:48
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
Feb 5 2016, 20:41
|
.
     
Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753

|
Цитата An operator is called a Postfix Operator when the operator follows the operand. Postfix Operators may operate on either one or two operators. There are five postfix operators in C:
1. Array subscripts 2. Function Call 3. Structure and Union Members 4. Postfix Increment and Decrement Operators 5. Compound Literals Добавлю. Определение subscripts (по-русски индексации), зацитированное в этой ветке из стандарта, в сочетании с терминологией некорректна в обоих предложениях. Термин постфикс-оператор обязывает оператор следовать за операндом, к которому тот применим. Хоть вторая часть явно не указана, но она очевидна ещё из списка двухоперандных постфикс-операторов компилятора (не препроцессора). При иных требованиях к операндам оператор называется не постфикс-оператором, а оператором другого рода. Т.о. без вынесения оператора subscripts из списка постфикс-операторов получается некорректная ерунда. Если ерунда содержится в какой-то части стандарта, то наиболее адекватно её не учитывать. А если его вынести из постфикс-операторов, то явно нарушится общность с другими операторами обращения к члену/субэлементу. Которая есть в корректной части стандарта. По поводу строк. Если по сути вещей в кавычках находится значение, и называя его значением aka rvalue упрощается логика без каких-либо противоречий, то это вполне законно.
Сообщение отредактировал GetSmart - Feb 5 2016, 20:55
--------------------
Заблуждаться - Ваше законное право :-)
|
|
|
|
|
  |
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|