А вот как "напечатать"-вывести в Serial указатель ?

vlkam
Offline
Зарегистрирован: 17.02.2013

 Думал все просто, типа

Serial.println(&buffer);

а вот фиг там

Geronimo
Offline
Зарегистрирован: 06.05.2013

а смысл?

указатель это число указывающее на память в дуине

наприемнике он не имеет смысла

vlkam
Offline
Зарегистрирован: 17.02.2013

Geronimo пишет:
а смысл?
указатель это число указывающее на память в дуиненаприемнике он не имеет смысла

Смысл то как раз имеется. Хочу проверить, вот такую конструкцию, правильно ли там все инкрементируется

memcpy(&buffer + sizeof(int) ,((uint8_t *)&id_array) + DATA_adr,l_pack_size);

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

не знаю как в winavr, в IAR адрес добывается вот так

char buffer[3] = {0x01, 0x02, 0x03};
char * ptr;
void main(void)
{
   ptr = &buffer[0]; 

тут же дело в понимании языка. объявляя любой длины буфер, компилятор запоминает только его первый элемент. другими словами, объявление буфера это и есть обявление адреса нулевого его элемента.

т.е.

buffer == &buffer[0]

отсюда и пляшем.

step962
Offline
Зарегистрирован: 23.05.2011

vlkam пишет:

 Думал все просто, типа

Serial.println(&buffer);

а вот фиг там

А вот так попробовать не пытались?

int a,arr[10],b;
void setup() {
  Serial.begin(9600);
  a=1; b=2; arr[0]=3;
  Serial.print((int)&a);   Serial.print(": ");  Serial.println(a);
  Serial.print((int)&arr); Serial.print(": ");  Serial.println(arr[0]); 
  Serial.print((int)&b);   Serial.print(": ");  Serial.println(b); 
}

 

Geronimo
Offline
Зарегистрирован: 06.05.2013

Понял, без указания цели, показалось странным намерение)

&buffer

имеет тип type*

и нет подходящего println, как писали выше надо привести к целому

vlkam
Offline
Зарегистрирован: 17.02.2013

step962 пишет:
А вот так попробовать не пытались?

О, спасибо ! Работает!

vlkam
Offline
Зарегистрирован: 17.02.2013

Ого, какие интересные результаты. Я думал, что когда объявляешь массив и увеличиваешь указатель на массив на единицу, то указатель инкрементируется на размер элемента массива. Нифига, оказывается на размер всего массива

uint8_t buffer[42]; // буфер данных

Serial.println((int)&buffer);
Serial.println((int)(&buffer + 2));
Serial.println((int)(&buffer + sizeof(int)));

Результат

2222
2306
2306

Geronimo
Offline
Зарегистрирован: 06.05.2013

Он инкрементируется на величину sizeof(var)C

Geronimo
Offline
Зарегистрирован: 06.05.2013

Чтобы на единицу надо так
Int buf[42];
Int* ptr;
ptr = &buf;
ptr +=1;//ptr сдвинется на sizeof (int)

vlkam
Offline
Зарегистрирован: 17.02.2013

Geronimo пишет:
Чтобы на единицу надо так Int buf[42]; Int* ptr; ptr = &buf; ptr +=1;//ptr сдвинется на sizeof (int)

Или вот так

Serial.println((int)(&buffer[0]));
Serial.println((int)(&buffer[0]+2));

Результат

2220
2222

Т.е. все абсолютно логично, если ссылка на сам массив, то при +1 указатель увеличивается на размер массива
А если указатель на элемент массива, то при +1 указатель увеличивается на элемент массива
 

__Alexander
Offline
Зарегистрирован: 24.10.2012

мда. какой "увеличивается на размер массива"? это не из этой оперы. 

vlkam
Offline
Зарегистрирован: 17.02.2013

__Alexander пишет:
мда. какой "увеличивается на размер массива"? это не из этой оперы.

В смысле не из той оперы ? Этож вроде классический Си.
При инкрементации указателя он увеличивается на размер объекта, на который указывает.
В случае, если указатель на массив, указатель как раз увеличивается на размер массива
А вот если указатель на элемент массива, то он увеличивается на размер элемента массива
 

__Alexander
Offline
Зарегистрирован: 24.10.2012

та нет. любой инкремент типа ++ увеличивает только на единицу. и компилятору всё равно, указатель это или переменная.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Конструкция &buffer[0] + 1 обычно не используется, проще использовать buffer + 1, другой аналог &buffer[1].

Конструкция &buffer + 1 это вообще нонсенс, она указывает на адрес за последним элементом массива. Не рекомендую вообще пользоваться.

Еще примеры вполне корректного (с определенными ограничениями) использования:

uint8_t buffer[8] = { '0', '1', '2', '3', '4', '5', '6', '7', '\0' };

uint8_t *ptr = buffer;

uint8_t index = 5;

index = 5;

Serial.println( buffer + 5 );
Serial.println( buffer + index - 2 );

ptr += index;
Serial.println( ptr  );
ptr -= 2;
Serial.println( ptr  );

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

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

__Alexander пишет:

та нет. любой инкремент типа ++ увеличивает только на единицу. и компилятору всё равно, указатель это или переменная.

Вот по поводу "на единицу" не надо путать. vlkam всё правильно сказал, на размер объекта.

 

vlkam
Offline
Зарегистрирован: 17.02.2013

__Alexander пишет:
та нет. любой инкремент типа ++ увеличивает только на единицу. и компилятору всё равно, указатель это или переменная.

Все верно, на единицу.
Только для char единица это байт, для int "единица" 2 байта, а для массива - размер массива.
Попробуйте запустить код :

void setup() {                
	char a;
	uint8_t buffer[10]; // буфер данных
	Serial.begin(9600);	 
	
	Serial.println((int)&a);
	Serial.println((int)(&a+1));
	Serial.println((int)&buffer);
	Serial.println((int)(&buffer + 1));


}

void loop() {
}

Результат :

2281
2282
2282
2292
 

 

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

не знаю. это мутка winavr. как он из адреса извлекает адрес добавляя единицу. возможно неправильная расстановка приоритетов.

Смотрим сюда.

void setup() {                
	uint8_t buffer[10]; // буфер данных
	Serial.begin(9600);	

Serial.println((int)&buffer);

int addr;

addr = (int)((&buffer));
addr += 1;
Serial.println(addr);
}

void loop() {
}

Результат:

2282
2283
 

И почему при addr += 1 нифига не добавилось на 10?

 

Пример номер два.

Serial.println((int)&buffer[0]);
Serial.println((int)&buffer[0]+1);

Результат:

2282
2283

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

 

И пример номер три, который подтверждает мои слова что buffer это уже &buffer[0], т.е. уже содержит адрес! нулевого элемента и не надо никаких &... не? Смотрим.

Serial.println((int)buffer);
Serial.println((int)buffer+1);

Результат:

2282
2283

И никаких прибавлений на размер массива не наблюдается.

 

Geronimo
Offline
Зарегистрирован: 06.05.2013

У тебя addr тип int a не int[10]

vlkam
Offline
Зарегистрирован: 17.02.2013

__Alexander пишет:

Serial.println((int)buffer);
Serial.println((int)buffer+1);

Тут приоритет операций - сперва адрес конвертируется в int, а только потом добавляется единица.
buffer+1 В скобки возьми, тогда сперва указатель увеличится, а потом конвертация произойдет

И это не "мутка avr", я это помню еще с Borland C++

 

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Чтобы не париться с приоритетами, ставьте скобки, тогда будет как задумано

__Alexander
Offline
Зарегистрирован: 24.10.2012

vlkam пишет:

__Alexander пишет:

Serial.println((int)buffer);
Serial.println((int)buffer+1);

Тут приоритет операций - сперва адрес конвертируется в int, а только потом добавляется единица.
buffer+1 В скобки возьми, тогда сперва указатель увеличится, а потом конвертация произойдет

И это не "мутка avr", я это помню еще с Borland C++

ну взял в скобки

Serial.println((int)buffer);
Serial.println((int)(buffer+1));

результат тот-же. собственно, почему ему быть другим?

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

step962
Offline
Зарегистрирован: 23.05.2011

__Alexander пишет:

результат тот-же. собственно, почему ему быть другим?

А вы определите несколько указателей:

char *cptr;

int *iptr;

long *lptr;

Присвойте им адрес буфера, добавьте к каждому из этих указателей по единичке и выведите результат(ы).

Получится ли у вас "тот-же" результат?

__Alexander
Offline
Зарегистрирован: 24.10.2012

причем тут указатели? понятное дело, что если указатель объявить как long, то инкремент будет на четыре байта. причем тут массив? эта хрень пройдет и без массива. и адрес вытаскивается не в указатель, а в обычную переменную, которая не может инкрементироваться как ей хочется, а только на единицу.

 

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

Error[Pe513]: a value of type "char (*)[3]" cannot be assigned to an entity of type "char"

winavr компилирует, но почему именно с таким результатом, известно наверное только ему и правильно сказал kisoft

"Конструкция &buffer + 1 это вообще нонсенс, она указывает на адрес за последним элементом массива. Не рекомендую вообще пользоваться."

и я щетаю это правильный ответ.

 

upd: вот только что проверил в CVAVR, он тоже такой записи не знает, так что это самоинициатива winavr, а не стандарт си. нет в си такой "чухни" где "+1" это прибавление на размер массива.

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

__Alexander пишет:

upd: вот только что проверил в CVAVR, он тоже такой записи не знает, так что это самоинициатива winavr, а не стандарт си. нет в си такой "чухни" где "+1" это прибавление на размер массива.

Я тоже так думал, потому что никогда не использовал эту странную конструкцию, даже в голову не приходило. Свои примеры (см. сообщение #14) проверял в MS Visual Studio C++ 2010 Express, там &buffer + 1 указывает, как я уже писал на первый элемент ПОСЛЕ массива. Так что это всё вписывается в стандарты. ;)

Если уж сравнивать работу компиляторов, нужно взять один пример и скомпилировать в разных средах, затем уже сравнивать результаты, сдается мне, что они будут одними и теми же. А то cейчас "спор" ни о чем.

По собственному опыту часто использую конструкцию (buffer + index) и, почти никогда &buffer[index]. На мой взгляд проще всего завести указатель uint8_t *ptr = buffer; и им оперировать, не забывая про выход за границы массива. Экономия на спичках дорого обходится.

vlkam
Offline
Зарегистрирован: 17.02.2013

__Alexander пишет:
  нет в си такой "чухни" где "+1" это прибавление на размер массива.

Борланд С++ 1995 год

__Alexander
Offline
Зарегистрирован: 24.10.2012

ну так я как-бы и проверил. winavr, IAR, CVAVR... последние такую запись не знают.

потом, стандарт C++ это уже далеко не С. Там уже ООП. И такая конструкция возможна. Точнее, конструкция

&buffer переделывается в &buffer[10], где 10 - это размер, объявленный при создании массива, тогда логично что +1 к этому делу указывает на следующий байт после массива. Так делает и winavr.

Но, надоело повторяться, это не прибавление на размер массива,т.к. &buffer + 2 не прибавить два раза по десять, а +3 не прибавит по три десятка, а прибавит эти числа только к адресу последнего элемента.

Всё, на этом заканчиваю, а то создается впечатление, что я сам себе что-то доказываю.

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

vlkam пишет:

__Alexander пишет:
  нет в си такой "чухни" где "+1" это прибавление на размер массива.

Борланд С++ 1995 год

Вы сами понимаете, что читаете? Увеличивается на размер связанного с ним типа! т.е. если массив объявлен как int, то увеличение будет на 2, если long, то на 4 внутри массива. Это логично! Но не на размер ВСЕГО массива! Неужели это так трудно понять.

И второе,  в вашей записи Serial.println((int)&buffer);

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

 

 

tsostik
Offline
Зарегистрирован: 28.02.2013

Мда. Каша в голове - она такая каша.

Предположим, у нас есть несколько переменных:

char myChar;

int myInt;

long myLong

char buffer[10];

Тогда конструкция "&myChar" будет иметь тип "указатель на char", "&myInt" - "указатель на int", "&myLong" - укащатель на long, а "&buffer" - "указатель на массив из десяти элементов типа char"

Следующий шаг - конструкция &var + 1 обозачает "адрес ячейки памяти, в котором будет храниться следующая после var" переменная.

Пусть наш чар лежит по адресу 0x1000, по какому адресу будет лежать следующая за ним переменная? Правильно, 0x1001.

А если по этому адресу лежит не чар, а инт, по какому адресу будет следующая переменная? 0x1002. А если там лежит переменная типа "массив из десяти чаров?" - 0x100A

Цитата:

И второе,  в вашей записи Serial.println((int)&buffer);

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

Нету в языках программирования C и C++ типа "обычная переменная". А каждое выражение имеет какой-то тип, вот незадача.

Внимание вопрос - какой тип имеет выражение "&buffer"?

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

tsostik пишет:

Следующий шаг - конструкция &var + 1 обозачает "адрес ячейки памяти, в котором будет храниться следующая после var" переменная.

Поправочка, это если выравнивание по байтам, а если нет, то не факт, что следующая переменная будет храниться по этому адресу, может быть пустое место. Я не даром писал, что на "следующий элемент после массива" - это не значит, что на следующую переменную. Что я, собственно и наблюдал в MS VS C++.

Уфф, всё, я пас :)

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

tsostik пишет:

Предположим, у нас есть несколько переменных:

char myChar;

Пусть наш чар лежит по адресу 0x1000, по какому адресу будет лежать следующая за ним переменная? Правильно, 0x1001.

А если по этому адресу лежит не чар, а инт, по какому адресу будет следующая переменная? 0x1002. А если там лежит переменная типа "массив из десяти чаров?" - 0x100A

нет. следующая относительно первого элемента будет ровно на один тип больше. если в массиве чары, то следующая будет 0x1001, если инты, то 0x1002.

если у вас есть уверенность в ваших предположениях, давайте код. будем посмотреть.

tsostik пишет:

Внимание вопрос - какой тип имеет выражение "&buffer"?

всмысле тип? если он (буфер) размещен в конце карты памяти в 32Гб, то может быть и long long.

tsostik
Offline
Зарегистрирован: 28.02.2013

У меня не предположения. Я первым делом все проверил и посмотрел результаты -)

Вот код:

#include <stdio.h>
int main()
{
    char myChar;
    short myShort;
    int myInt;
    char buffer[10];
    printf("%lld\n" , (long long)(&myChar + 1 ) - (long long)(&myChar) );
    printf("%lld\n" , (long long)(&myShort + 1 ) - (long long)(&myShort) );
    printf("%lld\n" , (long long)(&myInt + 1 ) - (long long)(&myInt) );
    printf("%lld\n" , (long long)(&buffer + 1 ) - (long long)(&buffer) );
    return 0;
}

Вот вывод:

1
2
4
10

Компилятор:

>gcc --version
gcc 4.4.4 20100726 (Red Hat 4.4.4-13)
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

ОС:

> cat /etc/redhat-release
Red Hat Enterprise Linux Client release 5.5 (Tikanga)
 

Выше kisoft уже писал про поведение MSVS.

Цитата:

всмысле тип? если он (буфер) размещен в конце карты памяти в 32Гб, то может быть и long long.

 

Тип - это такое базовое понятие многих языков программирования, в том числе и C/C++.

Тип этот никоим образом не зависит от того, где именно хранятся данные.

И тип выражения &var никогда и ни при каких условиях не будет long long.

Да, этот адрес, в зависимости от платформы может иметь длину 2, 4 и 8 байт (а изредка в экзотических случах, даже 1 байт), но тип всегда останется "указатель на <тип переменной var>".

 

__Alexander
Offline
Зарегистрирован: 24.10.2012

tsostik пишет:

У меня не предположения. Я первым делом все проверил и посмотрел результаты -)

Вот код:

#include <stdio.h>
int main()
{
    char myChar;
    short myShort;
    int myInt;
    char buffer[10];
    printf("%lld\n" , (long long)(&myChar + 1 ) - (long long)(&myChar) );
    printf("%lld\n" , (long long)(&myShort + 1 ) - (long long)(&myShort) );
    printf("%lld\n" , (long long)(&myInt + 1 ) - (long long)(&myInt) );
    printf("%lld\n" , (long long)(&buffer + 1 ) - (long long)(&buffer) );
    return 0;
}

Вот вывод:

1
2
4
10

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

Доказательсво это когда 

printf("%lld\n" , (long long)(&buffer + 1 ) // Здесь получаете 10

а вот здесь

printf("%lld\n" , (long long)(&buffer + 2 ) //  получаете 20, как тут во весь голос кричат

В противном случае... короче понятно.

 

leshak
Offline
Зарегистрирован: 29.09.2011

__Alexander пишет:

Вы сами понимаете, что читаете? Увеличивается на размер связанного с ним типа! т.е. если массив объявлен как int, то увеличение будет на 2, если long, то на 4 внутри массива. Это логично! Но не на размер ВСЕГО массива! Неужели это так трудно понять.

Тут, IMHO, небольшой винигрет. Не важно "как массив объявлен", важно "как указатель объявлен".

Если у вас "указатель на int", то его инкремент будет сдвигать на 2 байта. А вот если "указатель на массив _неважно_чего_", то инкремент будет сдвигать на "размер массива" (само собой размер масива должен быть известен на момент компиляции).

Вообщем рояль играет "тип указателя". Мы же при его объявлении указываем "на объекты какого типа он указывает".

Ну  и еще, конечно, тут добавляет путаницы, что "под капотом", сами массивы реализованны как указатели :(
Поэтому с помощью приведения типов можно довольно безболезненно конвертировать скажем "char*" в "char[]" и обратно. Лично я для себя, если честно, массивы так и воспринимаю - как более наглядный синтаксис для указателей. Вообщем, в большинстве случаев, нужно просто просто выборать "что тебе понятней", массивы или указатели (но знать нужно и то и другое :). И старатся их не смешивать. Писать "однотипно".

__Alexander
Offline
Зарегистрирован: 24.10.2012

я не отрецаю, но код в пример я обязан попросить. и желательно оперируя только & как в теме, а не условным присовением "*", но в любом случае на получние знаний не повлияет. я только за.

 

upd.

leshak пишет:

Поэтому с помощью приведения типов можно довольно безболезненно конвертировать скажем "char*" в "char[]" и обратно. Лично я для себя, если честно, массивы так и воспринимаю - как более наглядный синтаксис для указателей.

я тоже честно, массивы воспринимаю уже глядя на ячейки памяти МК в озу. Простые тупые ячейки с размером в байт. Никаких чудес. )

__Alexander
Offline
Зарегистрирован: 24.10.2012

кстати. запостю на изи. мож вразумительный ответ получим.

tsostik
Offline
Зарегистрирован: 28.02.2013

Ок, вот Вам еще один код, как просили.

#include <stdio.h>
int main()
{
    char myChar;
    short myShort;
    int myInt;
    char buffer[10];
    printf("%x, %x\n" , (long long)(&myChar ), (long long)(&myChar + 1 ) );
    printf("%x, %x\n" , (long long)(&myShort ), (long long)(&myShort + 1 ) );
    printf("%x, %x\n" , (long long)(&myInt ), (long long)(&myInt + 1) );
    printf("%x, %x\n" , (long long)(&buffer ), (long long)(&buffer + 1 ) );
    return 0;
}

Вывод:

773864df, 773864e0
773864dc, 773864de
773864d8, 773864dc
773864c0, 773864ca
 

PS: У меня вопрос - какова цель жанного обсуждения? Вы хотите что-то доказать или все-же уяснить для себя ответ на вопрос?

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

Если уяснить для себя ответ - давайте начнем с того, ответ на какой именно вопрос?

__Alexander
Offline
Зарегистрирован: 24.10.2012

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

и Вы, кстати, тоже не устаете приводить очевидную вещь в виде строки

printf("%x, %x\n" , (long long)(&buffer ), (long long)(&buffer + 1 ) );

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

vlkam
Offline
Зарегистрирован: 17.02.2013

__Alexander пишет:
прибавте мне число два к указателю массива и покажите результат, что он действительно равен двум массивам.

Так вроде как раз с этого и началось все, там пример кода есть и возвращаемый результат. У Вас он не такой ?  :
http://arduino.ru/forum/programmirovanie/vot-kak-napechatat-vyvesti-v-se...

__Alexander
Offline
Зарегистрирован: 24.10.2012

окей. уговорили. тогда почему iar и cvavr не хавают эту запись?

&buffer + 1

и говорят тчо надо обратиться к элементу? [] либо не использовать &, т.к. buffer это ужа сам по себе указатель. Типа winavr хоть и бесплатный, но даже покруче чем IAR выходит? )) шутка.

 

 

Geronimo
Offline
Зарегистрирован: 06.05.2013

buffer указатель
&buffer адрес указателя. Т.е указатель на указатель

vlkam
Offline
Зарегистрирован: 17.02.2013

Geronimo пишет:
buffer указатель &buffer адрес указателя. Т.е указатель на указатель

И как же по Вашему "указатель на указатель" инкрементируется на размер буфера ?

tsostik
Offline
Зарегистрирован: 28.02.2013

В данном случае, &buffer - это все таки не указатель на укащатель, а указатель на массив жестко заданной длины. При инкременте, указатель увеличивается на

sizeof() от того типа, на который указывает. Sizeof от типа "массив из десяти чаров" - это 10. (Ключевой момент здесь то, что 10 часть определения типа, известная на этапе компиляции).

 

leshak
Offline
Зарегистрирован: 29.09.2011

[quote=__Alexander]

 

leshak
Offline
Зарегистрирован: 29.09.2011

Сорри,что-то проглючило...

 

 

__Alexander пишет:
я не отрецаю, но код в пример я обязан попросить. и желательно оперируя только & как в теме, а не условным присовением "*"

Александр, к сожалению такой код как вы просити - вам никто дать не сможет. Поэтому "одни слова".
 
Что-бы два человека могли понять/объяснить что-то друг-другу - нужно у них в голове выстроились (хотя-бы временно) одинаковые "модели предметной области" и при общении они пользовались терминами вкладывая в них одинаковый смысл.
 
Поэтому, что-бы не путаться, предлагаю открыть какую-нибудь книгу по C/C++ (а лучше несколько) и внимательно вчитатся и понять разницу между:
- указатель
- адресс
- "оператор взятия адресса"
(опционально еще и про ссылки почитать можно)
 
Тогда вы поймете, что ваша просьба, фактически является "просьбой показать пример инкрементации оператора", хотя речь шла (и цитаты сканы книги показывали) - про указатель.А "как в теме", так ведь топик стартер и спрашивал потому что не знал "как привально" (и код написать, и назвать конструкцию).
А что вы имелли ввиду под '"а не условным присовением "*"' - для меня полная загадка.
 
Итак, такой код вы просите, показать вам я не могу. Так как, с моей точки зрения выражение "инкремент оператора" - не имеет смысла.
 
Вообщем это тот случай когда "терминологическое занудство" - вполне полезная вещь.
 
А вот пример инкремента указателя - можно показать :)
 
int buffA[10]; // первый массив
int buffB[10]; //второй массив



void setup(){
  Serial.begin(57600);
  
  for(byte i=0;i<10;i++){ // заполним массивы какими данным
    buffA[i]=10+i;
    buffB[i]=20+i;
  }
  
  // обявляем указатели
  byte* bytePointer;  // указатель на байт
  
  int* intPointer; // указатель на целое число
  int (*intArrayPointer)[10]; // указатель на массив интов в 10-ть элементов
  
  
  
  // Выводим размеры переменных
  Serial.println("Variable sizes:");
  Serial.println(sizeof(buffA));
  Serial.println(sizeof(bytePointer));  // как видим все указатели имеют одинаковый размер, независимо от того на что они указывают
  Serial.println(sizeof(intPointer)); // 
  Serial.println(sizeof(intArrayPointer));
  
  Serial.println("------------------");
  
  // теперь берем заполняем все наши указатели адресом первого элемента массива
  bytePointer=(byte *)&buffA; // насильно указываем компилятору, что нам плевать какого типа buffA
  intPointer=&buffA[0]; // тут у компилятора "все совпадает", приведение типа делать не нужно? так как сослались на элемент типа int
  intArrayPointer=&buffA; // А тут вообще "все совпадает"
  
  // Выведем куда указывают у нас все наши указатели
  
  Serial.println("Print pointer addrs ");
  Serial.println("------------------");
  
  
  Serial.println((unsigned int)bytePointer); // делаем приведение типа, к двухбайтовому типу, что-бы println понял что нас интересует именно адресс
  Serial.println((unsigned int)intPointer); // как видим - все адреса совпадают. все указатели указыают на одно место в памяти
  Serial.println((unsigned int)intArrayPointer);
  
    Serial.println("------------------");
  
  // вывдем еще значение массива на который ссылкает "указатель на массив int[10]"
  Serial.println("Array values:");
  for(byte i=0;i<10;i++){Serial.print( (*intArrayPointer)[i]);Serial.print(i<9?",":"\n------------------");}
  
  // теперь инкрементим все наши указатели на единицу
  bytePointer++; // теперь указывает на старший байт первого элемента
  intPointer++;  // теперь указывает на второй элемент
  intArrayPointer++; // туперь указывает на второй массив
  
  // И опять выводим адреса куда указателей
  Serial.println("Print pointer addrs after increment");
  Serial.println((unsigned int)bytePointer); // увеличился на единицу, так как указывает на байт.
  Serial.println((unsigned int)intPointer); // увеличился на 2, так как указывает на int
  Serial.println((unsigned int)intArrayPointer); // увеличился на 20-ть, так указывает на массив 10-ть элементов по 2 байта
  
  Serial.println("------------------");  
   // Выведем еще раз значени массива куда указывает указатель
  Serial.println("Array values after increment:");
  for(byte i=0;i<10;i++){Serial.print( (*intArrayPointer)[i]);Serial.print(i<9?",":"\n------------------");}   
  // как видим, у нас вывелись значение массива buffB, так как он в памяти расположен за buffA, а указатель у нас увеличился ровно на размер массива
  
  
  // а теперь чуток поиграемся с адрессом
  intArrayPointer=&buffA; // возстановим первоначальное значение указателя, опять указывает на первый элемент buffA
  unsigned int intArrayAddr=(unsigned int)intArrayPointer; // возмем его адресс
  
  
  Serial.println("Addr before:");
  Serial.println(intArrayAddr); // опять видим тот же адресс :)
  
  intArrayAddr++; // инкрементим его
  
  
  Serial.println("Addr after:");
  Serial.println(intArrayAddr);// как видим, он увиличился всего на единицу. Так как адресс -  это "просто число". В отличие от указателя число не знает "какого типа объект  лежит в пямяти по этому адресу".

  
}

void loop(){
}

Выводит:

Variable sizes:
20
2
2
2
------------------
Print pointer addrs 
------------------
712
712
712
------------------
Array values:
10,11,12,13,14,15,16,17,18,19
------------------Printýù8éñ/Variable sizes:
20
2
2
2
------------------
Print pointer addrs 
------------------
712
712
712
------------------
Array values:
10,11,12,13,14,15,16,17,18,19
------------------Print pointer addrs after increment
713
714
732
------------------
Array values after increment:
20,21,22,23,24,25,26,27,28,29
------------------Addr before:
712
Addr after:
713

Вообщем указатель это такия фигня "два в одном". И какой-то адресс в памяти и "что там находится" в одном флаконе. Это скорее "нечто" которое информацию о том как интерпретировать некий участок памяти (где он находится, какого размера, его составные части если это объект или структура  и т.п.)

 
 
 
__Alexander
Offline
Зарегистрирован: 24.10.2012

Одним словом, я признаю свое поражение в данном споре, т.к. выяснил одну важную деталь, до сегодняшнего дня конструкция &buffer + 1 игнорилась всеми компиляторами для AVR, кроме winavr, который является основой ардуино иде. Видимо в свете последних дней, когда существуют множиство языков с ООП, в него были встроены данные изменения и поэтому компиляция проходит без проблем и действительно вычисляется как вы и говорите. Пролистав книги по си до сегодняшнего дня, все указатели писались &buffer[x], т.е. с указанием на конкретную ячейку или просто buffer, т.к. это уже само по себе указатель. Всё, устал. )

leshak пишет:

А что вы имелли ввиду под '"а не условным присовением "*"' - для меня полная загадка.
 
Да, не так выразился, хотел сказать с оператором косвенной адресации.
 
ptr = &peremennaya
x = *ptr;
отсюда
x = peremennaya. 
 
Надеюсь тут то уже споров не будет... ) 
 
 
 
 
leshak
Offline
Зарегистрирован: 29.09.2011

 

__Alexander пишет:

Надеюсь тут то уже споров не будет... ) 
 
 
Ага. Щассссзз :)
 

__Alexander пишет:

 

Одним словом, я признаю свое поражение в данном споре

 

Вот про это и поспорим :) Поражение - как правило термин игр с нулевым или отрицательным балансом.

А тут у нас, скорее речь идет про "игру с положительным балансом". Ведь у вас же "ничего не убыло". Наоборот - прибавилось понимание :)

Все зависит от того какие цели вы ставили... термин "поражение" имеет смысл только если целью было поднять свое ЧСВ. Но... в этом бы случае вы бы вряд ли признали "поражение". А значит - нет никакого поражения ;)