Autor Tema: Que otro lenguaje (fuera de C++) permite mas de una condición de control (FOR)?  (Leído 2658 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
En un blog se comenta lo siguiente:

una condición de bucle for puede ser más compleja en C++, y se pueden hacer post-decrementos o post-incrementos más avanzados.

....


Nunca hasta este fin de semana había requerido esta poderosa característica de C++, hasta que inicie a programar con la biblioteca de procesamiento de imágenes OPENCV para C++, (ver ejemplo final abajo), sin esta característica el código seria mucho mas largo y por no decir mas complejo, pues se requiere codificar mas ciclos for para obtener lo mismo, o también definir variables extras dentro del ciclo y agregar condicionales para emular el ciclo for "avanzado", no se que otro lenguaje de programación permita esta característica de un ciclo for "avanzado"?


Un for que manipule por lo menos 2 variables de control, en un caso especifico optimiza el la exploración y operación de datos dentro un arreglo( vector o matriz) explorar no solo en un solo sentido sino por ejemplo de izquierda a derecha /o viceversa etc, pienso que esta es una FORMA DE PROCESAMEINTO PARALELO DE DATOS


/////////////////////

ejemplo didactico:

Ejemplo 7 (http://ideone.com/TFbp4):
#include <iostream>
using namespace std;
 
int main()
{
    for(int disminuye=10,aumenta=9 ; ((disminuye>2) && (aumenta<20)) ; disminuye-=2, aumenta+=3)
        cout<<'('<<disminuye<<';'<<aumenta<<") ";
}
// Salida:
// (10;9) (8;12) (6;15) (4;18)
En este caso declaramos e inicializamos dos variables enteras: disminuye (empezó valiendo 10) y aumenta (empezó valiendo 9). La condición para que entrara al bucle era que disminuye fuera mayor a 2 y aumenta menor a 20. Ambas condiciones se tenían que dar para que siguiera repitiéndose (o entrara por primera vez siquiera).

Luego de cada repetición, la variable disminuye disminuía en 2, pues "disminuye-=2" es equivalente a "disminuye=disminuye-2", que también se podría haber escrito así. Y la variable aumenta se incrementaba de a tres por razones análogas.

Como se observa en la salida, disminuye empezó valiendo 10 y aumenta 9. Luego disminuye se decrementó en dos y pasó a valer 8, al mismo tiempo que aumenta se incrementó en 3 y pasó a valer 12. Y así hasta que disminuye pasó a valer 4 y aumenta pasó a valer 18. Luego de eso, las variables, al terminar el bucle, quedaron valiendo (2;21). En ese caso, disminuye ya no era mayor que dos, como pedía la condición (era igual). Y aumenta tampoco era menor que 20, sino mayor (21). Entonces no volvió a entrar al bucle.


Ejemplo 8 (http://ideone.com/ez9SL):

#include <iostream>
using namespace std;
 
int main()
{
 
    for(int disminuye=10,aumenta=9 ; ((disminuye>2) && (aumenta<20)) ; disminuye-=2, aumenta+=3)
    {
        cout<<"disminuye = "<<disminuye;
        cout<<"; aumenta = "<<aumenta<<endl;
    }
}
// Salida:
// disminuye = 10; aumenta = 9
// disminuye = 8; aumenta = 12
// disminuye = 6; aumenta = 15
// disminuye = 4; aumenta = 18


////////////////////


// ejemplo practico utilizando ciclo for con multiples variables de control

//////////////


Código: C++
  1. #include <opencv\cv.h>
  2. #include <opencv\highgui.h> // x/i/cols/n
  3. #include <cstdlib> // y/j/rows/m
  4. #include <iostream>
  5.  
  6. using namespace cv;
  7. using namespace std;
  8.  
  9. #define TRUE 1
  10. #define FALSE 0
  11. #define YES 1
  12. #define NO 0
  13. #define ON YES
  14. #define OFF NO
  15.  
  16. #define RED_COLOR_POS 1
  17. #define GREEN_COLOR_POS 2
  18. #define BLUE_COLOR_POS 3
  19.  
  20. #define BLACK_COLOR 0
  21. #define WHITE_COLOR 255
  22.  
  23. int main(){
  24.  
  25.         Mat imagenOri, imagenUmbral;
  26.  
  27.         imagenOri = imread("D:\\a vision artificial\\images\\rombo0.jpg");
  28.  
  29.         int imageOriRows = imagenOri.rows; // Extrae el valor del numero de filas
  30.         int imageOriCols = imagenOri.cols; // Extrae el valor del numero de columnas
  31.  
  32.         int imageOriRows0 = imageOriRows-1; // En base 0
  33.         int imageOriCols0 = imageOriCols-1; // En base 0
  34.  
  35.         const unsigned int rows = 14; //imageOriRows; // ojo
  36.  
  37.         int arrayInfo[rows][3];  //Row0...14 (0:rowY, 1:leftX, 2:rightX, 3:xValue) // for arrayInfo[13][3]
  38.        
  39.         int arrayMaxCoo[2][4];   //Row0 (0:rowY, 1:leftBlkPxlPos, 2:rightBlkPxlPos, 3:xValue) // for arrayMaxCoo[2][4]
  40.         //                         Row1  (0:colX, 1:upBlkPxlPos, 2:downBlkPxlPos, 3:xValue)
  41.  
  42.     //#define ASIZE dimArrayCoo
  43.  
  44.  
  45.         printf("Tama\xA4o del Arreglo de la imagen (Filas #%d, Columnas #%d)\n\n", imageOriRows, imageOriCols);
  46.  
  47.         // 1: Crea un espacio de memoria o imagenOri sin datos, pero con el alto, ancho especificado y resolucion en amplitud de 8 bits (256 valores) 1 canal(8 bits por pixel)
  48.         imagenUmbral.create(imageOriRows, imageOriCols, CV_8UC1); // Define imagenSalida vacia de 1 CANAL de tamaño (rxc).
  49.         //imagenUmbral = imagenOri;
  50.         cvtColor(imagenOri, imagenUmbral, CV_RGB2GRAY); // Crea una imagen en escala de grises en imagenUMbral
  51.         threshold(imagenUmbral, imagenUmbral, 128, 255, CV_THRESH_BINARY);
  52.  
  53.         namedWindow("Entrada", 1); // Genera una ventana llamada 'entrada'
  54.         namedWindow("Salida1", 1); // Genera una ventana llamada 'salida1' /!\ sin espacios el nombre
  55.  
  56.         //imshow("Entrada", imagenOri);
  57.         //imshow("Salida1", imagenUmbral);
  58.         imwrite("imagenUmbral.jpg", imagenUmbral);
  59.         waitKey(1000);
  60.     int MaxValX = 0;
  61.  
  62.         /////////// FILAS ///////////
  63.         for (int rowJ = 0; rowJ<=imageOriRows0; rowJ++){// recorrer filas j -->
  64.                 //uchar *pOriRowJ = imagenOri.ptr<uchar>(rowJ); // puntero secuencial por filas hacia la imagen original
  65.                 uchar *pResRowJ = imagenUmbral.ptr<uchar>(rowJ); // puntero secuencial por filas hacia la imagen resultado
  66.                
  67.                 int xTotalValue = 0;
  68.                 int leftBlkPxlFlag = 0;
  69.                 int rightBlkPxlFlag = 0;
  70.                 int leftBlkPxlPos = 0;
  71.                 int rightBlkPxlPos = 0;
  72.                
  73.                 /////////// COLUMNAS ///////////
  74.                 for (int colI = 0, colRightI = imageOriCols0; colI< (imageOriCols / 2)+1; colI++, colRightI--){ // recorrer cols i |
  75.  
  76.                         // [ col0:pixel0(BGR), col1:pixel1(BGR), ... colI:pixelI(BGR) ]
  77.                         // [ px0:{0,1,2}, px1:{3,4,5}, px2{6,7,8}, px3{9,10,11}, px4{12,13,14},  ....
  78.                         //   3*0  =0,     3*1  =3,     3*2  =6 <= 3*colI   // Extrae el color BLUE
  79.                         //   3*0+1=1,     3*1+1=4,     3*2+1=7 <= 3*colI+1 // Extrae el color GREEN
  80.                         //   3*0+2=2,     3*1+2=5,     3*2+2=8 <= 3*colI+2 // Extrae el color RED
  81.  
  82.          [ row0-col0:pixel0(BGR), row0-col1:pixel1(BGR), row0-col2:pixelI(BGR)][ row1-col0:pixel0(BGR), row1-col1:pixel1(BGR), row2-col2:pixelI(BGR) ]
  83.  
  84.                         /*
  85.                         int skipCol = 3 * colI;
  86.                         int posRed = skipCol + 2;
  87.                         int posGreen = skipCol + 1;
  88.                         int posBlue = skipCol + 0;
  89.                         */
  90.  
  91.         [ row0-col0:pixel0, row0-col1:pixel1, row0-col2:pixelI,  row1-col0:pixel0, row1-col1:pixel1, row2-col2:pixelI; ] // 2 bits
  92.  
  93.  
  94.  
  95.                         printf("\nLeftCoo(Fila #%d, Columna #%d)=%d\n", rowJ, colI, pResRowJ[colI]);
  96.                         //printf("pixel valor 3 canales= %d,%d,%d \n\n", pResRowJ[posBlue], pResRowJ[posGreen], pResRowJ[posRed]);
  97.                         printf("RightCoo(Fila #%d, Columna #%d)=%d\n", rowJ, colRightI, pResRowJ[colRightI]);
  98.                         system("PAUSE");
  99.  
  100.                         // Row0...14 (0:rowY, 1:leftX, 2:rightX, 3:xValue) // for arrayInfo[0...14][3]
  101.  
  102.                         arrayInfo[rowJ][0] = rowJ;
  103.                         /////////// COLUMNAS LADO IZQUIERDO ///////////
  104.                         if (leftBlkPxlFlag == OFF){ // No se a encontrado el primer pixel negro de izq a derecha                               
  105.                                 if (pResRowJ[colI] == BLACK_COLOR){
  106.                                         leftBlkPxlFlag = ON;
  107.                                         printf("Hay un pixel negro del lado izquierdo en (Fila #%d, Columna #%d) \n\n", rowJ, colI);
  108.                                         system("PAUSE");
  109.                                         leftBlkPxlPos = colI;
  110.                                         arrayInfo[rowJ][1]=colI;
  111.                                 }
  112.                         }
  113.  
  114.                         /////////// COLUMNAS LADO DERECHO ///////////
  115.                         if (rightBlkPxlFlag == OFF){ // No se a encontrado el primer pixel negro de izq a derecha                              
  116.                                 if (pResRowJ[colRightI] == BLACK_COLOR){
  117.                                         rightBlkPxlFlag = ON;
  118.                                         printf("Hay un pixel negro del lado derecho en (Fila #%d, Columna #%d) \n\n", rowJ, colRightI);
  119.                                         system("PAUSE");
  120.                                         rightBlkPxlPos = colRightI;
  121.                                         arrayInfo[rowJ][2] = colRightI;
  122.                                 }
  123.                         }
  124.  
  125.                         if (rightBlkPxlFlag && leftBlkPxlFlag == ON){
  126.                                 printf("Se activaron los flags\n\n");
  127.                                 break;
  128.                         }
  129.  
  130.                 }//End for cols
  131.  
  132.                 if (rightBlkPxlFlag || leftBlkPxlFlag == ON){ // Se activo algun flag
  133.                         xTotalValue = (rightBlkPxlPos - leftBlkPxlPos) + 1;// mas uno por que se incia a contar desde 0
  134.                         arrayInfo[rowJ][3] = xTotalValue;
  135.                         printf("Valor en x = (xf:%d - xi:%d =%d)+1, para la Fila #%d\n", rightBlkPxlPos, leftBlkPxlPos, xTotalValue, rowJ);
  136.                         if (MaxValX < xTotalValue){
  137.                                 MaxValX = xTotalValue;
  138.                                 //Row0 (0:rowY, 1:leftBlkPxlPos, 2:rightBlkPxlPos, 3:xValue) // for arrayMaxCoo[2][4]
  139.                                 //Row1 (0:colX, 1:upBlkPxlPos, 2:downBlkPxlPos, 3:xValue)
  140.                                 arrayMaxCoo[0][0] = rowJ;
  141.                                 arrayMaxCoo[0][1] = leftBlkPxlPos;
  142.                                 arrayMaxCoo[0][2] = rightBlkPxlPos;
  143.                                 arrayMaxCoo[0][3] = xTotalValue;
  144.                         }
  145.                         printf("\nValor maximo acumulado en x =%d,  \n\n", MaxValX);
  146.                 }
  147.                 else{
  148.                         arrayInfo[rowJ][3] = xTotalValue; // debe ser cero
  149.                 }
  150.  
  151.         }//End for rows
  152.  
  153.         printf("\nValor maximo x = %d\n",  arrayMaxCoo[0][3]);
  154.         printf("entre coo (y:%d xi:%d)\n", arrayMaxCoo[0][0], arrayMaxCoo[0][1]);
  155.         printf("y coo (y:%d xf:%d)\n",     arrayMaxCoo[0][0], arrayMaxCoo[0][2]);
  156.  
  157. ////////////////
Desde Colombia

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Prácticamente todos los lenguajes en los que existe el for, permiten sentencias de ese tipo. No es algo exclusivo del C++. Si miras verás que C, Java, Javascript y muchos otros permiten for avanzados como el que mencionaste. La posibilidad de hacer bucles de este tipo siempre estuvo, lo que pasa es que muchos lo desconocen.
Aunque por ejemplo en gcc, para poder declarar variables dentro de un bucle, hace falta especificar que se quiere utilizar el standard C99.


"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado CompSystems

  • PIC18
  • ****
  • Mensajes: 488
    • Home Page
me falto aclarar lenguajes no herederos del C (ni java, ni c++, ...) , entonces fuera de los anteriores que otro lenguaje soporta la característica mencionada arriba?
« Última modificación: 09 de Abril de 2014, 09:58:42 por CompSystems »
Desde Colombia

Desconectado fabianjsm

  • PIC18
  • ****
  • Mensajes: 255
    • fabianjsm is on twitter
Puede que la aparente complejidad resulte de que la sintaxis de C/C++ admite una expresión compuesta (lista de expresiones simples separadas por coma) donde se espera una expresión simple, pero esto dista de ser un procesamiento paralelo, ya que el procesamiento sigue siendo secuencial.

Como dice BrunoF, la posibilidad de hacer bucles de ese tipo siempre estuvo. El ciclo DO de Fortran de los 60 por ejemplo es muy semejante al FOR de C o BASIC, e incluso al WHILE. Es más, sin ir muy lejos, en C/C++ siempre puedes hacer con WHILE lo que haces con un FOR:

Código: C
  1. int disminuye=10,aumenta=9;
  2. while ((disminuye>2) && (aumenta<20)) {
  3.         cout<<'('<<disminuye<<';'<<aumenta<<") ";
  4.         disminuye-=2, aumenta+=3;
  5. }

Parece que la sintaxis de C/C++ siempre nos da una manito cuando queremos escribir complicado un código que en realidad es muy sencillo:

Código: C++
  1. const char *s = "^ukrvyqzy~7uw{6j}llqol", *t=s;
  2. for(int n = ({int n=0; while(*t++) n++; n;}); n--;)
  3.         cout << (char)(n? *(s+n) ^ 0x18: '\n');

@fabianjsm is on twitter