gcc 4.4.4

¿Qué estoy haciendo mal?

char x[10];
char y[] = "Hello";
while(y != NULL)
    *x++ = *y++;

Muchas gracias por cualquier consejo.

  • Matrices no son punteros.
InformationsquelleAutor ant2009 | 2010-07-29

9 Comentarios

  1. 28

    x++ es la forma corta de x = x + 1. Sin embargo, x aquí es una matriz y no se puede modificar la dirección de una matriz. Así es el caso de la variable y demasiado.

    Lugar de tratar de incremento de las matrices, se puede declarar un entero i y el incremento que, a continuación, acceder a la i‘th índice de matrices.

    char x[10], y[5] = "Hello";
    int i = 0;
    while (y[i] != 0)
    {
        x[i] = *y[i];
        i++;
    }
    x[i] = 0;
    • ¿Por qué mezclar el *(x+i) y x[i] formas en el mismo código?
    • Para demostrar la relación entre los dos.
    • ¿por qué se le permite hacer argv++ entonces? lo que es especial acerca de argv?
    • Soy un principiante en C que a mí, así yo podría estar equivocado, pero no es argv declarado como char *argv[] (como opuesto a char buf[] en estos ejemplos)? Por lo tanto, que no modifique la dirección de la base de la matriz en sí, sólo un puntero en relación a la matriz. O?
    • no es especial, es un argumento. Argumentos (bueno, argumentos que no son const, de todos modos) son totalmente mutable porque son copias de las variables originales. Es por eso que una función que modifica int x ha de ser definido como este void modifyX(int *x){ ... } y se invoca como este modifyX(&x). En consecuencia, la que me llevó aquí porque estoy tan acostumbrado a pasar un char[] en una función y modificar directamente que yo estaba confundido cuando llegué a este error de compilación después de definir un char[] en la misma función que modifica la dirección de la base. TIL
    • no, es porque argv es un argumento, lo que se copia en el ámbito local por separado de la variable original. Yo diría que el hecho de que este funciona es suficiente prueba de ello.
    • No debe ser al mismo tiempo(s[i] != ‘\0’) ?

  2. 21

    Más probable es que usted es víctima de una idea falsa popular que «array es un puntero», es decir, cuando se define una matriz de lo que en realidad consigue es un ordinario puntero que apunta a un bloque de memoria asignada a algún lugar. En el código se está haciendo un intento para incrementar ese puntero.

    El código no «trabajo» porque, en realidad, las matrices no son punteros. Las matrices son matrices. Las matrices no se incrementa. No hay tal operación como «el incremento de una matriz» en lenguaje C. De hecho, las matrices de por sí en C son no modificables lvalues. No existen operaciones en C que puede modificar la propia matriz (sólo a los elementos individuales pueden ser modificables).

    Si quieres recorrer los arrays utilizando el «deslizamiento» puntero de la técnica (que es lo que realmente están tratando de hacer), es necesario crear los punteros de forma explícita y ponerlos a punto para el inicio de los elementos de las matrices

    char *px = x;
    char *py = y;

    Después de que usted puede incrementar estos punteros tanto como usted desea.

    • En la «realidad», las matrices de se punteros. Es cierto que en la pila de matrices asignadas como char myString[] son inmutables en el sentido de que no se puede modificar el puntero de la dirección. Pero eso no cambia el hecho de que todavía están punteros, al principio de un bloque de memoria que se encuentra en la pila. Así que cuando usted dice «Matrices no son punteros», que son directamente contradiciendo fundamentales de los detalles de implementación que son necesarios para la comprensión de C.
    • Mejor: Mal. Matrices NO son punteros. Y este es un detalle fundamental, la comprensión de que es necesario para la comprensión de C. Esta cuestión ha sido explicada hasta la muerte ya (c-faq.com/aryptr/index.html) y es muy raro ver a alguien que todavía luchan con el concepto de hoy, en el año 2016. Dennis Ritchie en la decisión de abandonar los punteros para la aplicación de las matrices fue uno de los pasos críticos en la evolución de la lengua. Y aún así seguir reiterando este «matrices de punteros» sin sentido hoy en día?
    • bien, entonces ¿qué printf("%p", myString) de impresión? Oh, a la derecha, una dirección de memoria. Causa p es un puntero. Debido a que las implementa como punteros, porque no hay ningún tipo de error se produce cuando se envía un array a una función que espera un puntero. Incluso en un compilador de C++ con -Wall -pedantic. ¿Por qué alguien podría creer que es un puntero? Tal vez porque lo es. Tal vez porque *myString elimina referencias a la dirección y devuelve el valor que señala el puntero. Los punteros son rectángulos y los arreglos son cuadrados. Todas las matrices son punteros, pero no todos los punteros son matrices. Ellos NO son mutuamente excluyentes.
    • array[n] es la sintaxis de azúcar para *(pointer + n). Puede resultar sorprendente, en su delirante todo al más alto nivel, código máquina no existe el mundo de la fantasía, que n[array] devolverá exactamente lo mismo y producir ni un solo error o advertencia de un C ni C++ compilador ejecuta con -Wall -pedantic. TODOS los observables evidencia visto en la práctica puntos a las matrices de ser sintaxis de azúcar para los punteros. La única contradicción, de que una matriz de dirección no puede ser modificada dentro del mismo ámbito que se define en el, no significa nada cuando se puede pasar a otra función, de todos modos.
    • Mejor: No. Su printf imprime correctamente la dirección de la memoria, simplemente porque en lenguaje C de la matriz de myString en este contexto es sometida de inmediato a los llamados matriz a-puntero de conversión (también conocido como «tipo de matriz de la corrupción»). El temporal resultado de la conversión – de hecho un puntero – es enviado a printf en lugar de la matriz. La misma se aplica a todos sus pequeños experimentos, todos los cuales han sido golpeados hasta la muerte ya que, como dije antes. La FAQ enlace que te di, explica todo esto.
    • La única contextos en C que no activan la matriz-a-puntero de conversión son: 1) sizeof, 2) unario &, 3) intialization de char[] con el literal de cadena (en C++ hay más). En otras palabras, usted ha hecho un montón de [no-representativa] experimentos y, a continuación, saltó a una ingenua y absurda conclusión: «matrices de punteros». Matrices NO son punteros. Sólo las matrices de convertir (caries) a punteros implícitamente en la mayoría de los contextos de los casos en C. Pero no en todos los contextos.
    • Estoy hablando acerca de los detalles de implementación de bajo nivel, como en, cómo C se implementa en el nivel de la máquina, y no las abstracciones que el compilador utiliza para evaluar la corrección de código. En el nivel más bajo, todo es un entero. Una matriz es un número entero almacenado en la RAM, que cuando se examinan, revela la ubicación en la memoria RAM para otro número entero, almacenados en otro lugar. Los punteros también se ajustan a este proyecto de ley, porque son un entero que revela la ubicación de otro entero en algún otro lugar. Es importante entender esto para que uno pueda comprender intuitivamente las matrices y punteros.
    • También, usted debe trabajar en su uso de los artículos, la puntuación y la frase de flujo. Porque su inglés es difícil de leer. "Your printf correctly prints memory address simply because in C language array myString in this context is immediately subjected to so called array-to-pointer conversion (aka "array type decay")" <– Difícil de leer
    • "The only reason your printf example works is because, in this context, arrays are subjected to array-to-pointer conversion, a.k.a. array type decay." <– más Fácil de leer.
    • Mejor: de Bajo nivel implementatin detalles es exactamente de lo que estoy hablando. De hecho, en el nivel más bajo de todo, es un número entero. Y NO, la matriz no se almacena como un entero que revela la ubicación en la memoria RAM para otro número entero, almacenados en otro lugar». Al hacer esta afirmación son, otra vez, tratando de forzar su imaginario «punteros» en la imagen. Una matriz se almacena en la memoria de inmediato, como un continuo bloque de números enteros. No hay necesidad de un entero intermedio a «punto» para que el bloque de memoria.
    • Cuando se declara char a[100], lo que obtienes es una continua bloque de memoria de 100 bytes (chars) directamente asociadas con el nombre de a. Cuando usted accede a a, que de forma directa e inmediata el acceso de ese bloque de 100 bytes. NO hay intermedio entero que contiene la ubicación de los que 100 bytes de bloque, como usted parece creer erróneamente.
    • Es importante entender que, con el fin de «conseguir» el simple hecho de que en lenguaje C las matrices y punteros son dos entidades completamente diferentes (que de casualidad se comportan de manera similar superficial de nivel de idioma en algunos contextos). En realidad matrices NO son punteros y matrices NO son implementadas bajo el capó como «punteros en disfraz».
    • Hay (que solía ser) muy pocas personas en C círculos que sufren de este popular «matrices de punteros» el error, hasta que finalmente empezar a usar unario & o sizeof con matrices o empezar a trabajar con mutidimensional de matrices. Esto es cuando este error se viene abajo sobre ellos y que finalmente consiga aprender lo que las matrices son realmente en C.
    • «No existe NINGÚN entero intermedio» Uh huh, y cómo, entonces, ¿el CPU por arte de magia almacenar una matriz, sin un lugar físico en la memoria RAM para almacenar en? Se tiene que guardar en algún lugar, y ese lugar es, de hecho, un número entero. El x-esima byte desde el punto de partida en la memoria RAM es donde la matriz se inicia. x es la dirección, y el «intermedio entero». Para los que no tienen «entero intermedio» es físicamente imposible, porque entonces no habría ninguna manera de la CPU podría almacenar. La caché L1 y de la CPU en la placa de registros son incapaces de mantener un 1000-la longitud de la matriz de char. Tiene que ir a la pila o montón.
    • Mejor: Wow Wow Wow! Vamos a parar un segundo aquí. En primer lugar, usted necesita decidir qué es exactamente lo que están hablando acerca de whwn usted está diciendo que «matrices de punteros». Es cierto que cada objeto en memoria tiene una dirección y se refiere por un número entero (dirección) emebedded en la instrucción de la máquina. Pero eso es cierto para todos los objetos almacenados en la memoria. Cada vez que se declara una int a; variable o double x; variable o struct S { int x, y; } s; variable, estas variables se refiere por entero de direcciones en la que genera el código máquina.
    • Así que, ¿estás tratando de reclamar que int a; también es un puntero? Estás tratando de reclamar que cada struct objeto es un puntero? Básicamente, esta lógica nos llevaría a la conclusión de que cada objeto y cada función en C es «realmente un puntero». Lo siento, si bien esto puede retener agua en lenguaje ensamblador terminolgy, esto no tiene nada que ver con C de ningún tipo. En lenguaje C de objetos en la memoria se llama lvalues. Lvalue es la adecuada C plazo de lo que está hablando. «Lvalue» y «puntero» en C son dos conceptos totalmente diferentes. No los mezcle. Y matrices no son punteros en C.
    • Mientras tanto, comenzó con algo completamente diferente. Comenzó con un printf ejemplo y *(a + i) ejemplo, afirmando que estos ejemplos demuestran que las «matrices de punteros». Esto no tiene nada que ver con la forma de objeto addersses están representados en la máquina de comandos. Le miró fijamente con una reclamación de que las matrices en C son «bipartito» objetos: un puntero de datos apuntando a otro bloque de datos en la memoria. Esta afirmación no es simplemente verdad. Las matrices no son diferentes de estructura en este sentido: sólo son bloques continuos de la memoria. Las estructuras no son punteros en C. Ni son matrices, exactamente de la misma manera.
    • Así que, de nuevo, usted necesita decidir primero lo que está hablando. Se mezcla (y flip-flop entre) dos conceptos totalmente diferentes temas.

  3. 7

    Matrices en C son de hecho los punteros, pero constante de los punteros, lo que significa que después de la declaración de sus valores no se pueden cambiar.

    int arr[] = {1, 2, 3};
    //arr is declared as const pointer.

    (arr + 1) es posible, pero arr++ no es posible porque arr no puede almacenar otra dirección, ya que se es constante.

  4. 5
    char x[10];
    char y[] = "Hello";
    char *p_x = &x[0];
    char *p_y = &y[0];
    while(*p_y != '\0') *p_x++ = *p_y++;

    Ya que no se puede modificar la matriz de direcciones (hecho por x++ y y++ en el código) y puede modificar el puntero de dirección, he copiado la dirección de la matriz en distintos punteros y luego incrementa ellos.

    Si quieres, estoy seguro de que usted puede reducir la notación, pero espero que se entendió el punto.

    • char *p_y = &y[0]; en lugar de char *p_y = y;? Parece un poco redundante.
  5. 3

    x y y son matrices, no punteros.

    Se pudren en los punteros en la mayoría de los contextos de expresión, tales como su incremento de expresión, pero se pudren en rvalues, no lvalues y sólo se puede aplicar el incremento a los operadores de lvalues.

  6. 1

    Puesto que usted ha definido tanto x y y como las matrices, no se puede modificar. Una posibilidad sería el uso de punteros lugar:

    char x[10];
    char *xx = x;
    
    char *y = "Hello";
    
    while (*y != '\0')
        *xx++ = *y++;

    Nota que me he fijado su condición de terminación — un puntero no se NULL sólo porque llegó a la final de una cadena.

    • Supongo que un nul es mejor que un null.
  7. 0

    En la mayoría de las veces, de la matriz como un puntero.

    Sólo recuerde que usted no puede modificar la matriz!

    Y y++ es y = y + 1.

    char y[] = "Hello";

    Lo que no es modificar la matriz cuando y++!!

    Se va a producir error: lvalue required as increment operand.

  8. 0

    No podemos modificar un nombre de matriz, pero, ¿Qué acerca de argv++ en f(int argv[])?

    Citas de K&R en p99 «del nombre de una matriz no es una varible; la construcción como a = pa y a++ son ilegales», que dice el nombre de un array es un sinónimo para la ubicación del elemento inicial.»

    Pero ¿por qué parámetro de la función func(char *argv[]), podemos hacer argv++ a pesar de argv es un nombre de matriz.

    Y en int *a[10], no podemos hacer el a++ como argv++.

    El nombre de matriz es un sinónimo para la ubicación del elemento inicial. —K&R

    arrayname++ es ilegal.

    En función de parámetros, tales como char *argv[], es el mismo que char **argv. type *arrayname_para[] en parámetro es otro sinónimo de type **arrayname_para.

  9. -1

    Matrices son constantes punteros. No podemos cambiar ellos.

    int q;
    int *const p = &q;
    p = NULL; //this is not allowed.

Dejar respuesta

Please enter your comment!
Please enter your name here