2009-08-31 17 views
26

Soy un novato en programación aunque he estado enseñándome Python durante aproximadamente un año y estudié C# hace algún tiempo.¿Por qué la sintaxis de C++ es tan complicada?

Este mes comencé cursos de programación C++ en mi universidad y solo tengo que preguntar; "¿Por qué el código C++ es tan complicado?"

Escribiendo "Hello world." en Python es tan simple como pero en C++ es "imprimir 'Hola mundo'.":

# include <iostream> 
using namespace std; 

int main() 
{ 
    cout << "Hello world."; 
    return 0; 
} 

Sé que es probable que haya una buena razón para todo esto, pero, ¿por qué ...

  • ... ¿tiene que incluir <iostream> cada vez? ¿Alguna vez no lo necesita?
  • ... la misma pregunta para la biblioteca estándar, ¿cuándo no necesita std :: *?
  • ... ¿la función "principal" es una función? ¿Alguna vez llamas a la función principal? ¿Por qué es un número entero? ¿Por qué C++ necesita tener una función principal pero Python no?
  • ... ¿necesita "std :: cout < <"? ¿No es innecesariamente largo y complicado en comparación con Python?
  • ... ¿necesita devolver 0 incluso cuando nunca va a usarlo?

Esto es probablemente porque estoy aprendiendo C++ básico, pero cada programa que he hecho hasta ahora se parece a esto, así que tengo que volver a escribir el mismo código una y otra vez. ¿No es eso redundante? se le fue el compilador acaba de introducir el código en sí, ya que es siempre el mismo (es decir, que yo sepa que siempre incluyen <iostream>, std, int principal, devuelve 0)

+19

Respuesta simple: C++ y Python están diseñados para resolver diferentes problemas con diferentes restricciones. Diferentes objetivos de diseño le dan diferentes diseños. –

+3

No estoy seguro de qué significa la etiqueta 'código redundante' en este contexto. La tarea de main() en la mayoría de los usos no triviales no es solo dar salida a la consola. Es el punto de entrada para la ejecución del programa. El retorno 0; es para los O.S. que inicia el programa y que * puede * usar el valor de retorno como estado informado desde la ejecución del programa. Es posible que desee leer primero las preguntas frecuentes del Dr. Stroustrup antes de posiblemente incriminar a C++ de muchas otras cosas además de la sintaxis @ http://www.research.att.com/~bs/bs_faq.html. – Abhay

+0

En serio, C++ puede ser la pata de la abeja, pero creo que es un código realmente complicado y tedioso. –

Respuesta

71

C++ es un lenguaje de bajo nivel que se ejecuta sin el contexto de un intérprete. Como tal, tiene muchas opciones de diseño diferentes a las de Python, porque C++ no tiene un entorno en el que pueda confiar para administrar información como tipos y memoria. C++ se puede usar para escribir un kernel de sistema operativo donde no hay código ejecutándose en la máquina, excepto para el programa en sí, lo que significa que el lenguaje (algunas instalaciones de biblioteca no están disponibles para las llamadas implementaciones independientes) debe ser autónomo. Es por eso que C++ no tiene equivalente a Python eval, ni un medio de determinar miembros, etc. de una clase, ni otras características que requieren un entorno de ejecución (o una sobrecarga masiva en el programa en vez de tal entorno)

para sus preguntas individuales:

  • qué tiene que incluir el cada vez de <iostream>? ¿Alguna vez no lo necesitas?

#include <iostream> es la directiva que importa el encabezado <iostream> en su programa. <iostream> contiene los objetos de entrada/salida estándar, en particular, cout. Si no está utilizando objetos de E/S estándar (por ejemplo, sólo utiliza File I/O, o el programa utiliza una biblioteca de interfaz gráfica de usuario, o está escribiendo un núcleo del sistema operativo), no es necesario <iostream>

  • misma pregunta para la biblioteca estándar, ¿cuándo no necesita std :: *?

std es el espacio de nombres que contiene toda la biblioteca estándar. using namespace std; es algo así como from std import *, mientras que una directiva #include es (en este sentido) más como una declaración barebones import std.(en realidad, el mecanismo es bastante diferente, porque C++ no usa using namespace std; para buscar objetos automáticamente en std; using-directive solo importa los nombres en el espacio de nombres global.)

Voy a señalar aquí que el uso directivas (using namespace) son con frecuencia mal vistas en el código C++, ya que importan muchos nombres y pueden causar conflictos de nombres. using-declarations (using std::cout;) son preferibles cuando es posible, ya que limita el alcance de una directiva using (por ejemplo, a una función o a un archivo fuente). Nunca coloque using namespace en un encabezado sin una buena razón.

  • es la parte "principal" una función? ¿Alguna vez llamas a la función principal? ¿Por qué es un número entero? ¿Por qué C++ necesita tener una función principal pero Python no?

main es el punto de entrada al programa, donde se inicia la ejecución. En Python, el módulo __main__ tiene el mismo propósito. C++ no ejecuta código fuera de una función definida como lo hace Python, por lo que su punto de entrada es una función en lugar de un módulo.

  • hacer lo necesario "std :: cout < <"? ¿No es innecesariamente largo y complicado en comparación con Python?

std::cout sólo es necesario si usted no importa el nombre cout en el espacio de nombres global, ya sea por una directiva utilizando (using namespace std;) o por una declaración usando-(using std::cout). En este sentido, una vez más es muy similar a la distinción entre Python import std y from std import * o from std import cout.

El << es un operador sobrecargado para objetos de transmisión estándar. cout << value llama a la función cout a la salida value. Python no necesita dicho código adicional porque print está integrado en el idioma; esto no tiene sentido para C++, donde ni siquiera puede haber un sistema operativo, y mucho menos una biblioteca de E/S.

  • ¿Necesitas devolver 0 incluso cuando nunca vas a usarlo?

No. main (y ninguna otra función) tiene un implícito return 0; al final. El valor de retorno de main (o, si se llama a la función exit, el valor que se le transfiere) se devuelve al sistema operativo como el código de salida. 0 indica que el programa se ejecutó con éxito, que no encontró errores, etc. Si se encuentra un error, se debe devolver un valor distinto de cero (o pasarlo a exit).

+4

¡Guau! ¡Muchas gracias por la excelente y detallada respuesta! –

+1

No hay problema :) En realidad, estoy aprendiendo Python, por lo que fue una buena prueba de mi conocimiento el poder explicar el camino de regreso. – coppro

+1

Quizás estoy haciendo esto de la manera incorrecta. ¿Crees que sería una buena idea continuar con C++ durante un par de meses hasta que tenga una base sólida y luego intente estudiar idiomas de bajo nivel como ensamblar? ¿Los lenguajes de alto nivel como Python deberían ser los últimos idiomas que aprenda? –

0

Python es alto nivel idioma. C++ es de nivel medio idioma.

+1

No, no siempre necesitas iostream. Muchas aplicaciones gráficas/de ventana no se preocupan por la salida de la consola. – andy

5

Esto me recuerda a The Evolution of a Programmer. Algunos de los idiomas y tecnologías demostrados son un poco anticuados ahora, pero debes tener una idea general. :)

6

Usted incluye <iostream> cuando desea enviar cosas a la consola. Dado que imprimir "Hola mundo" implica salida de consola, necesita iostream.

La función main es llamada por el sistema operativo, básicamente. Se llama con los argumentos de línea de comandos pasados ​​al programa. Devuelve un número entero porque el programa debe devolver un código de error al sistema operativo (esta es la forma estándar para determinar si el último comando fue exitoso).

Siempre puede usar printf("hello world"); en lugar de std::cout << "hello world"; si desea ir al estilo C. Es un poco más rápido de escribir y te permite hacer una salida formateada.

Usted return 0 de main para indicar que el programa se ejecutó correctamente.

El compilador no incluye automáticamente todas las bibliotecas estándar y utiliza el espacio de nombres std porque a veces pueden producirse colisiones de nombres entre su código y el código de biblioteca que en realidad no necesita. No siempre necesitas todas las bibliotecas.Del mismo modo, a veces está utilizando una rutina principal diferente (el desarrollo de Windows viene a la mente con su propia función de inicio diferente WinMain). El compilador tampoco se activa automáticamente al return 0 porque a veces el programa necesita indicar que se completó sin éxito.

+0

Por lo que vale, en C simple un programa puede llamar a la función 'main()' así como también al sistema operativo, aunque esto está prohibido en C++. El único propósito real de esto sería generar el error favorito de todos. –

+0

Y realmente, un trozo puesto por el compilador llama a la función 'main()', pero esencialmente, es el sistema operativo el que inicia la ejecución, y tiene que comenzar en alguna parte, de alguna manera. – jgottula

+0

Esta es una gran respuesta, solo sabía que no sería capaz de seguir el ritmo de C++ si inconscientemente pienso que lo que estoy haciendo no tiene sentido. A juzgar por las respuestas, parece que _no_ utilizando std y iostream es la EXCEPCIÓN. ¿Por qué no hacer una manera de indicar que el usuario no está usando std o iostream, opuesto a indicar que el usuario los está usando? Y sé que Python es un lenguaje de alto nivel como señaló Aziz (aunque no estoy muy seguro de la diferencia), pero ¿cómo puede Python lograr una sintaxis tan simple y hermosa que haga lo mismo que esa complicado C++ uno? –

6

Hay buenas razones para todas estas cosas. C++ es un lenguaje muy amplio que se usa para todo, desde pequeños sistemas integrados hasta aplicaciones gigantes creadas por cientos de programadores. El caso de uso de un chico que construye un pequeño programa para ejecutar en un escritorio no es el único. Entonces, algunas veces estás construyendo componentes de biblioteca. En ese caso, no main(). Algunas veces estás trabajando en un pequeño sistema sin una biblioteca estándar. En ese caso, no estándar A veces querrás construir una herramienta Unix que funcione con otras herramientas de texto de Unix y señalizar su estado de finalización con una int devuelta desde main().

En otras palabras, las cosas de las que se queja son un prototipo para usted. Pero son detalles vitales que varían para otros usuarios del idioma.

8

En respuesta a sus preguntas al final del post, que se puede resumir con la filosofía de C++:

Usted no paga por lo que no se utiliza.

No siempre es necesario utilizar stdin o stdout (aplicaciones de Windows/GUI?), Ni siempre usará el STL, ni todo lo que escriba necesariamente utilizará el estándar principal (winAPI), etc. Como un anterior el cartel dijo, C++ es un nivel más bajo que Python. Estará expuesto a más detalles, que le ofrece más control sobre lo que está haciendo.

2

Como han dicho las personas, la respuesta simple es que son idiomas diferentes, con diferentes objetivos. Para responder a sus preguntas específicas ...

... ¿tiene que incluir el <iostream> cada vez? ¿Alguna vez no lo necesitas?

<iostream> es uno de los archivos de cabecera para iostreams, la parte de la biblioteca estándar de C++ responsable de la entrada/salida; en este caso, lo necesita para obtener acceso al std::cout. Si no está haciendo operaciones de E/S en un archivo fuente, no necesita incluirlo; por ejemplo, la mayoría de los archivos que contienen definiciones de clases probablemente no necesiten <iostream>.

... la misma pregunta para la biblioteca estándar, ¿cuándo no necesita std :: *?

std es el nombre del espacio de nombres que contiene clases en la biblioteca estándar; está ahí para evitar colisiones de nombres. Python tiene paquetes y módulos para hacer esto.

Usted puede utilizar la instrucción using para llevar artículos de otro espacio de nombres en su ámbito actual, ver this FAQ entry para un ejemplo (y una explicación de por qué es mala para llevar ciegamente en todos std alcance!).

... ¿por qué es la parte "principal" una función? ¿Alguna vez llamas a la función principal? ¿Por qué es un número entero? ¿Por qué C++ necesita tener una función principal pero Python no?

declaraciones ejecutables en C++ tienen que estar contenidos dentro de una función, y la función de main se define como donde comienza la ejecución.En Python, las sentencias ejecutables se pueden colocar en el nivel superior de un archivo y la ejecución se define como.

Si lo desea, puede llamar al main(); es solo una función, después de todo, pero no suele haber una razón para hacerlo. Detrás de escena, la mayoría de las implementaciones de C++ llaman al main() una vez que la biblioteca de tiempo de ejecución ha realizado algunas tareas de mantenimiento.

El valor de retorno de main() se devuelve al sistema operativo. Esto se deriva de C y UNIX, en el que los programas de aplicación deben proporcionar un código de estado de salida de 1 byte, y devolver ese valor desde main() es una forma clara de expresar esto.

... ¿por qué es necesario "std :: cout < <"? ¿No es innecesariamente largo y complicado en comparación con Python?

Esto es solo una diferencia de diseño. iostreams es una bestia bastante compleja con muchas características, y uno de los efectos secundarios de esto es que la sintaxis es un poco fea para tareas simples a veces.

... ¿Por qué necesita devolver 0 incluso cuando nunca va a utilizarlo?

Lo usa; este es el valor devuelto al sistema operativo como el estado de salida del programa.

7

... ¿tiene que incluir el cada vez? ¿Alguna vez no lo necesita ?

No lo necesita si no va a utilizar iostreams en ese módulo. En programas más grandes, pocos módulos hacen directamente un IO directamente, y tan pocos necesitan realmente usar iostreams.

Dando la vuelta a la pregunta: en python necesitas importar sys y/o os en la mayoría de los programas no triviales. ¿Por qué?

... la misma pregunta para la biblioteca estándar , cuando no necesita std :: *?

Puede tener la línea que usa o puede usar el prefijo std ::. Esto es muy similar a la elección que le da python de decir "desde sys import *" o "import sys" y luego tener que prefijar cosas con "sys". En python tienes que decir "sys.stdout". ¿Es "std :: cout" realmente peor?

... ¿la función "principal" es una función? ¿ alguna vez llama a la función principal? ¿Por qué es un número entero? ¿Por qué necesita C++ tener una función principal pero Python no?

Sí, principal es una función. Por lo general, no llamarías a main. El nombre "principal" está reservado para el punto de entrada de su programa. Devuelve un número entero porque el valor devuelto se utiliza como el código de estado de su programa. En Python puede usar sys.exit si desea devolver un código de estado que no sea cero.

Python no tiene la misma convención porque con Python puede tener código en un módulo que no está en una función. Este código se ejecuta cuando carga el módulo. Curiosamente, muchas personas sienten que es un mal estilo a tener el código en el nivel superior de un módulo y en su lugar crear una función principal al hacer algo como esto:

def main(argv): 
    # program goes here 

    return 0 

if __name__ == '__main__': 
    sys.exit(main(sys.argv)) 

Además, en Python le dice al intérprete con el módulo es el módulo "principal" cuando lo ejecutas. por ejemplo: "python foo.py". En C, el módulo "principal" es (efectivamente) el que tiene una función llamada main. (Si hay varios módulos con una función principal, que es un error de vinculador.)

... ¿Necesita "std :: cout < <"? ¿No es innecesariamente largo y complicado en comparación con Python?

El equivalente en Python es en realidad "sys.stdout.write (...)". La declaración impresa de Python es un caso especial abreviado.

Dicho esto, muchas personas sienten que la convención iostreams de usar operadores de cambio de bit para IO era una mala idea. Irónicamente, Python parece haber sido "inspirado" por esta sintaxis. Si desea utilizar la impresión escribir en algún lugar que no sea la salida estándar que se puede decir:

print >>file, "Hello" 

... Qué se necesita para devolver 0, incluso cuando que nunca va a usar?

No lo va a usar, pero su programa lo hará. Como se mencionó anteriormente, el valor que devuelve es el código de estado de su programa.

Aparte: Realmente siento que C++ es demasiado complicado, pero no por ninguno de los puntos que mencionas. Todas las diferencias que mencionas desaparecen (en el sentido de que necesitas tanta complejidad en Python) una vez que comienzas a escribir programas no triviales que tienen múltiples módulos y hacen más que solo escribir en stdout.

3

Baldur:

No siempre se necesita <iostream>. Las únicas cosas que siempre se necesitan son:

  1. Un main función (o un WinMain, si usted está escribiendo aplicaciones Win32).
  2. Variables, funciones, operadores, construcciones de lenguaje (if, while, etc.).
  3. La capacidad de incluir la funcionalidad de las bibliotecas en su programa.

Todo lo demás es específico de la aplicación.

Como dicen otros carteles, el valor de retorno de la función main es un código de error . Si main devuelve 0, sea feliz: ¡todo funcionó bien!

Esto es útil cuando escribe programas que "se comunican" con otros programas. La forma más sencilla en que un programa puede "decir" a otro si se ejecutó correctamente es utilizando un código de error.

5

Uno de los motivos por los cuales C++ es bastante complicado es porque fue diseñado para abordar problemas que surgen en programas grandes. En el momento en C++ se creó como AT & T, su mayor programa de C fue de aproximadamente 10 millones de líneas de código. En esa escala, C no funciona muy bien. C++ resuelve muchos de los problemas que obtienes con ese tipo de programa.

Dicho esto, también es posible responder a la pregunta original:

  • Usted habría include <iostream> donde más se necesita. Si tiene 10.000 archivos C++, es bastante común que menos de 1000, a veces menos de 100, produzcan resultados visibles para el usuario.
  • Una afirmación como print "Hello, world" asume que hay una salida predeterminada, pero hace que sea difícil generalizar. El formulario cout << "Hello, world" lo hace explícito donde va la salida, pero la misma forma también permite cerr << "Goodbye, world" y MyTmpFile << "Starting phase #" << i
  • La biblioteca estándar está en el espacio de nombres std::. Mis 10.000 archivos estarán en 25 espacios de nombres adicionales.
  • main es una rareza en muchos sentidos, siendo la función de inicio.