Си - передача аргументов по ссылке

Все о программировании под *nix
Anonymous

Си - передача аргументов по ссылке

Сообщение Anonymous »

Си - передача аргументов по ссылке

Код: Выделить всё

#include <stdio.h>
#include <string.h>
void q1(char *a){
	strcat(a, "123");
}
void main(){
	char a[20];
	strcpy(a, "hello");
	printf("%s\n", a);
	q1(a);	//добавляем к строке "123"
	printf("%s\n", a);
}

//gcc 1.c && ./a.out
//hello
//hello123
как того же эффекта добиться (т.е. как должна выглядеть
функция q1), если строка a будет объявлена так:
char *a = "hello";
Пытался написать что-то вроде этого, но не работает:

Код: Выделить всё

#include <glib.h>
#include <stdio.h>
void q1(char *a){	//я так понял ошибка здесь - аргумент надо задать
			//по-другому, но как?
	a = g_strdup_printf("%s123", a);
}
main(){
	char *a = "hello";
	printf("%s\n", a);
	q1(a);
	printf("%s\n", a);
}

//gcc `pkg-config --cflags --libs glib-2.0` 1.c && ./a.out
//hello
//hello /*а надо hello123*/

Аватара пользователя
fa3a
Неотъемлемая часть форума
Сообщения: 619
Зарегистрирован: 25 июл 2003, 17:22
Откуда: Minsk

Сообщение fa3a »

вообще-то и printf("%s123", a) сработает... но обычно используют sprintf() для которого выделяют еще один буфер.. в котором и формируют конечную строку..

для сравки -- man sprinf

gl
Never touch the running program!!!

sAm
Интересующийся
Сообщения: 42
Зарегистрирован: 03 дек 2003, 13:49
Откуда: г.Минск

Сообщение sAm »

char *a="hello";

a = const char* - а его менять низя

sAm

Aleksey Kondratenko
Неотъемлемая часть форума
Сообщения: 250
Зарегистрирован: 12 авг 2003, 03:55
Контактная информация:

Сообщение Aleksey Kondratenko »

Дык сделай так:

Код: Выделить всё

#include <glib.h>
#include <stdio.h>

void q1(char **a)
{
        *a = g_strdup_printf("%s123", *a);
}

main()
{
        char *a = "hello";
        printf("%s\n", a);
        q1(&a);
        printf("%s\n", a);
}
А лучше всего так:

Код: Выделить всё

#include <glib.h>
#include <stdio.h>

char * q1(char *a)
{
        return g_strdup_printf("%s123", a);
}

main()
{
        char *a = "hello";
        printf("%s\n", a);
        a = q1(a);
        printf("%s\n", a);
}

[/code]

sAm
Интересующийся
Сообщения: 42
Зарегистрирован: 03 дек 2003, 13:49
Откуда: г.Минск

Передача аргументов через указатель

Сообщение sAm »

Да! для начала через указатель.

Оставте _а_ в покое, так его объявив, мы навечно даем ему это
значение

Для собственного просвещения, дайте ссылку где можно прочитать
сжато про bin формат под L

sAm

Anonymous

Сообщение Anonymous »

Спасибо, Алексей, это то что надо.

Аватара пользователя
kostaLom
Маньяк
Сообщения: 170
Зарегистрирован: 24 авг 2002, 14:14
Откуда: 9-й Отдел
Контактная информация:

Re: Си - передача аргументов по ссылке

Сообщение kostaLom »

manny21 писал(а): как того же эффекта добиться (т.е. как должна выглядеть
функция q1), если строка a будет объявлена так:
char *a = "hello";
Таким образом ты определили a как _указатель_ на строку "hello" длиной в 5 символов. strcat() не проверяет границ массивов, поэтому возможны ошибки в работе. Правильнее было бы сделать через malloc() и sprintf().[/code]

sAm
Интересующийся
Сообщения: 42
Зарегистрирован: 03 дек 2003, 13:49
Откуда: г.Минск

Сообщение sAm »

Люди объясните плиз
Скомпилил, да работает, но правильно ли так делать

main()
{
char *a = "hello";
>>> где храниться "hello"
>>> сегмент данных (инициализированные переменные)
printf("%s\n", a);
a = q1(a);
>>> переопределили а, ну бог сним
>>> "hello" для нас потерян, или я ошибаюсь
printf("%s\n", a);
}

PS. Для собственного просвещения

sAm

Аватара пользователя
mend0za
Неотъемлемая часть форума
Сообщения: 2332
Зарегистрирован: 30 авг 2002, 12:33
Откуда: Minsk

Сообщение mend0za »

я бы сделал char a[] = "hello"; но почему я так делаю, уже не помню :)
что-то из области бессознательного

Aleksey Kondratenko
Неотъемлемая часть форума
Сообщения: 250
Зарегистрирован: 12 авг 2003, 03:55
Контактная информация:

Сообщение Aleksey Kondratenko »

Да "hello" практически потерян.
а теперь указывает навыделенный malloc()'ом блок

dimm_coder
Интересующийся
Сообщения: 65
Зарегистрирован: 19 авг 2003, 10:56
Откуда: Anwerpen, Belgium / Belarus
Контактная информация:

Сообщение dimm_coder »

mend0za писал(а):я бы сделал char a[] = "hello"; но почему я так делаю, уже не помню :)
что-то из области бессознательного
Ну вообщето, тут смотря чего ждали. В случае char *a = "hello", будет 4 байта (32-ОС)
в стеке, а при char a[] = "hello" отбабахает из стека (если это не глобальное данное) размер под строку и скопирует туда эту строку, которая в обоих случаях все равно будет размещена в некот. секции под инициализированные данные. И если уж потом менять значение a на другую строку, то массив этот в стеке не совсем надо.

Гость

Сообщение Гость »

2 dimm_coder

char *a = "hello" или char [] = "hello"
результат один и тотже - 6 байт длина строки в

2Aleksey Kondratenko
про себя - было уже подумал что С начал забывать. :(

sAm

Гость

Сообщение Гость »

Anonymous писал(а):2 dimm_coder

char *a = "hello" или char [] = "hello"
результат один и тотже - 6 байт длина строки в

sAm
Где будет 6 байт? В секциии инициализированных данных , где будет хранится эта строка - да будет 6 байт. Разговор был *не об этом*.
Повторяю.

1) char *a = "hello" - в стеке 4 байта для указателя на char (*a*) и инициализируется адресом строки "hello" в секции данных.
2) char a[] = "hello" - в стеке будет выделено 6 байт и скопирована строка "hello" из секции данных.

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

Можете проверить gcc с ключом -S и посмотреть сгенерированный код.

dimm_coder
Интересующийся
Сообщения: 65
Зарегистрирован: 19 авг 2003, 10:56
Откуда: Anwerpen, Belgium / Belarus
Контактная информация:

Сообщение dimm_coder »

тут авторегистрация работает по некоторым дням - наверное от фазы луны зависит :roll:

Aleksey Kondratenko
Неотъемлемая часть форума
Сообщения: 250
Зарегистрирован: 12 авг 2003, 03:55
Контактная информация:

Сообщение Aleksey Kondratenko »

Кроме этого, в случае "char *". Получаем указатель в .rodata.
Попытка напр. *a = 0 даст segfault.
В другом случае у нас копия строки, которую можно править.

Ответить