LINUX.ORG.RU

[C, K&R примеры] Примеру 1.9, передача аргумента в функцию, откуда возбмется строка


0

0

Поясните пожайлуста «неродивому» по примеру 1.9

из книги Кернигана и Ритчи

Собственно вопрос

откуда возьмется строка в переменной line, которую мы передаем в качестве аргумента при вызове функции _getline(line, MAXLINE) - строка:12,16

мы ее объявили, но мы же ее предварительно несчитывали ниоткуда, из ввода, например getchar'ом или другим способом...

#include <stdio.h>
#define MAXLINE 10		/* максимальная длина строки в потоке */

int _getline(char line[], int maxline);
void copy(char to[], char from[]);

/* вывод самой длинной строки в потоке */
main()
{
	int len;				/* длина текущей строки */
	int max;				/* текущая максимальная длинна */
	char line[MAXLINE];		/* текущая введенная строка */
	char longest[MAXLINE];	/* самая длинная строка из введенных */
	
	max = 0;
	while ((len = _getline(line, MAXLINE)) > 0)
		if (len > max){
			max = len;
			copy(longest, line);
		}
	if (max > 0)	/* была не пустая строка */
		printf("%s", longest);
	
	return 0;
}

/* _getline: считывает строку в s, вовращает ее длину */
int _getline(char s[], int lim)
{
	int c, i;
	
	for (i = 1; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
		s[i] = c;
	if (c== '\n') {
		s[i] = c;
		++i;
	}
	s[i] = '\0';
	
	return i;
}

/* copy: копирует строку 'from' в 'to'; длина to считается достаточной */
void copy(char to[], char from[])
{
	int i;
	
	i = 0;
	while ((to[i] = from[i]) != '\0')
		++i;
}

функцию getline заменил на _getline, потому как такая же есть в /usr/include/stdio.h

>мы ее объявили, но мы же ее предварительно несчитывали ниоткуда, из ввода, например getchar'ом или другим способом...

Объявили и передали пустую. Далее в _getline она наполняется с помощью getchar (под видом s[]).

anonymous ()
Ответ на: комментарий от anonymous

и получается что после вызова функции будет line и s идентичны...
поясните пожайлуста почему так получается?

в прототипе функции line[]
а в определении фукнции s[]



SuperNoob ()
Ответ на: комментарий от SuperNoob

в прототипе функции line[] а в определении фукнции s[]

Компилятору без разницы как вы там назвали свою переменную в прототипе. Он игнорирует ее имя, и смотрит только на тип.

Прототип:

int _getline(char line[], int maxline);
можно записать как:
int _getline(char, int);

edigaryev ★★★★★ ()
Ответ на: комментарий от SuperNoob

>в прототипе функции line[] а в определении фукнции s[]

Вам стоит прочитать про функции вообще и про передачу параметров в них, а также про видимость переменных.

Как бы попроще объяснить, в объявлении функции даётся имя переменной для использования внутри функции, а вне её это имя уже не видно. Собственно, потому и можно не ограничивать себя в именовании переменных внутри функции - они могут совпадать с другими переменными в программе.

В фунции _getline первым параметром будет s[], и внутри неё мы используем имя s для работы с этим параметром. А при вызове функции мы передаём первым параметром line, и он как-бы «становится» s. Вообще там всё похитрее, есть передача по значению и ссылке, указатели и прочее-прочее, но вкратце оно работает именно так.

anonymous ()
Ответ на: комментарий от SuperNoob

>и далее используется внутри нее, локально получается вроде как

В случае с массивами в функцию передаётся не копия массива, а указатель на него, поэтому работа идёт не с локальной переменной, а с той самой line, которая остаётся после завершения функции _getline.

anonymous ()
Ответ на: комментарий от anonymous

Все теперь ясно...
если указатель тогда все проясняется...
СПАСИБО! :)

SuperNoob ()
Ответ на: комментарий от LamerOk

НЕ волнуйтесь читаем...

а вы троллите

а по теме ничего не сказали...

или вы имеете ввиду что если указатель то должно быть явно обозначено символом *

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

char *s
char s[]

только вот в Главе 1 об этом ничего не сказано... поэтому у меня и возник вопрос... в процессе

SuperNoob ()
Ответ на: комментарий от SuperNoob

>только вот в Главе 1 об этом ничего не сказано... поэтому у меня и возник вопрос... в процессе

По правде в главе 1 написано, что массив передаётся по ссылке, а не по значению:)

anonymous ()
Ответ на: комментарий от SuperNoob

> или вы имеете ввиду

Я имею в виду, что у K&R всё очень хорошо разжевано и расписано. Надо просто читать, если не понятно - перечитывать. Только в последнем издании есть опечатки в коде.

LamerOk ★★★★★ ()
Ответ на: комментарий от LamerOk

> Это не QT. Причем тут QuickTime?

Это покемоны.

А они тут причем?

Только они способны разучить людей читать.

Лучше бы они, покемоны, разучили некоторых писать.

anonymous ()
Ответ на: комментарий от anonymous

Да, пардон, вы правы...

прям перед 1.9 в последнем абзаце 1.8.

1.8. Аргументы - вызов по значению
Один аспект в «C» может оказаться непривычным для программистов, которые использовали другие языки, в частности, фортран и PL/1. в языке «C» все аргументы функций передаются «по значению». это означает, что вызванная функция получает значения своих аргументов с помощью временных переменных /фактически через стек/, а не их адреса. Это приводит к некоторым особенностям, отличным от тех, с которыми мы сталкивались в языках типа фортрана и PL/1, использующих «вызов по ссылке », где вызванная процедура работает с адресом аргумента, а не с его значением.
Главное отличие состоит в том, что в «C» вызванная функция не может изменить переменную из вызывающей функции; она может менять только свою собственную временную копию.
Вызов по значению, однако, не помеха, а весьма ценное качество. Оно обычно приводит к более компактным программам, содержащим меньше не относящихся к делу переменных, потому что с аргументами можно обращаться как с удобно инициализированными локальными перемнными вызванной процедуры.

....
....

Когда в качестве аргумента выступает имя массива, то фактическим значением, передаваемым функции, является адрес начала массива. /Здесь нет никакого копирования элементов массива/. С помощью индексации и адреса начала функция может найти и изменить любой элемент массива.

(Это из старой версии, в новой тот же смысл, немного интреперетация другая)

SuperNoob ()
Ответ на: комментарий от anonymous

Может, то, что совсем не это хотел написать?

LamerOk ★★★★★ ()

тупой вопрос. Я бы постыдился бы с таким вопросом появиться тебе 1 с большим минусом

enep ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.