main;
#include <iostream> #include <unistd.h> int main() { for(auto i = 0; i < 1000; i++) std::cout << "Hello world!\n"; fork(); }
#include <iostream> int main() { int array[] = { 1, 2, 3 }; std::cout << (4, (1, 2)[array]) << std::endl; }
#include <regex> #include <iostream> int main() { std::regex re("(.*|.*)*O"); std::string str("0123456789"); std::cout << std::regex_match(str, re); return 0; }
#include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(Foo&&) { std::cout << "Foo(Foo&&)\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } }; int main() { Foo f; auto a = [f = std::move(f)]() { return std::move(f); }; Foo f2(a()); return 0; }
Foo()
Foo(Foo&&)
Foo(const Foo&)
#include <iostream> int x = 0; int bar(int(x)); int main() { std::cout << bar; }
0
1
0x0
#include <iostream> struct Foo { Foo() { std::cout << "Foo()\n"; } Foo(const Foo&) { std::cout << "Foo(const Foo&)\n"; } Foo(int) { std::cout << "Foo(int)\n"; } Foo(int, int) { std::cout << "Foo(int, int)\n"; } Foo(const Foo&, int) { std::cout << "Foo(const Foo&, int)\n"; } Foo(int, const Foo&) { std::cout << "Foo(int, const Foo&)\n"; } }; void f(Foo) {} struct Bar { int i, j; Bar() { f(Foo(i, j)); f(Foo(i)); Foo(i, j); Foo(i); Foo(i, j); } }; int main() { Bar(); }
Foo(int, int)
Foo(const Foo&, int)
Foo(int, const Foo&)
Foo(int)
El programa más pequeño
Este es un código C legal. Se compilará y vinculará correctamente. Se bloqueará si intenta ejecutarlo. main;
- es una variable global.
En el código C se pueden omitir muchas cosas. Por ejemplo, se puede omitir el tipo de una variable global. De forma predeterminada, el compilador asumirá que este tipo es un int
. Además, en C no (a diferencia de C++), por lo que al vincular no hay forma de distinguir la variable main
de la función main
.
De esta forma, el compilador compilará código válido y el enlazador encontrará algo llamado main
en el archivo objeto para enlazar un programa.
El tenedor
Esta es una característica más de POSIX que de C o C++. Las implementaciones de operaciones de E/S utilizan búferes para optimizar el rendimiento. Cuando se invoca fork
, el sistema operativo creará un duplicado de copia en escritura de la memoria del proceso, los búferes de E/S probablemente también se duplicarán y las cadenas almacenadas en búfer probablemente se imprimirán más de 1000 veces .
Todo lo que necesitas son índices
La respuesta es 3
Para entender este código, veamos más de cerca cómo funcionan los índices en C y C++: array[index]
, es lo mismo que *(array + index)
, es lo mismo que (index + array)
y lo mismo que index[array
.
La segunda pista es el operador ,
. Es un operador binario que descarta el argumento izquierdo y devuelve el argumento derecho.
Expresiones regulares
¡Es imposible predecir lo que sucederá! El comportamiento depende de la implementación.
En mi entorno, este programa genera la excepción The complexity of an attempted match against a regular expression exceeded a pre-set level.
Primero, transformar expresiones regulares en autómatas finitos O(n**2)
(n - longitud del patrón), hacer coincidir la cadena O(m)
(m - longitud de la cadena). Este enfoque no admite de las lambdas.
Cuando mueves f
creas const Foo&&
. const Foo&&
es un tipo extraño, por lo tanto, el compilador simplemente copia Foo
auto a = [f = std::move(f)]() mutable { return std::move(f); };
Declarar constructor Foo(const Foo&&)
X y barra
El programa imprimirá 1
.
int bar(int(x));
— es una forma extraña de declarar una función, es igual a int bar(int x);
.
Si lo confundes con la conversión de tipo, int bar((int(x)));
- esto es una conversión de tipo.
Luego intentamos convertir implícitamente la dirección de función a bool
, el resultado de dicha conversión siempre es true
.
La función bar()
nunca se ha utilizado, lo que nos permite evitar errores de símbolo no referenciado durante la vinculación.
Constructores
La última línea es Foo(const Foo&, int)
.
Foo(i)
es una declaración de variable, lo mismo que Foo i
. Por lo tanto, el miembro de clase con el nombre i
está oculto en este ámbito.