Categorías
C/C++

Utilice Eclipse CDT para desarrollar aplicaciones C ++ en el entorno de Windows

Eclipse es una buena herramienta para desarrollar programas C ++ en Windows. La configuración del entorno a veces causa problemas a muchos desarrolladores. Estos son los pasos que pueden hacer que funcione en su sistema Windows.

1. actualice eclipse galileo a helios.
2. agregue el complemento CDT
3. instalar MinGW
4. Cree un proyecto de muestra y vea la estructura del proyecto. El sitio web de IBM tiene un buen artículo para un proyecto de muestra.

http://www.ibm.com/developerworks/opensource/library/os-eclipse-stlcdt/

Categorías
C/C++

Un ejemplo simple de palabra clave virtual de C ++

La palabra clave virtual determina si una función miembro de una clase puede anularse en sus clases derivadas. Aquí hay un ejemplo simple para mostrar esto.

#include <iostream>
using namespace std;
 
class Car // Base class for C++ virtual function example
{
public:
	virtual void Create() // virtual function for C++ virtual function example
	{
		cout << "Parent class: Carn";
	}
};
 
class Sedan: public Car {
public:
	void Create() {
		cout << "Derived class: Sedan - Overridden C++ virtual function";
	}
};
 
int main() {
	Car *x, *y;
 
	x = new Car();
	x->Create();
 
	y = new Sedan();
	y->Create();
}

Esto se produce como resultado de:

Clase para padres: Coche
Clase derivada: Sedan – Función virtual de C ++ anulada

Simplemente eliminando la palabra clave «virtual», el resultado sería:

Clase para padres: Coche
Clase para padres: Coche

Las funciones miembro no virtuales se resuelven en el momento de la compilación y se denomina enlace estático. Sin embargo, las funciones de miembros virtuales de c ++ se resuelven durante el tiempo de ejecución y se llaman como enlace dinámico.

Esto es diferente con Java. Aquí es una publicación sobre la comparación de Java y C ++.

Categorías
C/C++ Versus

Un ejemplo de uso de puntos y flechas de C ++

vs.

En general, el punto (.) Es para el objeto en sí, la flecha (->) es para el puntero.

Un buen ejemplo que vale más que mil palabras. El siguiente ejemplo debería ser bueno.

#include <iostream>
 
using namespace std;
 
class Car
{
public:
	int number;
 
	void Create() 
	{
		cout << "Car created, number is:  " << number << "n" ;
	}
};
 
int main() {
	Car x;
	// declares x to be a Car object value,
	// initialized using the default constructor
	// this very different with Java syntax Car x = new Car();
	x.number = 123;
	x.Create();
 
	Car *y; // declare y as a pointer which points to a Car object
	y = &x; // assign x's address to the pointer y
	(*y).Create(); // *y is object
	y->Create(); // same as previous line, y points to x object. It stores a reference(memory address) to x object.
 
	y->number = 456; // this is equal to (*y).number = 456;
	y->Create();
}

Categorías
C/C++

Ejemplo de función constructora de C ++

Aquí hay un ejemplo que muestra cómo usar la función constructora en C ++.

#include <iostream>
 
using namespace std;
 
class Car
{
public:
	int number;
 
	// a construct without parameter
	Car(){
		number = 123; //assign a default value
	}
 
	// a construct with parameter
	Car(int x){
		number = x;
	}
 
	void Create() 
	{
		cout << "Car created, number is:  " << number << "n" ;
	}
};
 
int main() {
	Car x(456); //equals to Car *z = new Car(63746);
	x.Create();
 
	Car y;
	y.Create();
 
 
	Car *z;
	z = new Car(789);
	z->Create();
}

Si no se define ningún constructor, puede usar Car x = {123456};

#include <iostream>
 
using namespace std;
 
class Car
{
public:
	int number;
 
	void Create() 
	{
		cout << "Car created, number is:  " << number << "n" ;
	}
};
 
int main() {
	Car x = {123456};
	x.Create();
 
	Car *y = new Car();
	y->Create();
}

Categorías
C/C++

Programación de procesos de Linux – fork ()

¿Qué es un proceso?

En informática, un proceso es una instancia de un programa informático que se está ejecutando. Contiene el código del programa y su actividad actual. Dependiendo del sistema operativo (SO), un proceso puede estar compuesto por múltiples subprocesos de ejecución que ejecutan instrucciones al mismo tiempo.

¿Qué hace fork ()?

El fork () es un sistema que creará un nuevo proceso hijo. El proceso hijo creado es un proceso idéntico al padre, excepto que tiene una nueva ID de proceso del sistema. El proceso se copia en la memoria de su proceso padre, luego el kernel asigna una nueva estructura de proceso. El valor de retorno de la función es el que discrimina los dos hilos de ejecución. La función fork devuelve un 0 en el proceso del hijo, mientras que el PID del proceso hijo se devuelve en el proceso del padre.

En resumen, fork () crea un proceso hijo que se diferencia del proceso padre solo en su PID y PPID (el PID padre, el creador del proceso), y en el hecho de que las utilizaciones de recursos se establecen en 0. Bloqueos de archivos y pendientes las señales no se heredan. En Linux, fork () se implementa utilizando páginas de copia en escritura, por lo que la única penalización en la que incurre es el tiempo y la memoria necesarios para duplicar las tablas de páginas del padre y para crear una estructura de tareas única para el hijo.

Aquí hay un programa de ejemplo en c que usa la llamada al sistema fork (). Note el comentario.

/* Example of use of fork system call */
#include <stdio.h>
#include <iostream>
#include <string>
// Required by for routine
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
 
main()
{
  int pid;
 
  pid = fork();
 
  if (pid < 0) { // error occurred 
	  fprintf(stderr, "Fork failed!n");
	  exit(-1);
  }else if (pid == 0) { // child process 
	  printf("I am the child, return from fork=%dn", pid);
	  execlp("/bin/ps", "ps", NULL);
  }else { // parent process 
	  printf("I am the parent, return from fork, child pid=%dn", pid);
	  printf("Parent exiting!n");
	  exit(0);
  }
}

Resultado:

programcreek:~/cdtworkspace/CPractice/src> ./a
I am the parent, return from fork, child pid=15053
Parent exiting!
I am the child, return from fork=0
programcreek:~/cdtworkspace/CPractice/src>   PID TTY          TIME CMD
15033 pts/0    00:00:00 tcsh
15053 pts/0    00:00:00 ps

Al principio, el proceso padre se ejecuta, imprime el pid secundario real y sale.
Luego, se ejecuta el proceso hijo, imprime pid 0.

Piense en por qué el proceso padre se ejecuta antes que el proceso hijo.

Categorías
C/C++ linux

Canal de Linux para la comunicación entre el programa Java y C ++

La pipa está ordenada. Una tubería es una forma de conectar la salida de un programa a la entrada de otro programa sin ningún archivo temporal.

Esta sencilla prueba contiene un programa Java y un programa C ++. La salida del programa Java se utiliza como entrada para el comando «wc», y luego la salida es utilizada por un programa C ++.

El programa Java imprime una cadena simplemente.

 public class Main {
    public static void main(String args[]){
        System.out.println("result from Java program.");
    }
}

Compile el programa usando javac Main.java y se generará un archivo de clase.

El programa C ++ simplemente acepta un número entero y luego envía la salida a la consola.

 
#include <iostream>
using namespace std;
int main(void)
{
  int number;
  cin >> number;
 
  cout << "Your number is " << number << "n";
  return 0;
}

Compile el programa usando el comando: g ++ -oa accept.cpp. Cambie su acceso al ejecutable usando el comando: chmod 755 a.

Ahora usa el comando:

~/linuxPractice/java> java Main | wc -l | ./a
Your number is 1

Categorías
C/C++

Estrella doble después del tipo y antes de la variable

¿Qué significa ** en el siguiente código?

char **argv;

Declara argv como un puntero que apunta a un puntero char. Es equivalente al siguiente código.

char *argv[];

He aquí un buen ejemplo.

#include <unistd.h>
#include <iostream>
 
using namespace std;
int test(int argc, char **argv) {
 
        // Start at 1 to skip the program name                                                                                                                                                                                              
        for (int i = 1; i < argc; ++i) {
                for (int j = 0; argv[i][j] != ''; ++j) {                                                                                                                                                                                 
                        cout << *(argv + i) << 'n'; // this and next line are the same                                                                                                                                                                
                        cout << argv[i] << 'n';
                        cout << *(*(argv + i) + j) << 'n';
                }
        }
 
}
 
int main(int argc, char **argv){
 
        //how to pass pointers                                                                                                                                                                                                              
        cout << argc << "parameters"<<endl;
        test(argc, argv);
 
}

Una pregunta interesante es cómo inicializar «str» ​​declarado en «char ** str».
Un diagrama vale mil palabras.

Categorías
C/C++

Instrucción Switch y If en C / C ++

Considere este ejemplo:

void send(int *to, int *from, int count)
{
  int n = (count+7)/8;
  switch(count%8) {
case 0: do{*to++ = *from++;
case 7:    *to++ = *from++;
case 6:    *to++ = *from++;
case 5:    *to++ = *from++;
case 4:    *to++ = *from++;
case 3:    *to++ = *from++;
case 2:    *to++ = *from++;
case 1:    *to++ = *from++;
    } while(--n > 0);
  }
}

¿Qué hace?

Básicamente, todos los ‘casos’ son como la etiqueta en la declaración goto. Aunque la instrucción switch es el alcance adjunto en el sentido léxico, la instrucción do while es el alcance adjunto real de la mayor parte del código. Switch es simplemente un enrutador para proporcionar varias entradas a la declaración do while. La próxima vez, cuando tenga que decidir entre usar switch o if, tenga en cuenta este ejemplo.

Referencia:
1. Dispositivo de Duff

Categorías
C/C++ Top 10

Las 5 preguntas principales sobre punteros C / C ++

Este artículo resume las principales preguntas formuladas sobre los punteros de C / C ++ en stackoverflow.com. Los punteros son la parte más confusa de C / C ++, esas preguntas utilizan ejemplos simples para explicar conceptos clave de punteros.

1. Cuente de 1 a 1000 sin usar bucles

#include <stdio.h>
#include <stdlib.h>
 
void main(int j) {
  printf("%dn", j);
  (&main + (&exit - &main)*(j/1000))(j+1);
}

El único otro método para contar del 1 al 1000 es la recursividad. Según el lenguaje C, j tiene ‘1’ como su valor al principio. Cuando 1 <= j <1000, & main + (& exit - & main) * (j / 1000) siempre se evalúa como & main, que es la dirección de memoria de main. (& main) (j + 1) es la siguiente iteración que queremos obtener, que imprimiría '2' en la pantalla, etc. La condición de parada de esta recursividad es que cuando j llega a 1000, & main + (& exit - & main) * (j / 1000) evalúa a & exit, que saldrá elegantemente de este proceso y tiene el código de error 1001 devuelto al sistema operativo.

2. ¿Por qué un[5] == 5[a]?

a[b] significa * (a + b) según el estándar C. a es la dirección base, b es un desplazamiento a partir de a. a[b] es el valor en la dirección de a + b.

Por tanto, a + 5 y 5 + a es la misma dirección de memoria. Su valor * (a + 5) y * (5 + a) es el mismo. Entonces un[5] == 5[a]

3. ¿Cuántos niveles de punteros podemos tener?

Tanto como un humano pueda manejar. Cualquier compilador de c / c ++ definitivamente admite más que eso.

4. C puntero a matriz / matriz de desambiguación de punteros

¿Cuál es la diferencia entre las siguientes declaraciones?

int* arr1[8];
int (*arr2)[8];
int *(arr3[8]);

Por tabla de precedencia C, matriz [], la función return () tiene mayor prioridad sobre el puntero *.

Para int * arr1[8]
arr1 ante todo es una matriz sin importar el tipo de elemento. Después de aplicar el puntero *, sabemos que arr1 es una matriz de punteros int.

Para int (* arr2)[8]
Por regla de anulación de corchetes, el puntero * tiene mayor prioridad sobre la matriz [] en este caso. Entonces arr2 es ante todo un puntero sin importar a qué esté apuntando. Después de aplicar la matriz [], sabemos que arr2 es un puntero a una matriz de int.

Para int * (arr3[8])
El corchete en este caso no cambia ninguna precedencia predeterminada, por lo que es lo mismo que int * arr1[8]

5. ¿Qué sentido tienen los punteros constantes?

(1) void foo (int * const ptr);
(2) void foo (int * ptr);

Para el llamador de foo, el valor de ptr se copia en foo tanto en (1) como en (2).

(1) y (2) marcan la diferencia solo para el implementador de foo, no para el cliente de foo.

En (2), el implementador puede cambiar accidentalmente el valor de ptr, lo que potencialmente puede introducir errores.

(1) es como el implementador le dice al compilador antes de escribir el cuerpo de foo, «oye, no quiero valorar ptr, si se cambia de alguna manera oscura, haz que la compilación falle, déjame verificar eso»

Categorías
C/C++

Extensión y trampolín de «funciones anidadas» GNU C

Conocimientos previos requeridos: registro de activación, alcance estático y alcance dinámico.

A continuación, no se muestra el código C estándar. (caso 1)

foo (double a, double b){
  double square (double z) { return z * z; }    
  return square (a) + square (b);
}

Sin embargo, GNU C admite esta sintaxis de ‘función anidada’ por extensión. También se le permite tomar la dirección de la función anidada y pasarla a otras funciones como esta: (case2)

hack (int *array, int size){
   void store (int index, int value){ 
        array[index] = value; 
   }
   intermediate (store, size);
}

Observe que la función anidada ‘store’ usa ‘array’ de la función ‘hack’.

Ahora, veamos la implementación de la función anidada en el compilador ac / c ++ (lo llamaré compilador de ahora en adelante, pero tenga en cuenta que me refiero específicamente al compilador c / c ++).

El enlace estático en el registro de activación (AR) se utiliza para acceder a datos de otros AR que tienen relación léxica con él.
El compilador AC / C ++ no necesita un enlace estático en AR para implementar el alcance léxico, ya que todas las funciones están en el alcance global, una función solo tiene acceso al montón (asignado usando malloc), área estática, su propio AR, pero no AR de cualquier otro función.

Por lo tanto, si implementamos una función anidada mediante un enlace estático, definitivamente no es rentable porque paga el precio (un campo por cada AR) cada vez, pero el servicio rara vez se usa (la mayoría de los AR no son para funciones anidadas).

Sin embargo, si pudiéramos usar un enlace estático para implementar la función anidada solo cuando sea necesario, es una situación en la que todos ganan. El método es así:

0. Suponga que se utiliza un registro SL para almacenar un enlace estático temporalmente.
1. En llamador, asigne una pequeña memoria en la pila. Ponga en él código de ensamblaje equivalente al siguiente:

     004    move caller FP to SL
     008    jmp to nested function

2. En callee, cargue SL en el enlace estático y utilícelo para acceder a los datos de la persona que llama.
3. Ahora la dirección 0004 se convierte en la nueva dirección de la función anidada.

El código del paso 2 se llama trampolín. La dirección de la función original junto con el llamador FP se denomina cierre en este caso, lo que le brinda una función para ejecutar y un entorno de datos adicional para acceder. Para obtener más información, puede consultar estas referencias.

Oh, por cierto, el siguiente código es legal en C ++

void foo() {
   void bar(int);
   bar(1);
}

Referencias:
1. Funciones anidadas
2. Simular función anidada en C ++
3. Cómo implementar la extensión anidada por trampolín
4. ¿Qué es el cierre?
5. Alcance estático frente a alcance dinámico
6. Alcance de implementación