Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.77/137: Рейтинг темы: голосов - 137, средняя оценка - 4.77
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36

инициализация char (уточнение )

05.12.2011, 23:46. Показов 27982. Ответов 33
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
товарищи, как я понимаю, такая инициализация в Си не верна:

C
1
char *pChar = "dsfdsfdsf"
коли да, почему я в интернетах часто встречаю её?
или всё же она верна?
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
05.12.2011, 23:46
Ответы с готовыми решениями:

Error C2440: инициализация: невозможно преобразовать 'int' в 'char [100]'
#include "stdafx.h" #include <string.h> const int max=100; void strcat(char dest, char src) { int n=strlen(dest); ...

Инициализация char в классе
Не понимаю, как поместить символьный массив в класс. На выводе получаются случайные символы. class Person { char last_name; public: ...

Инициализация char массива
Мне нужно объявить и инициализировать массив char'ов. К примеру, char *m_words={'1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; ...

33
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
06.12.2011, 01:28
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от testsova Посмотреть сообщение
точно, спасибо.
ради интереса, можно заставить, например gcc, вести по-иному. чтобы он даже для одинаковых констант?

и вот ещё нюанс
C
1
2
3
4
5
6
const char* sz = "hello";
   printf ("%p\n", sz);
   sz = "test";
   printf ("%p\n", sz);
   sz = "hello";
   printf ("%p\n", sz);
Bash
1
2
3
4
%./a.out
0x400668
0x400672
0x400668
в данном примере нет ничего удивительного. Указатель cz у вас не объявлен как константный, константная память "hello\0" на которую указатель указывает неизменима (должна быть по идее), а указатель переписать можно на что угодно. Другое дело вы попытаетесь изменить данные, тут компилятор (gcc точно) даже не построит код. Пример, где мы пытаемся изменить константные данные
C
1
2
3
    const char *p = "ghj";
    p = "test";
    p[ 0 ] = 'p';  //error: assignment of read-only location ‘*p’
другой пример где мы пытаемся изменить константный указатель
C
1
2
3
    char *const p = "ghj";
    p[ 0 ] = 'p';
    p = "test";    //error: assignment of read-only variable ‘p’
Добавлено через 49 секунд
Цитата Сообщение от easybudda Посмотреть сообщение
который так и не поверил, что слово "будет" через е пишется?
спасибо, повеселило
0
Заблокирован
06.12.2011, 01:32
Цитата Сообщение от Net_Wanderer Посмотреть сообщение
здесь то же самое...
Не тоже самое.

C++
1
2
3
int n = 1;  //компилятор инициализирует переменную n числом 1
                       //для этого, ему не нужно знать адрес циферки 1
                        //нужно знать лишь значение самой циферки
C++
1
2
3
const char* sz = "hello"; //здесь требуется присвоить 
                                    //адрес литерной константы
//Это вынудит компилятор поместить  константу туда, где у неё можно будит взять адрес
C++
1
2
3
4
char sz = ("hello")[0];  //здесь переменной присваивается значение 
                                 //первого элемента литерной константы
//возможно, компилятор просто тупо подсунет переменой символ 'h',
//а вот под саму константу даже памяти не выделит.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
06.12.2011, 01:47
http://msdn.microsoft.com/en-u... e775t.aspx

The result of modifying a string constant is undefined. For example:
char *szStr = "1234";
szStr[2] = 'A'; // Results undefined
Добавлено через 12 минут
Вот еще какая-то статейка
http://learningcppisfun.blogsp... -in-c.html
Не знаю на сколько там все достоверно. Кому не лень, посмотрите что в стандарте написано. В статье есть ссылки на всякие разделы из стандарта.
0
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36
06.12.2011, 02:06  [ТС]
к моему стыду у меня всё равно непонятица:

а переменной типа char* можно присваивать значение функции возвращающей char*, вот так:

C
1
char *tmp = inet_ntoa(clientaddr.sin_addr);
кажеццо, можно. но что получается на пальцах?
как я понимаю, это строка, равносильна вот этой:
C
1
char *tmp ="blaha muha";
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
06.12.2011, 02:10
Цитата Сообщение от testsova Посмотреть сообщение
кажеццо, можно. но что получается на пальцах?
как я понимаю, это строка, равносильна вот этой:
нет. во втором случае справа в кавычках - строковый литерал, он константный по определению.
в первом случае - нет.
0
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36
06.12.2011, 02:47  [ТС]
хорошо, патсаны.
тогда ни соблаговолите ли вот сюды глянуть:

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void
connect()
{
    char *ip = NULL;
    uint16_t port;
    int connectedSocket = acceptConnection(listenSocket, &ip,
                           &port);
    if (connectedSocket == -1) {
        perror("accept");
    } else {
        FD_SET(connectedSocket, &readfdset);
        if (insertClient(&clients_head, &connectedSocket,
                 &ip, &port) == -1) {
            //---------------//
            printf("\nWARNING:insertion client info lost!\n");
        }
    }
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int
acceptConnection(int sockFD, char **charClntAddr, uint16_t *port)
{
    int acceptFD;
 
    struct sockaddr_in clientaddr;
    socklen_t addrlen = sizeof(clientaddr);
    acceptFD = accept(sockFD, (struct sockaddr*) &clientaddr,
                   &addrlen);
 
    if (charClntAddr != NULL) {
        *charClntAddr = inet_ntoa(clientaddr.sin_addr);
    }
 
    if (port != NULL) {
        *port = ntohs(clientaddr.sin_port);
    }
 
    return acceptFD;
}

из функции connect() вызывается функция acceptConnection(), в которую передаются указатель ip.

там он очень легко обрабатывается вот так:

C
1
2
3
    if (charClntAddr != NULL) {
        *charClntAddr = inet_ntoa(clientaddr.sin_addr);
    }
является ли это идиологически корректным (грамотным, красивым)? или хотя бы "потянет" ?
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
06.12.2011, 03:18
зачем на нуль проверять?
C
1
2
3
4
5
acceptConnection(int sockFD, char **charClntAddr, uint16_t *port)
{
..............
if (charClntAddr != NULL)
}
C
1
2
3
4
5
6
7
8
9
10
11
void f (char **x)
{
    printf("%x", x);
}
 
int main( void )
{
    char *x;
    f(&x);
    return 0;
}
0
Заблокирован
06.12.2011, 03:24
Цитата Сообщение от testsova Посмотреть сообщение
является ли это идиологически корректным (грамотным, красивым)? или хотя бы "потянет" ?
Вот так, навскидку, не вижу никаких проблем.
Хотя я не знаю, что именно делает, например, функция accept()

Цитата Сообщение от alkagolik Посмотреть сообщение
зачем на нуль проверять?
Наверное, что бы программа знала как себя вести, если кто нибудь, вместо живого указателя закинет нулл:

C
1
int connectedSocket = acceptConnection(listenSocket, NULL, *&port);
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
06.12.2011, 03:26
кроме прочего
The inet_ntoa() function converts the Internet host address in, given in network byte order, to a string in IPv4 dotted-decimal notation. The string is returned in a statically allocated buffer, which subsequent calls will overwrite.
так что если функция вызывается не однажды, то указатель будет указывать на последний результат вызова.
0
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36
18.12.2011, 04:13  [ТС]
товарищи! я пробегался по своему коду. и снова задрочился в одном месте. три-четыре сообщения назад я спрашивал вас: корректно ли делать так, как я делаю. некоторые из ответили - что верно. мне кажется это не так. вот так делать верно:

C
1
2
    char *ip; uint16_t port;
    connect_client(sock, &ip, &port);
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int
connect_client(const int sock, char **clientip, uint16_t *clientport)
{
    struct sockaddr_in addr;
    socklen_t addrlen;
    int newsock;
    char tmp[INET_ADDRSTRLEN];
    size_t len;
 
    addrlen = sizeof(addr);
    newsock = accept(sock, (struct sockaddr *) &addr, &addrlen);
    if (newsock == -1) {
//      error handler
    }
 
    if (clientip != NULL) {
        inet_ntop(PF_INET, &addr.sin_addr.s_addr,
            tmp, sizeof(tmp));
        len = strlen(tmp)+1;
        *clientip = malloc(len*sizeof(char));
        strncpy(*clientip, tmp, len);
    }
 
    if (clientport != NULL)
        *clientport = addr.sin_port;
 
    return newsock;
}

попытаюсь объяснить: когда мы делаем так

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
int
connect_client(int sockFD, char **charClntAddr, uint16_t *port)
{
        int acceptFD;
 
        struct sockaddr_in clientaddr;
        socklen_t addrlen = sizeof(clientaddr);
        acceptFD = accept(sockFD, (struct sockaddr*) &clientaddr,
                                   &addrlen);
 
        if (charClntAddr != NULL) {
                *charClntAddr = inet_ntoa(clientaddr.sin_addr);
        }
 
        if (port != NULL) {
                *port = ntohs(clientaddr.sin_port);
        }
 
        return acceptFD;
}
мы прираниваем указателю указатель на некотрую область памяти, которую вернула функция inet_ntoa(). но ведь это облась памяти "уничтожается" при выходе из фукнции connect_client(), т.е. что-то типа undefined behavior.

т.е. надо обязательно выделять память на указатель. правильно я понимаю?
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
18.12.2011, 04:32
Цитата Сообщение от testsova Посмотреть сообщение
т.е. надо обязательно выделять память на указатель. правильно я понимаю?
удивляюсь вам. Программируете сетевые приложения, а фундаментальные вещи не знаете. Итак проведем ликбез. Поскольку вы программируете в юникс, то наверняка слышали что существуют man'ы. Пишем man inet_ntoa. и видим полезную информацию, внимательно ее читаем и находим строки, из поста 29. Где черным по белому написано что функция inet_ntoa возвращает указатель на "строку", которая расположена в статическом буфере (массиве), который в свою очередь будет перезаписан при следующем вызове функции. Кто-то должен был додгадаться чего вы хотите? Так же на всякий случай хочу напомнить что выделяя память надо не забыть ее освободить, а то кто знает чего вы там еще упустили пока учили язык.
0
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36
18.12.2011, 04:38  [ТС]
какой-то вы старнный. зачем меня обвинять в незнании фундаментальных вещей, когда я больше, чем неделю назад, получил одобрение, но сам же нашёл это неправильным? другое дело в том, что опыта у меня мало. вы бы отвелили лаконично на ответ, без вяших удивлений. вы ж мега программист, чё так не рацонально-то?
0
 Аватар для alkagolik
1599 / 622 / 113
Регистрация: 15.07.2011
Сообщений: 3,548
18.12.2011, 04:54
Цитата Сообщение от testsova Посмотреть сообщение
но сам же нашёл это неправильным?
уточните что вы нашли неправильным. Вот ваш вопрос
Цитата Сообщение от testsova Посмотреть сообщение
является ли это идиологически корректным (грамотным, красивым)? или хотя бы "потянет" ?
вот мой ответ: да потянет. Откуда я знаю что именно вы хотите делать? Для однократного вызова вполне, для многократных - нет. И ничего там не уничтожается после выхода из функции, а перезаписывается при каждом последующем вызове.

Добавлено через 1 минуту
посмотрите с чего вы вообще стартанули топик и к чему все свелось.
0
-8 / 1 / 0
Регистрация: 18.10.2011
Сообщений: 36
18.12.2011, 13:14  [ТС]
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
 
void
f(int **p)
{
    int a = 45;
    *p = &a;
}
 
int
main()
{
    int *p;
    f(&p);
    return 0;
}
ну ведь вы позволяете форумчанам делать такие вещи, когда всё сводится к мусору? как можно?

flame!..
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
18.12.2011, 13:14

Инициализация vector<char>
Добрый день. Подскажи те, как инициализировать vector&lt;char&gt; символами - буквами алфавита.

Инициализация *char в конструкторе
Хай эврибади! class A { private: int a; int b; char *str; public: A() : a(0), b(0) { str = '\0'; }

Инициализация char в конструкторе
class Abit { public: Abit(); ~Abit(); protected: private: bool medal;

Error C2440: инициализация: невозможно преобразовать "const char [12]" в "char *"
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; void str_len(char* str) { int i = 0; ...

Инициализация массива char в конструкторе
Вопрос такой. Есть класс simple, в классе есть поле char in. Естественно хочу инициализировать это поле в конструкторе. in={0},...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
34
Ответ Создать тему
Новые блоги и статьи
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
GitHub Copilot в JetBrains: модель по умолчанию, Fix и контроль MCP
and_y87 12.10.2026
10 октября 2026 года GitHub обновил Copilot для JetBrains: добавил настройки стартовой модели, исправления из диагностики и управление автозапуском MCP. Поддержка IDE 2025. 1 прекращена — требуется. . .
День 5 из 28: Codex подсказывает следующий запрос
and_y87 12.10.2026
9 октября 2026 года OpenAI запустила бету Composer predictions — подсказок следующего сообщения в текущем диалоге Codex. Это помощь с формулировкой запроса, а не автоматическое продолжение задачи. . . .
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru