2009-06-28 19 views
7

Estoy escribiendo un pequeño programa en C para hacer algunos cálculos numéricos, y necesita pasar arreglos entre funciones. Las funciones deberían aceptar y devolver punteros, ¿verdad?¿Los punteros y matrices son diferentes en C?

Por ejemplo, este (ya sé que puede no ser lo más eficiente):

int* reverse(int* l, int len) { 
    int* reversed = malloc(sizeof(*reversed)*len); 
    int i, j; 
    for (i = 0, j = len-1; i < len; i++, j--) { 
     reversed[j] = l[i]; 
    } 
    return reversed; 
} 

Am I utilizando punteros verdad?

+1

tu ejemplo miradas multa. El tema más amplio de la diferencia entre arrays y punteros se ha abordado aquí anteriormente, como en http://stackoverflow.com/questions/660752/pointer-vs-array-in-c-non-trivial-difference. –

+0

(Esto no calificaría como respuesta) La matriz y el álgebra del puntero difieren solo en ese tamaño (array_name) devuelve el recuento de los elementos de array_name, no el tamaño de la matriz en bytes. – jpinto3912

Respuesta

14

el fragmento de código es correcto. Sin embargo, los punteros y matrices en C son de hecho diferentes. Simplemente, "el puntero para escribir T" no es lo mismo que "la matriz de tipo T".

Por favor, eche un vistazo a C Faq discutiendo matrices & para obtener una mejor comprensión de esto.

+2

Upvoted for C Faq - más detallada que una respuesta se pondría así SO. –

+1

+1 para C Preguntas frecuentes –

1

Desde una perspectiva de bajo nivel, una matriz es una porción continua de memoria a la que se accede por la dirección del comienzo de esa porción y la compensación, por lo que desde ese nivel de abstracción, es un puntero. Sin embargo, desde la perspectiva del lenguaje C, un tipo de matriz es diferente de un tipo de puntero. Básicamente, una matriz se puede asignar a un valor de puntero, pero no es del mismo tipo.

Para el propósito de su función, lo está haciendo bien.

+3

su audaz declaración requiere una explicación. –

+0

No importa, Crashworks ya lo explicó –

0

las matrices en C se representan y manipulan mediante un puntero al primer elemento, p.

int arr[50]; 
int * ptr1 = arr; 
int * ptr2 = &arr[0]; 

en este ejemplo, ptr1 == ptr2 porque la dirección del primer elemento de la matriz y el puntero de base para la matriz son los mismos.

para que su ejemplo básico es correcta, aunque sospecho que el malloc probablemente debería ser:

int* reversed = malloc(sizeof(int)*len); 

+0

Eso es por si acaso quiero cambiarlo a algo más (un 'largo', por ejemplo) así que no tendré que cambiar dos cosas. – Javier

+1

No, su malloc está bien (y es preferible al suyo) desde C99. – smcameron

+0

@ [smcameron]: @reyjavikvi]: una técnica interesante (no noté el * prefijo la primera vez, ¡lo siento por eso!). Aprendí C en 1982 y no lo he usado mucho desde 1994, así que nunca he leído la especificación C99 (debe haber perdido la nota sobre eso! ;-)) –

1

En teoría pedante, los arreglos y punteros son cosas diferentes, ya que una matriz especifica una región de memoria y, por lo tanto, el tamaño de una matriz es parte de su tipo. Entonces uno dice que un nombre de matriz decae en un puntero cuando se usa en ese contexto. There's a detailed explanation in the C-FAQ.

En la práctica son los mismos ya que formalmente a[i] es lo mismo que *(a+i), y por lo tanto el extremo posterior del compilador trata un nombre de matriz y un puntero exactamente de la misma manera. La única diferencia que vale la pena preocuparse es que

void foo() 
{ 
    int a[5]; // allocates five words of space on the stack 
    int *b; // allocates *one* word of space on the stack (to hold the pointer) 
} 

Su fragmento de código está bien. Sólo tenga cuidado de liberar la memoria de que su función malloc() s en quien la llame.

2

Un enlace a C-FAQ: matrices y punteros ya se ha dado, pero también hay una explicación detallada en C for Smarties: Arrays and Pointers. Es posible que desee leer la página "Analizar expresiones" primero.

Un par de cosas acerca de su ejemplo que deben corregirse:

  1. Usando int en lugar de la correcta size_t para el almacenamiento de tamaño de los objetos.
  2. Falla al verificar el valor de retorno de malloc().

Una forma de "arreglar" este segundo problema es dejar que la persona que llama decidir dónde se almacena la salida (tal vez la persona que llama no quiere o necesita una matriz recién asignado):

int *reverse(int *out, int *l, size_t len) { 
    size_t i, j; 
    for (i = 0, j = len - 1; i < len; ++i, --j) { 
    out[j] = l[i]; 
    } 
    return out; 
} 
Cuestiones relacionadas