¿Qué hace el operador con char *?

Soy nuevo en C. Estoy leyendo un algoritmo de búsqueda y reemplazo para C y estoy un poco confundido sobre lo que hacen los operadores - & + en este código:

 char *replace(char * src, const char * search, const char * replace) { char * buffer = malloc(4096); //allocate 4096 bytes in memory to new string char * p; //substring of my search in the src string int i; p = strstr(src, search); if ( NULL == p ) return src; if // 'search' not found on 'src' return src i = p - src; //index of my substring strncpy(buffer, src, i); //copy the substring value to buffer sprintf(buffer + i, "%s%s", replace, p + strlen(search)); // ??? return buffer; } 

Dado que p es una ubicación en la matriz de caracteres (cadena) y src es el comienzo de la misma,

 i = p - src; 

establecerá i en el índice al que p apunta.

Por ejemplo, considere el siguiente diseño de memoria:

  [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] <-- Indexes 123 124 125 126 127 128 129 130 131 132 <-- Addresses +---+---+---+---+---+---+---+---+---+----+ | H | i | , | | w | o | r | l | d | \0 | +---+---+---+---+---+---+---+---+---+----+ ^ ^ | | src p 

En este caso, p - src le dará 127 - 123 o 4 , que es el índice de w dentro de "Hi, world" .

Esto se denomina aritmética de punteros y se cubre en los Additive operators en la norma ISO ( C99 6.5.6/9 ):

Cuando se restan dos punteros, ambos apuntarán a elementos del mismo objeto de matriz, o uno más allá del último elemento del objeto de matriz; el resultado es la diferencia de los subíndices de los dos elementos de la matriz.

Proporciona una forma escalada de resolver diferencias dentro de la misma matriz o con una que apunta más allá del final de la matriz (todo lo demás no está definido).

Con eso me refiero a hacer aritmética de punteros con (por ejemplo) enteros de cuatro bytes, le dará una diferencia de uno entre las direcciones de arr[7] y arr[8] , no cuatro como algunos pueden pensar.

La construcción buffer + i es simplemente otra forma de decir &(buffer[i]) , la dirección del elemento i th del buffer . De hecho, prefiero el último método, ya que parece más explícito en lo que estoy tratando de representar.

Para lo que vale, no es realmente un código de reemplazo de cadena muy bueno. Tiene numerosos problemas:

  • Si no se hacen reemplazos, tiene una pérdida de memoria 4K con buffer .
  • En cualquier caso, siempre debe verificar que malloc no haya fallado.
  • tiene la posibilidad de desbordar el búfer de la forma en que se asigna la nueva cadena, realmente debería asignar en función de las longitudes de search y replace src .
  • puede crear la nueva cadena con un solo sprintf ("%*.*s%s%s", i, i, src, replace, &(src[i + strlen (search)])); o una strcpy y dos operaciones strcat . Mezclar los dos me parece incongruente.

Es un simple indicador de aritmética.

buffer + i es la subcadena de buffer , que comienza desde el carácter i th [hasta el final]

p - src le da el desplazamiento entre p a src .

p es solo un puntero – un valor entero

Los operadores + y - funcionan exactamente como cabría esperar: aumentan o disminuyen el valor del puntero.

Si piensas que las cadenas son una matriz contigua de caracteres, solo estás hablando de una ubicación dentro de esa cadena.

Lea más sobre aritmética de punteros.

Básicamente + para char * :

 a=a+1 => a=(char *) ( (int)a + sizeof(char) )