Зачем использовать endl, если я могу использовать символ новой строки?

Есть ли причина использовать endl с cout, когда я могу просто использовать \n? В моей книге по C ++ сказано использовать endl, но я не понимаю, почему. \n не поддерживается так широко, как endl, или я что-то упускаю?


person Moshe    schedule 06.09.2011    source источник
comment
Чтобы было ясно, в большинстве случаев вам не следует использовать endl. См. Также этот ответ + комментарии.   -  person ildjarn    schedule 06.09.2011
comment
помните, что конец строки - это \ r \ n на платформе DOS / Windows и пустой \ r на некоторых (всех?) платформах Mac.   -  person PypeBros    schedule 06.09.2011
comment
@sylvainulg: Это не особенно актуально. Символ '\ n', напечатанный в текстовом потоке, будет автоматически переведен в системное представление конца строки. В этом отношении нет разницы между '\n' и std::endl (разница в flush). (Платформы Mac, начиная с OSX (я думаю), основаны на Unix и используют '\n' для обозначения концов строк.)   -  person Keith Thompson    schedule 06.09.2011
comment
И если вам действительно нужно очищать поток как можно чаще (например, чтобы увидеть выходные данные отладки до сбоя), вы можете просто использовать std::cerr, который также не требует явной очистки.   -  person UncleBens    schedule 06.09.2011
comment
@keith: спасибо за точность. Это было не очень ясно в документации, которая у меня была под рукой, и я сам не знал о разнице смыва.   -  person PypeBros    schedule 07.09.2011
comment
@UncleBens: Да, но std::cerr может легко перейти в другой файл, чем std::cout.   -  person Keith Thompson    schedule 07.09.2011
comment
Эта ссылка также сообщает, когда использовать промывку (\endl), а когда просто \n. programmers.stackexchange.com/questions/185064/   -  person Ruchir    schedule 21.08.2015


Ответы (3)


endl добавляет '\n' в поток и вызывает flush() в потоке. Так

cout << x << endl;

эквивалентно

cout << x << '\n';
cout.flush();

Поток может использовать внутренний буфер, который фактически передается, когда поток очищается. В случае cout вы можете не заметить разницы, поскольку он каким-то образом синхронизирован (связан) с cin, но для произвольного потока, такого как файловый поток, вы заметите разницу в многопоточной программе для пример.

Здесь есть интересное обсуждение того, почему может потребоваться промывка.

person Armen Tsirunyan    schedule 06.09.2011
comment
Кроме того, не преобразован ли endl в соответствующий символ EndLine платформы (\ r \ n в Windows, \ n в Linux)? - person André Puel; 06.09.2011
comment
Стандарт C определяет, что '\n' прозрачно конвертируется в соответствующий символ. Итак, да, поскольку endl прикрепляет '\n', это происходит. Но это не относится к endl. - person Chad La Guardia; 06.09.2011
comment
Или, точнее, можно написать (cout << x << '\n').flush();. То есть теперь все в одном операторе, поскольку cout << x << endl; - это одно выражение. - person Nawaz; 06.09.2011
comment
@Nawaz: Избегайте обфускации и излишков. Espouse разъяснение - person Armen Tsirunyan; 06.09.2011
comment
@Chad: Да, как и стандарт C ++, который мы здесь обсуждаем. - person Keith Thompson; 06.09.2011
comment
@Keith Thompson Тот факт, что '\n' прозрачно преобразован, явно не указан в стандарте C ++; это что-то, что было перенесено из стандарта C. - person Chad La Guardia; 06.09.2011
comment
@Chad: Хм, я этого не знал. Но в этом случае важно отметить, что C ++ наследует это правило от C. (я пытаюсь выяснить, где это сказано в стандарте C ++, но я считаю, что стандарт C ++ труднее читать, чем стандарт C.) - person Keith Thompson; 06.09.2011
comment
@Keith: Был вопрос по поводу SO: что вы можете сделать с C, чего нельзя сделать с C ++. Один из моих любимых ответов гласил: я могу поднять печатную версию аннотированного стандарта C 1000 раз одной рукой. - person Armen Tsirunyan; 06.09.2011

endl - это больше, чем просто псевдоним для символа \n. Когда вы отправляете что-то в cout (или любой другой выходной поток), он не обрабатывает и не выводит данные немедленно. Например:

cout << "Hello, world!";
someFunction();

В приведенном выше примере существует некоторая вероятность того, что вызов функции начнет выполняться до того, как вывод будет сброшен. Используя endl, вы принудительно выполняете сброс перед выполнением второй инструкции. Вы также можете убедиться в этом с помощью функции ostream::flush.

person Paul Manta    schedule 06.09.2011
comment
Вы имеете в виду 'или любой другой буферизованный выходной поток'. - person ildjarn; 06.09.2011

endl - это функция, а не ключевое слово.

#include <iostream>
int main()
{
 std::cout<<"Hello World"<<std::endl;  //endl is a function without parenthesis.
 return 0;
}   

Чтобы понять картину endl, вам сначала нужно разобраться в теме "Указатель на функции".

посмотрите на этот код (на C)

#include <stdio.h>
int add(int, int);
int main()
{
   int (*p)(int, int); /*p is a pointer variable which can store the address    
   of a function whose return type is int and which can take 2 int.*/
   int x;

   p=add;                     //Here add is a function without parenthesis.

   x=p(90, 10); /*if G is a variable and Address of G is assigned to p then     
   *p=10 means 10 is assigned to that which p points to, means G=10                        
   similarly x=p(90, 10); this instruction simply says that p points to add    
   function then arguments of p becomes arguments of add i.e add(90, 10)   
   then add function is called and sum is computed.*/  

   printf("Sum is %d", x);
   return 0;
}
int add(int p, int q)
{
  int r;
  r=p+q;
  return r;
}

Скомпилируйте этот код и посмотрите результат.

Вернуться к теме ...

 #include <iostream>
 //using namespace std; 
 int main()
 {
 std::cout<<"Hello World"<<std::endl;
 return 0;
 }

Файл iostream включен в эту программу, потому что прототип объекта cout присутствует в файле iostream, а std - это пространство имен. Он используется, потому что определение (файлы библиотеки) cout и endl присутствует в пространстве имен std; Или вы также можете использовать вверху «using namespace std», чтобы не писать «std :: coutn ‹< .....» перед каждым cout или endl.

когда вы пишете endl без парантезиса, вы передаете адрес функции endl в cout, затем вызывается функция endl и изменяется строка. Причина этого

namespace endl
{
printf("\n");
}

Вывод: за C ++ работает код C.

person user8175502    schedule 17.06.2017