The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Строковые типы в C"
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 24-Июн-14, 16:28 
Всем доброго времени суток.
Недавно начал использовать язык программирования С. Интересный язык, должен сказать.

Вот только не могу до конца разобраться со строками.

Строковую переменную можно определить описанными ниже способами:
1) char *lala;
2) char *lala = "lala";
3) char lala[] = "lala";
4) char lala[4];
5) char lala[4] = "lala";
6) char *lala = (char *) malloc (sizeof(char) * 4);

Может быть существуют ещё варианты, но мне пока что повстречались только эти.

Самый первый вопрос, который рождается в голове, это является ли объявления номер 4, 6 идентичными? Тот же вопрос для объявление номер 3 и 5.
В чём разница между объявлениями 5, 2 и 3?

И какое из этих объявлений для каких случаев лучше подходит?

За ранее благодарен.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Строковые типы в C"  +/
Сообщение от Pahanivo (ok) on 24-Июн-14, 17:07 
> Всем доброго времени суток.
> Недавно начал использовать язык программирования С. Интересный язык, должен сказать.

я так понимаю дело дальше абзаца "А давайте напишем программу Hello world ..." не дошло?

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

4. "Строковые типы в C"  –1 +/
Сообщение от noisebringer (ok) on 24-Июн-14, 23:15 
>> Всем доброго времени суток.
>> Недавно начал использовать язык программирования С. Интересный язык, должен сказать.
> я так понимаю дело дальше абзаца "А давайте напишем программу Hello world
> ..." не дошло?

я так понимаю ответ дальше фразы "я так понимаю дело дальше абзаца "А давайте напишем программу Hello world... не дошло?" не дошел?

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

2. "Строковые типы в C"  +/
Сообщение от Evolve32 (ok) on 24-Июн-14, 19:42 
> Самый первый вопрос, который рождается в голове, это является ли объявления номер
> 4, 6 идентичными?

Нет
4 - массив
6 - указатель
> Тот же вопрос для объявление номер 3 и 5.

Нет
3 - массив из 5 символов, а
5 - из 4, причем с выходом за границу массива
> В чём разница между объявлениями 5, 2 и 3?

2 - находится в стеке как константа.
3 - в куче, размер массива определен автоматически
5 - в куче, размер определен ручками

Единственный совет - стек лучше не загромождать и не надеятся, что все libc выделяют для него столько же памяти, сколько glibc

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

3. "Строковые типы в C"  –1 +/
Сообщение от noisebringer (ok) on 24-Июн-14, 23:07 
В первую очередь хотелось бы поблагодарить за адекватный ответ.
Надеюсь вас сильно не затруднит провести небольшой лик-без :)

>> Самый первый вопрос, который рождается в голове, это является ли объявления номер
>> 4, 6 идентичными?
> Нет
> 4 - массив
> 6 - указатель

Что из этого проистекает, как это отражается непосредственно на работе программы?
То есть я ведь могу точно так же сделать strcat в lala и из неё, обращаться посимвольно в обоих вариантах.

>> Тот же вопрос для объявление номер 3 и 5.
> Нет
> 3 - массив из 5 символов, а
> 5 - из 4, причем с выходом за границу массива

Про пять символов вы имеете в виду нолик в конце?

>> В чём разница между объявлениями 5, 2 и 3?
> 2 - находится в стеке как константа.
> 3 - в куче, размер массива определен автоматически
> 5 - в куче, размер определен ручками
> Единственный совет - стек лучше не загромождать и не надеятся, что все
> libc выделяют для него столько же памяти, сколько glibc

Тут всё понятно :)


Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

30. "Строковые типы в C"  +/
Сообщение от Evolve32 (ok) on 26-Июн-14, 10:18 
> В первую очередь хотелось бы поблагодарить за адекватный ответ.
> Надеюсь вас сильно не затруднит провести небольшой лик-без :)
>>> Самый первый вопрос, который рождается в голове, это является ли объявления номер
>>> 4, 6 идентичными?
>> Нет
>> 4 - массив
>> 6 - указатель
> Что из этого проистекает, как это отражается непосредственно на работе программы?
> То есть я ведь могу точно так же сделать strcat в lala
> и из неё, обращаться посимвольно в обоих вариантах.

Все верно, но массив нельзя использовать как lvalue, то есть, т.е., как выражение слева, например:

char x[4];
char *pt;
x = pt; // Ошибка

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

7. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 25-Июн-14, 00:39 
> 5 - из 4, причем с выходом за границу массива

Нет там никакого выхода! Просто нуля в конце не будет. Из этих соображений
эту строку нельзя напрямую юзать в строковых функциях strcpy, strcmp, printf %s и т.д.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

9. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 25-Июн-14, 03:54 
>> 5 - из 4, причем с выходом за границу массива
> Нет там никакого выхода! Просто нуля в конце не будет. Из этих
> соображений
> эту строку нельзя напрямую юзать в строковых функциях strcpy, strcmp, printf %s
> и т.д.

Очень благодарен за дельное замечание!

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

16. "Строковые типы в C"  +/
Сообщение от Andrey Mitrofanov on 25-Июн-14, 09:41 
> Нет там никакого выхода! Просто нуля в конце не будет.

Правда?

$ ./tst.bb
- 0
$ cat tst.c
#include <stdio.h>

char str[4]="abab";
char *canary="zzzz";

int main() {
    printf( "%c - %d\n", str[4], (int)str[4]);
}

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

17. "Строковые типы в C"  +/
Сообщение от Andrey Mitrofanov on 25-Июн-14, 09:51 
>> 5 - из 4, причем с выходом за границу массива
> Нет там никакого выхода! Просто нуля в конце не будет.

А и правда,

$ ./tst.bb
0x6008ec 0x6008f1 0x6008f5
-5/ y - 121
-4/ y - 121
-3/ y - 121
-2/ y - 121
-1/  - 0
  0/ a - 97
  1/ b - 98
  2/ a - 97
  3/ b - 98
  4/ z - 122
  5/ z - 122
  6/ z - 122
  7/ z - 122
  8/  - 0


char canarx[]="yyyy";
char str[4]="abab";
char canary[]="zzzz";

int main() {
    int i;
    printf("%p %p %p\n", canarx, str, canary);
    for(i=-5;i<20;i++)
        printf( "%3d/ %c - %d\n", i, str[i], (int)str[i]);

Ответить | Правка | ^ к родителю #7 | Наверх | Cообщить модератору

12. "Строковые типы в C"  –1 +/
Сообщение от noisebringer (ok) on 25-Июн-14, 04:17 
До этого я имел дело с языками в которых память может распределяться автоматически, а тут такого дела не оказалось и меня мучал вопрос, как сделать так, чтобы не разводить бред из серии lala[1000000] = "lala", а всё остальное свободное.
Оказалось, что здесь это делается так
        char *lala; //Объявляем указатель
        lala = (char *) calloc(strlen("lala") + 1, sizeof(char)); // выделяем в куче кусочек памяти заполненный нулями необходимый для строки lala
        strcat(lala, "lala"); // записываем туда строку lala
        char tutu[5] = "tutu";
        tutu[5] = 0;
        lala = (char *) realloc(lala, (strlen(lala) + strlen(tutu) + 1) * sizeof(char)); //добавляем память для строки tutu
        strcat(lala, tutu); //записываем строку tutu
        printf("lala is %s\n", lala);
        free(lala);
Надеюсь, что здесь всё написано правильно, за исключением обработки возможных ошибок при распределении памяти, но здесь их можно опустить ибо это пример, и тему можно закрывать :)
Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

23. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 26-Июн-14, 02:46 
> Надеюсь, что здесь всё написано правильно,

tutu[5] = 0; /* Array out of bounds. Kernel panic. Topol-M has been started. USA destroyed */

И ваще, это "плохая" строка, забудь про такие фишки (на ближайшие лет 7-8).
Ты либо улетишь за пределы массива, либо затрёшь последний символ.  

Ответить | Правка | ^ к родителю #12 | Наверх | Cообщить модератору

25. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 26-Июн-14, 05:43 
>> Надеюсь, что здесь всё написано правильно,
> tutu[5] = 0; /* Array out of bounds. Kernel panic. Topol-M has
> been started. USA destroyed */
> И ваще, это "плохая" строка, забудь про такие фишки (на ближайшие лет
> 7-8).
> Ты либо улетишь за пределы массива, либо затрёшь последний символ.

Почему out of bounds если изначально массив объявлялся как массив из пяти элементов?
Если не так, то каким образом обозначать окончание строки? '\0' ? И чем отличается '\0' от просто 0?

Ответить | Правка | ^ к родителю #23 | Наверх | Cообщить модератору

26. "Строковые типы в C"  +/
Сообщение от Аноним (??) on 26-Июн-14, 06:44 

>> tutu[5] = 0; /* Array out of bounds. Kernel panic. Topol-M has been started. USA destroyed */

To Pavlinux - Нынче пишут "Курс доллара упал до 0" :-)

> Почему out of bounds если изначально массив объявлялся как массив из пяти элементов?

Всё верно от tutu[0] до tutu[4] :-) Тут вам на васик какой ...

> Если не так, то каким образом обозначать окончание строки? '\0' ? И
> чем отличается '\0' от просто 0?

Да не поможет это. Этот код:
char tutu[5] = "tutu";
посмотри в ассемблере чего делает - это константная строка, еЯ менять нельзя.
Да - да в ассемблере, тут вам не васик, тут ты по локоть в железе :)

Ответить | Правка | ^ к родителю #25 | Наверх | Cообщить модератору

27. "Строковые типы в C"  +/
Сообщение от Аноним (??) on 26-Июн-14, 06:59 
> Да не поможет это. Этот код:
> char tutu[5] = "tutu";
> посмотри в ассемблере чего делает - это константная строка, еЯ менять нельзя.

Ага ... сам посмотрел. Для 4.7.2 это больше не так :) Ложет их в .data - то есть менять - можно.

Сорьки - лопухнулся йа :)

Ответить | Правка | ^ к родителю #26 | Наверх | Cообщить модератору

33. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 27-Июн-14, 02:17 
>>> tutu[5] = 0; /* Array out of bounds. Kernel panic. Topol-M has been started. USA destroyed */
> To Pavlinux - Нынче пишут "Курс доллара упал до 0" :-)

Они ещё напечатают.

Ответить | Правка | ^ к родителю #26 | Наверх | Cообщить модератору

29. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 26-Июн-14, 09:22 
>>> Надеюсь, что здесь всё написано правильно,
>> tutu[5] = 0; /* Array out of bounds. Kernel panic. Topol-M has
>> been started. USA destroyed */
>> И ваще, это "плохая" строка, забудь про такие фишки (на ближайшие лет
>> 7-8).
>> Ты либо улетишь за пределы массива, либо затрёшь последний символ.
> Почему out of bounds если изначально массив объявлялся как массив из пяти
> элементов?
> Если не так, то каким образом обозначать окончание строки? '\0' ? И
> чем отличается '\0' от просто 0?

Правда-правда. Опять попутал с количественными и порядковыми циферками :))
tutu[4] = 0
а элементы 0,1,2,3 занимают четыре элемента строки.
Благодарен за напоминание :)

Ответить | Правка | ^ к родителю #25 | Наверх | Cообщить модератору

32. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 27-Июн-14, 01:17 
> И чем отличается '\0' от просто 0?

типами: первый - char, второй - int.
(Но по секрету, char во внутреннем представлении С это int. Только я тебе это не говорил)

void main() {
       int i;
        for (i=0x30; i < 0x80; i++)
             write(0, &i, 1);
}

вот эта хрень вроде должна напечатать все видимые символы.

Ответить | Правка | ^ к родителю #25 | Наверх | Cообщить модератору

6. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 25-Июн-14, 00:07 
> Может быть существуют ещё варианты, но мне пока что повстречались только эти.

char *lala[] = {"lala"};

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

10. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 25-Июн-14, 03:55 
>> Может быть существуют ещё варианты, но мне пока что повстречались только эти.
> char *lala[] = {"lala"};

Мусье знает толк в извращениях :)

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

18. "Строковые типы в C"  –1 +/
Сообщение от Аноним (??) on 25-Июн-14, 10:56 
> Тьфу, ёклмн. Не туда написал сообщение. В общем заинтересованные личности найдут.

2) char *lala = "lala";

и словишь разыменование NULL-указателя.

Ответить | Правка | ^ к родителю #6 | Наверх | Cообщить модератору

24. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 26-Июн-14, 03:08 
>> Тьфу, ёклмн. Не туда написал сообщение. В общем заинтересованные личности найдут.
> 2) char *lala = "lala";
> и словишь разыменование NULL-указателя.

Чей-то вдруг?

Ответить | Правка | ^ к родителю #18 | Наверх | Cообщить модератору

28. "Строковые типы в C"  +/
Сообщение от Andrey Mitrofanov on 26-Июн-14, 09:19 
>> 2) char *lala = "lala";
>> и словишь разыменование NULL-указателя.
> Чей-то вдруг?

lala=NULL; И "Усё пропало, шеф!"

Ответить | Правка | ^ к родителю #24 | Наверх | Cообщить модератору

31. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 27-Июн-14, 01:15 
>>> 2) char *lala = "lala";
>>> и словишь разыменование NULL-указателя.
>> Чей-то вдруг?
> lala=NULL; И "Усё пропало, шеф!"

Ну надеюсь этот код в конце функции, и пырыменная ляля больше не юзается?  

Ответить | Правка | ^ к родителю #28 | Наверх | Cообщить модератору

34. "Строковые типы в C"  –2 +/
Сообщение от noisebringer (ok) on 30-Июн-14, 16:51 
Нашел для себя отличие между вариантами 4 и 6.
Вариант 4 компилятор не дает использовать внутри функций.
Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

35. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 30-Июн-14, 17:05 
> Нашел для себя отличие между вариантами 4 и 6.
> Вариант 4 компилятор не дает использовать внутри функций.

Чёй-то вдруг?

char lala[4];
memset(lala, 0, sizeof(lala)/sizeof(lala[0]));

По-стандарту - массив не инициализированный, по-gcc - там нули.
и даже printf отработает нормально.

Ответить | Правка | ^ к родителю #34 | Наверх | Cообщить модератору

36. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 30-Июн-14, 17:11 
warning: function returns address of local variable

Это говорит компилятор примерно в таком случае:

char *f() {
char lala[10];
return lala;
}

int main() {
printf("%s", f());
return 0;
}

Ответить | Правка | ^ к родителю #35 | Наверх | Cообщить модератору

37. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 30-Июн-14, 18:53 
> warning: function returns address of local variable

Ну правильно - в ресторан со своими напитками нельзя!
Либо тут покупай, либо не занимай столик.

> Это говорит компилятор примерно в таком случае:
> char *f() {
>  char lala[10];
>  return lala;
> }
> int main() {
>  printf("%s", f());
>  return 0;
> }

Надо как "настоящие" кодеры - объявить lala[10] как глобальную переменную :)
<offtop> Первый признак - чем больше глобальных переменных, тем дол..ёбистей программер :)</offtop>


char lala[10];
char *f() {
       return lala;
}
int main() {
     return printf("%s", f());
}

Ответить | Правка | ^ к родителю #36 | Наверх | Cообщить модератору

38. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 30-Июн-14, 20:27 
Меня только одно беспокоит.
Для того чтобы функция могла возвращать указатель, нужно чтобы в ней делался alloc какого-то количества памяти. А если делается alloc, то его нужно free. А если перед окончанием функции сделать его free, то, по идее, это значит что память где хранится результат и куда в дальнейшем будет ссылаться основной код как бы free и в любой момент может быть потерта.
Но если не в конце функции, то где делать это free.

P.S. Спасибо за лестное замечание. На данный момент глобальные переменные отсутствуют :)

Ответить | Правка | ^ к родителю #37 | Наверх | Cообщить модератору

39. "Строковые типы в C"  +/
Сообщение от Аноним (??) on 30-Июн-14, 20:43 
> Меня только одно беспокоит.

Твой доктор беспокоится ещё больше. Он уже произносил "мы его теряем! " ....

> Для того чтобы функция могла возвращать указатель, нужно чтобы в ней делался
> alloc какого-то количества памяти.

Похоже зря твой доктор волнуется. Мы тебя уже потеряли, спи спокойно моск noisebringer'a ...


Ответить | Правка | ^ к родителю #38 | Наверх | Cообщить модератору

40. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 30-Июн-14, 20:51 
А вот тут не понял. Чтобы функция могла вернуть ссылку на какую-то область памяти, и в этой области памяти что-то лежало, то нужно сначала выделить эту область, потом сложить туда что-то. А потом вернуть ссылку на эту область.

Но если делается alloc, то где-то должен делаться free. Где?

Ответить | Правка | ^ к родителю #39 | Наверх | Cообщить модератору

41. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 01-Июл-14, 02:35 
> А вот тут не понял. Чтобы функция могла вернуть ссылку на какую-то
> область памяти, и в этой области памяти что-то лежало, то нужно
> сначала выделить эту область, потом сложить туда что-то. А потом вернуть
> ссылку на эту область.
> Но если делается alloc, то где-то должен делаться free. Где?

char *myfunc() { /* тут объявили, адрес ужо есть */
   char *lala = (char *)malloc(10);
   return lala;
}

// Чо происходит?!: *myfunc указывает на lala, *lala на 10-байтный кусок.

void main() {

   char *dudu = myfunc();  // dudu -> myfunc -> lala -> 10;
   free(dudu);  //
}

Отседа вывод - можно сделать даже так:

void main() {
   free(myfunc());
}

Ответить | Правка | ^ к родителю #40 | Наверх | Cообщить модератору

42. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 01-Июл-14, 05:46 
Так я и предполагал, так я и сделал :)
Указатели на функции. Видел краем глаза, но пока возиться не охото, но они быстрее говорять.
Ответить | Правка | ^ к родителю #41 | Наверх | Cообщить модератору

43. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 01-Июл-14, 09:38 
Ой. Перепутал :) Не указатель на функцию :)
В общем идею уяснил :)
Ответить | Правка | ^ к родителю #42 | Наверх | Cообщить модератору

44. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 01-Июл-14, 21:04 
> Указатели на функции.

Тоже можно, но через ж...у


char *myfunc() {
        char *lala = (char *)malloc(10);
        return lala;
}

void main() {

        char* (*dudu)() = myfunc;
        (*dudu)();
        free(dudu);
}


Ответить | Правка | ^ к родителю #42 | Наверх | Cообщить модератору

45. "Строковые типы в C"  +/
Сообщение от Andrey Mitrofanov on 02-Июл-14, 10:02 
>         free(dudu);

malloc(sizeof) + memcpy забыл для полного комплекта. </code review>

Ответить | Правка | ^ к родителю #44 | Наверх | Cообщить модератору

46. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 02-Июл-14, 12:19 
Насколько я знаю это не через ж**у, а так быстрее работать будет. Указатели на функции вроде как быстрее.
Ответить | Правка | ^ к родителю #44 | Наверх | Cообщить модератору

47. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 02-Июл-14, 14:45 
>  вроде как быстрее.

Как быстрее, это уже следующий уровень, после K&R
Затем: Как меньше.
Потом: Как меньше и быстрее.
И последний: А ну вас в ж...у, все равно никто не оплачивает. Ушел на C++/PHP/HTML/QT/JS/...

Ответить | Правка | ^ к родителю #46 | Наверх | Cообщить модератору

48. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 02-Июл-14, 19:41 
K&R?
Ответить | Правка | ^ к родителю #47 | Наверх | Cообщить модератору

50. "Строковые типы в C"  +/
Сообщение от anonymous (??) on 03-Июл-14, 00:32 
> Насколько я знаю это не через ж**у, а так быстрее работать будет.
> Указатели на функции вроде как быстрее.

Да-да, послушай идиотов. Его free(dudu) равнозначен free(myfunc), что являет собой адрес функции, который с динамической памятью связан чуть менее, чем никак. И покажи мне того полудурка, который что-то сказал о "быстрее" и "указатели на функции". Вся ветка вообще бред немыслимый, беги отсюда пока таким же не стал, мой тебе совет.

Ответить | Правка | ^ к родителю #46 | Наверх | Cообщить модератору

51. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 03-Июл-14, 02:00 
>> Насколько я знаю это не через ж**у, а так быстрее работать будет.
>> Указатели на функции вроде как быстрее.
> Да-да, послушай идиотов. Его free(dudu) равнозначен free(myfunc),

Ты всех авторов ядра назвал лохами!
На изучай, только как школу закончишь:  https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux....

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

Ога, ваще не связан, ну разве только, что указывает на кусок динамической памяти,
а так да... ваще никак..

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

Толсто

Ответить | Правка | ^ к родителю #50 | Наверх | Cообщить модератору

53. "Строковые типы в C"  +/
Сообщение от Andrey Mitrofanov on 03-Июл-14, 09:24 
>>Его free(dudu) равнозначен free(myfunc),
> Ты всех авторов ядра назвал лохами!
> На изучай, только как школу закончишь:  torvalds/linux.git/tree/mm/slab.c
> Толсто
Ответить | Правка | ^ к родителю #51 | Наверх | Cообщить модератору

54. "Строковые типы в C"  +/
Сообщение от anonymous2 on 03-Июл-14, 20:18 
Собери свой выхлоп, прочитай ради приличия выхлоп компилятора, запусти полученный бинарник.
Запустил? Теперь забейся в угол и рыдай, бессмысленный бот.
Ответить | Правка | ^ к родителю #51 | Наверх | Cообщить модератору

55. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 04-Июл-14, 02:40 
> Собери свой выхлоп, прочитай ради приличия выхлоп компилятора,

Пффф... придумал тоже. У меня тут целый зоопарк кодеров за меня это делает.

Ответить | Правка | ^ к родителю #54 | Наверх | Cообщить модератору

49. "Строковые типы в C"  +/
Сообщение от anonymous (??) on 03-Июл-14, 00:21 
Форум на опеннете все такой же детсад и раковник, анонимус вахуе.

> 1) char *lala;

Указатель как указатель, значение мусор.

> 2) char *lala = "lala";

Указатель на статичную строку (далее литерал), кстати const char *, т.к. "lala" имеет именно такой тип.

> 3) char lala[] = "lala";

Автоматический массив из пяти char'ов, скопированный из литерала. Массив не указатель.

> 4) char lala[4];

Автоматический массив из четырех char'ов с мусором.

> 5) char lala[4] = "lala";

Автоматический массив из четырех char'ов, скопированный из литерала. Си-строкой не является.

> 6) char *lala = (char *) malloc (sizeof(char) * 4);

Динамический массив из четырех char'ов. Си-строкой не является, т.к. внутри мусор. Канонично "= malloc(4)" без каста.

> Может быть существуют ещё варианты, но мне пока что повстречались только эти.

Подружись с к-н книжкой, не надо тыкать пальцем в небо и искать себе подобных.
Си-строка это последовательность char'ов, заканчивающаяся нулевым символом ('\0'). "lala" это 5 символов (ноль неявный). Другие последовательности по определению строками не являются. Четырех-символьный массив не сможет содержать "lala", потому что не хватает места для конечного нуля. Где находится строка -- неважно, но это может быть автоматическая память (стек), динамическая (malloc), или статическая (литералы и глобальные массивы (не указатели)). Указатель и массив условно взаимозаменяемы, если говорить по-детсадовски, т.к. оба являют собой адрес первого символа (но типы имеют разные; почему и как -- RTFM).

> За ранее благодарен.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

52. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 03-Июл-14, 02:02 
> Си-строка это последовательность char'ов, заканчивающаяся нулевым символом ('\0').

И кто тут идиот?! :D В Си ваще нет строк, а ноль в конце это для лохов,
которые границы не указывают.

> Четырех-символьный массив не сможет содержать "lala",

char lala[4] = {'l','a','l','a'};  Всё пиштец, массив, 4 символа.  
и прикинь, даже в stdout заслать можно  write(1, lala, 4);

>  Указатель и массив условно взаимозаменяемы,

Шёл бы ты мимо.

Ответить | Правка | ^ к родителю #49 | Наверх | Cообщить модератору

56. "Строковые типы в C"  –1 +/
Сообщение от datswd on 04-Ноя-14, 18:49 
Результатом стало следующее.

Для того чтобы в C по-человечески работать с строками была создана библиотека mstring, функции которой выполняя операции со строками выделяют соответствующее количество памяти в куче.

------mstring.h
char* Msprintf(char* To, char* Fmt, ...);
//форматированный вывод в строку To с заменой её содержимого

char* MCsprintf(char* To, char* Fmt, ...);
//форматированный вывод в конец строки To

char* Mstrcat(char* CatTo, char* ToCat);
//Вывод строки ToCat в переменную CatTo

char* Mstrcpy(char* CpyTo, char* ToCpy);
//Копирование строки ToCpy в строку CpyTo

int IsPosDigit(char* ToCheck);
//Является ли строка ToCheck положительным числом, то есть все символы 0-9

И со строкой работать нужно вот так вот.

char* MyString = NULL //Определяем указатель

int I = 5;
MyString = Msprintf(MyString, "lalala blblb %i", I); //Делаем форматированный вывод в строку MyString
printf("%s", MyString); //Выводим строку MyString

if(MyString) free(MyString); //Если MyString не NULL освобождаем выделенную память


Ну и собственно исходный код библиотеки.


------mstring.c

char* MCsprintf(char* To, char* Fmt, ...) {
    va_list Ptr;
    va_start(Ptr, Fmt);
    int L = vsnprintf(NULL, 0, Fmt, Ptr);
    va_end(Ptr);
    int M = To ? strlen(To) : 0;
    To = (char *)realloc(To, (L + M + 2) * CHAR_SIZE);
    va_start(Ptr, Fmt);
    vsprintf(To + M, Fmt, Ptr);
    va_end(Ptr);
    return To;
}

char* Msprintf(char* To, char* Fmt, ...) {
    va_list Ptr;
    va_start(Ptr, Fmt);
    int L = vsnprintf(NULL, 0, Fmt, Ptr);
    va_end(Ptr);
    if(To) free(To);
    To = (char *)calloc((L + 2), CHAR_SIZE);
    va_start(Ptr, Fmt);
    vsprintf(To, Fmt, Ptr);
    va_end(Ptr);
    return To;
}

int IsPosDigit(char *ToCheck) {
    if(ToCheck && strlen(ToCheck)) {
        int I = 0;
        for(I = 0; I < strlen(ToCheck); I++) if(!isdigit(ToCheck)) return 0;
        return 1;
    }
    else return 0;
}

char* Mstrcat(char* CatTo, char* ToCat) {
    int P = CatTo ? strlen(CatTo) : 0;
    CatTo = (char*)realloc(CatTo, (P + strlen(ToCat) + 2) * CHAR_SIZE);
    strcpy(CatTo + P, ToCat);
    return CatTo;
}

char* Mstrcpy(char* CpyTo, char* ToCpy) {
    if(ToCpy) {
        if(CpyTo) free(CpyTo);
        CpyTo = (char*)calloc(strlen(ToCpy) + 2, CHAR_SIZE);
        strcpy(CpyTo, ToCpy);
    }
    return CpyTo;
}

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

57. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 04-Ноя-14, 19:46 
> Для того чтобы в C по-человечески работать

Оптимист :)

Ответить | Правка | ^ к родителю #56 | Наверх | Cообщить модератору

58. "Строковые типы в C"  +/
Сообщение от noisebringer (ok) on 05-Ноя-14, 16:40 
>> Для того чтобы в C по-человечески работать
> Оптимист :)

Спасибо. :)
А что вы думаете о самом подходе к работе со строками?

Ответить | Правка | ^ к родителю #57 | Наверх | Cообщить модератору

59. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 05-Ноя-14, 18:26 
> А что вы думаете о самом подходе к работе со строками?

Хреново. Точнее банально.

Нет проверки размеров строк.
Нет проверки malloc и Сo.
Нет поддержки UTF8/16/32
strcpy/strlen - легко Досятся
куча NULL-dereference  
+2 - какой-то непонятный констант.  

Ответить | Правка | ^ к родителю #58 | Наверх | Cообщить модератору

60. "Строковые типы в C"  +/
Сообщение от datswd on 10-Ноя-14, 18:10 
>> А что вы думаете о самом подходе к работе со строками?
> Хреново. Точнее банально.
> Нет проверки размеров строк.
> Нет проверки malloc и Сo.
> Нет поддержки UTF8/16/32
> strcpy/strlen - легко Досятся
> куча NULL-dereference
> +2 - какой-то непонятный констант.

Не без этого :) И у мастерорв бывают люпы.
А какой подход используете вы?

P.S. Шутка :)

Ответить | Правка | ^ к родителю #59 | Наверх | Cообщить модератору

61. "Строковые типы в C"  +/
Сообщение от datswd on 10-Ноя-14, 18:11 
>> А что вы думаете о самом подходе к работе со строками?
> Хреново. Точнее банально.
> Нет проверки размеров строк.
> Нет проверки malloc и Сo.
> Нет поддержки UTF8/16/32
> strcpy/strlen - легко Досятся

Что значи досятся? Переполняются?
> куча NULL-dereference
> +2 - какой-то непонятный констант.

Ответить | Правка | ^ к родителю #59 | Наверх | Cообщить модератору

62. "Строковые типы в C"  –2 +/
Сообщение от NoiseBringer (??) on 12-Янв-15, 07:50 
Офигеть конечно, но, мне кажется, что все, кто тут отписывались меня затролили, если так то с...

В библиотеке stdio.h есть функция asprintf, которая как раз-таки позволяет по-человечески работать со строками. И самое в ней интересное, что в ней можно использовать рекурсию, в итоге её можно превратить в strcat с выделением памяти и много-много всего.

Код
    char *lala = NULL;
    asprintf(&lala, "ddd");
    asprintf(&lala, "%saaa", lala);
    printf("%s", lala);
Выведет
dddaaa

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

63. "Строковые типы в C"  +/
Сообщение от Alex_S (??) on 13-Янв-15, 10:11 
>[оверквотинг удален]
> работать со строками. И самое в ней интересное, что в ней
> можно использовать рекурсию, в итоге её можно превратить в strcat с
> выделением памяти и много-много всего.
> Код
>     char *lala = NULL;
>     asprintf(&lala, "ddd");
>     asprintf(&lala, "%saaa", lala);
>     printf("%s", lala);
> Выведет
> dddaaa

   free только делать придется

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

Ответить | Правка | ^ к родителю #62 | Наверх | Cообщить модератору

64. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 17-Янв-15, 08:10 
>    free только делать придется

Это само собой.

>    а откуда вообще такая тяга к динамической аллокации строк ?

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

>   вон под ddd - константа вообще  -  у
> тебя указатель потерялся же , утечка будет , не  ?

О каком именно участке кода идет речь?


Ответить | Правка | ^ к родителю #63 | Наверх | Cообщить модератору

66. "Строковые типы в C"  +/
Сообщение от Alex_S (??) on 19-Янв-15, 05:49 

> О каком именно участке кода идет речь?
>     asprintf(&lala, "ddd");
>     asprintf(&lala, "%saaa", lala);

аллокировал память под ddd , lala  на него указывает
потом аллокировал под dddaaa и переписал указатель .  ddd утекло .

Ответить | Правка | ^ к родителю #64 | Наверх | Cообщить модератору

67. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 19-Янв-15, 06:23 
>> О каком именно участке кода идет речь?
>>     asprintf(&lala, "ddd");
>>     asprintf(&lala, "%saaa", lala);
>  аллокировал память под ddd , lala  на него указывает
>  потом аллокировал под dddaaa и переписал указатель .  ddd утекло
> .

Бывает...

Ответить | Правка | ^ к родителю #66 | Наверх | Cообщить модератору

68. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 19-Янв-15, 17:08 
>> О каком именно участке кода идет речь?
>>     asprintf(&lala, "ddd");
>>     asprintf(&lala, "%saaa", lala);
>  аллокировал память под ddd , lala  на него указывает
>  потом аллокировал под dddaaa и переписал указатель .  ddd утекло
> .

А если на самом деле.

    char *lala = NULL;
    printf("%p\n", &lala);

    asprintf(&lala, "ddd");
    printf("%p\n", &lala);

    asprintf(&lala, "%saaa", lala ? lala : "");
    printf("%p\n", &lala);

    printf("%s", lala);

Выведет

0x7ffff40cfe68
0x7ffff40cfe68
0x7ffff40cfe68
dddaaa

Ответить | Правка | ^ к родителю #66 | Наверх | Cообщить модератору

71. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 22-Янв-15, 02:50 
> А если на самом деле.
> Выведет
> 0x7ffff40cfe68
> 0x7ffff40cfe68
> 0x7ffff40cfe68
> dddaaa

Это всё так, но только в академиеских примерах


Ответить | Правка | ^ к родителю #68 | Наверх | Cообщить модератору

76. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 22-Янв-15, 14:40 
>> А если на самом деле.
>> Выведет
>> 0x7ffff40cfe68
>> 0x7ffff40cfe68
>> 0x7ffff40cfe68
>> dddaaa
> Это всё так, но только в академиеских примерах

А дальше? Подобными изречениями вы создаете образ дилетанта...

Ответить | Правка | ^ к родителю #71 | Наверх | Cообщить модератору

78. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 22-Янв-15, 15:26 
>> А если на самом деле.
>> Выведет
>> 0x7ffff40cfe68
>> 0x7ffff40cfe68
>> 0x7ffff40cfe68
>> dddaaa
> Это всё так, но только в академиеских примерах

Теперь понял о чём речь и написал об этом чуть ниже.

Мог бы конечно извиниться, но не хочется, потому что сказал А, говори и Б. А если не хочется Б говорить, то не говори и А.

Ответить | Правка | ^ к родителю #71 | Наверх | Cообщить модератору

79. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 24-Янв-15, 23:02 
> что сказал А, говори и Б

Лень и поэтому готов признать себя какашкой :)

Ответить | Правка | ^ к родителю #78 | Наверх | Cообщить модератору

80. "Строковые типы в C"  +/
Сообщение от Аноним (??) on 31-Янв-15, 10:16 
> Лень и поэтому готов признать себя какашкой :)

У, павлин, теперь ты не отвертишься. В букмарки :)

Ответить | Правка | ^ к родителю #79 | Наверх | Cообщить модератору

65. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 17-Янв-15, 08:13 
>    а откуда вообще такая тяга к динамической аллокации строк
> ?

Ну или например запрос к базе, который может вернуть как 10 байт так и 10000 байт. Можно Можно конечно сделать массив, который будет постоянно занимать в памяти максимально возможную длинну (например 20000 байт), а можно динамически обработать.


Ответить | Правка | ^ к родителю #63 | Наверх | Cообщить модератору

72. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 22-Янв-15, 02:51 
>    free только делать придется

alloca(); но с ней всё сложно, особо для серьёзных программ.  

Ответить | Правка | ^ к родителю #63 | Наверх | Cообщить модератору

73. "Строковые типы в C"  +/
Сообщение от Alex_S (??) on 22-Янв-15, 05:05 
>>    free только делать придется
> alloca(); но с ней всё сложно, особо для серьёзных программ.

  экзотичненько , чо

  asprintf использует  malloc  ,
  хотя можно и свою имплементацию наваять ..

Ответить | Правка | ^ к родителю #72 | Наверх | Cообщить модератору

74. "Строковые типы в C"  +/
Сообщение от Alex_S (??) on 22-Янв-15, 05:09 

а зачем пост потерли про указатели  ? есть что-то нецензурное в том факте, что

  printf("%p\n", &lala);

   выведет адрес указателя , который не изменится,
   но содержимое его перетрется вторым вызовом  asprintf-a  и доступ к ddd  будет таки потерян ?

  

Ответить | Правка | ^ к родителю #73 | Наверх | Cообщить модератору

77. "Строковые типы в C"  +/
Сообщение от NoiseBringer (??) on 22-Янв-15, 15:25 
> а зачем пост потерли про указатели  ? есть что-то нецензурное в
> том факте, что
>   printf("%p\n", &lala);
>    выведет адрес указателя , который не изменится,
>    но содержимое его перетрется вторым вызовом  asprintf-a  
> и доступ к ddd  будет таки потерян ?

Вы, таки, были правы.
Проблема была в том, что я был абсолютно уверен в 2х вещах. Во-первых, я думал, что если несколько раз на один и тот же указатель вызвать malloc, то будет ошибка. Оказывается нет. Во-вторых, исходя из первого, я думал, что asprintf использует realloc.

И в самом деле утекает память. :)

P.S. Извиняюсь за то, что попросил модераторов грохнуть ваши сообщения, ибо посчитал их абсолютным бредом :)

Ответить | Правка | ^ к родителю #74 | Наверх | Cообщить модератору

75. "Строковые типы в C"  +/
Сообщение от pavlinux (ok) on 22-Янв-15, 05:36 
>   хотя можно и свою имплементацию наваять ..

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

Ответить | Правка | ^ к родителю #73 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру