Перейти к содержанию
    

На платформе АVR и так и сяк будет двойной расход памяти flash + копия в озу пока явно не зададим __flash.

Это так к слову...

 

Посмотрите здесь
Это объяснение не на том уровне. Хотелось бы в контексте Си стандарта...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На платформе АVR и так и сяк будет двойной расход памяти flash + копия в озу пока явно не зададим __flash.

Это так к слову...

На MSP430 - все литеральные строки хранятся во флэше. А для инициализированных массивов, если я не хочу переносить их п память, достаточно добавить const

 

Попутно. Оффтопик. Как вам удается редактировать свои сообщения, без того чтобы было написано "изменен тогда-то и тем-то"?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На MSP430 - все литеральные строки хранятся во флэше. А для инициализированных массивов, если я не хочу переносить их п память, достаточно добавить const

Это всё понятно. У MSP430 единое адресное пространство - просто и удобно... И про повсеместный static const я как бы тоже в теме. Меня интересует конкретный отсыл в стандарт и только...

Попутно. Оффтопик. Как вам удается редактировать свои сообщения, без того чтобы было написано "изменен тогда-то и тем-то"?
Также как и вам. Нажимаю редактировать -> быстрое...

 

В avr-gcc вообще все очень непросто со строковыми литералами.

Можете почитать нашу дискуссию на сей счёт: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56263

И был бы очень рад если ещё кто-то меня поддержит в ней!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Также как и вам. Нажимаю редактировать -> быстрое...

Я так делаю - обязательно пишет что меняли текст.

 

Можете почитать нашу дискуссию на сей счёт

Почитал. Познавательно. Я сам с AVR не работаю.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это объяснение не на том уровне. Хотелось бы в контексте Си стандарта...
Запросто - С99 стандарт, глава 6.4.5 (String Literals), параграф 5

In translation phase 7, a byte or code of value zero is appended to each multibyte

character sequence that results from a string literal or literals. The multibyte character

sequence is then used to initialize an array of static storage duration and length just

sufficient to contain the sequence.

Так что возвращать из функции можно :biggrin:

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О! Вот это вразумительно!

Спасибо! Приятно осознавать что ты поумнел после содержательной беседы. Серьёзно.

Отдельное спасибо igorle!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так делаю - обязательно пишет что меняли текст.

если после поста были добавлены посты других участников, то добавляется информация о редактировании. Возможно, на случай, что ваш пост процитировали, а вы потом что-то в нем поменяли

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

igorle ,вы привели программу

void foo1(int argc, char **argv)
{
    while (argc--)
        printf("\"%s\"\n", argv++);
}

void foo(void)
{
    char *my_argv[] = {"Hello", "World", "one", "two", "four"};

    foo1(5, my_argv);
}

 

Мне кажется, что argv не указатель на указатель, скорее это указатель на массив указателей ! И в аргументах функции foo1 правильнее будет записать *argv[] вместо **argv

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

 

Мне больше нравится вот так:

void foo1(char *argv[]) {
   while (*argv)
      printf("\"%s\"\n", *argv++);
}

int main(void) {
  
   char *my_argv[] = {"Hello", "World", "one", "two", "four", NULL};
   foo1(my_argv);
}

 

Мы подчеркнули природу аргумента функции foo1 ,но вынуждено используем "указательные" св-ва масива для упорядоченного, с начала в конец, вывода элементов на "печать".

 

Кароче трудно как-то все получается:(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне кажется, что argv не указатель на указатель, скорее это указатель на массив указателей ! И в аргументах функции foo1 правильнее будет записать *argv[] вместо **argv

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

Со временем придет "чуство" того, что имя массива и указатель - это одно и то-же.

... код не компилится ...

Да, это я ошибся. Нужно *argv++

Ваш вариант, с последним элементом NULL, правильный, тем более что функция main действительно получает массив argv размером на единицу больше, чем argc, с NULL терминатором.

 

Мы подчеркнули природу аргумента функции foo1 ,но вынуждено используем "указательные" св-ва масива для упорядоченного, с начала в конец, вывода элементов на "печать".

 

Короче, трудно как-то все получается:(

Массив и указатель - близнецы братья. При использовании - это одно и то-же. Немного практики, и это станет простым и естественным. И будет непонятно, как некоторые языки не используют указатели. Верной дорогой идете!

Изменено пользователем igorle

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не думаю, что массив и указатель одно и то же. Указатель это переменная, а массив это массив. Существует тесная, родственная связь механизма доступа к данным в массиве по индексам, и адресной арифметикой указателей, но это все же разные вещи.

 

Я спрашивал именно о указателе на указатель. Дело в том что гуглится что-то невразумительное на этот счет. В К&R нет подробного освещения вопроса. Уповаю на ваш експириентс. Спасибо!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Указатель и массив - это не одно и то же. Но имя массива - это указатель на первый его элемент

a[0] то же самое что и *a

a[10] то же самое что и *(a+10)

 

Понятно, что при определении переменной

int a[] и int *b - разные вещи. Но после этого они во многом ведут себя одинаков. Во многом, но не во всем. a нельзя присваивать новое значение, b - можно.

 

int a[10];

int *b = a;

 

Теперь все, что вы хотите делать с a, вы можете делать с b. Обратное не верно

Например b[2] - это то-же самое что и a[2].

 

Я считаю, что это из области, где легче понять чем объяснить. Даже гугл не поможет. И приходит только с небольшим опытом. Просто поиграйте с указателями. Потом - с указателями на указатели. Это действительно просто. Наш экспириенс не поможет. Можете придумыват, писать и компилировать простые примеры из нескольких строк, и задавать конкретные вопросы если не работает. Когда поймете то что говорили про указатели и массивы - посмотрите примеры про обработку связных списков. Там указатели на указатели очень эффективно работают.

 

Можете порешать олимпиаду, про которую я говорил в соседней ветке. Там тоже про указатели на указатели. Если не выиграете приз, то хоть согреетесь.

Изменено пользователем igorle

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Указатель и массив - это не одно и то же. Но имя массива - это указатель на первый его элемент

Дьявол в мелочах (с).

Тот случай, когда пренебежение терминологией, привело к не верному выводу. А именно, "указатель" != "адрес". Имя массива - не "указатель" на первый элемент, а "адрес" первого элемента.

 

P.S.

Оказывается, объяснить тоже не сложно. ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я вот думаю, что указатель на указатель используется только как формальный аргумент функции. А в качестве фактического аргумента используют адрес простого указателя. Не вижу смысла в использовании указателя на указатель где-то еще. Естественно могу ошибаться.

 

Скажите, а где можно посмотреть реализацию отдельных функций описаных в заголовочном файле string.h ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Скажите, а где можно посмотреть реализацию отдельных функций описаных в заголовочном файле string.h ?

http://www.uclibc.org/

 

http://git.uclibc.org/uClibc/tree/libc/string

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я вот думаю, что указатель на указатель используется только как формальный аргумент функции. А в качестве фактического аргумента используют адрес простого указателя. Не вижу смысла в использовании указателя на указатель где-то еще.
Многомерный динамический массив.

int** GenerateArray(int dim1, int dim2)
{
int** rv=new int*[dim1];
for(int i=0;i<dim1;++i)
  rv[i]=new int[dim2];
return rv;
}


// Usage:

int dim1=5;
int dim2=10;

int** my_array=GenerateArray(dim1,dim2);

for(int i=0;i<dim1;++i)
for(int j=0;j<dim2;++j)
   my_array[i][j] = ...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...