2016-06-02 17 views
0

In unserem Vermächtnis C/C++ Code in denen ich zwei Versionen von UnterschriftenUnterschiede zwischen Doppel * VEC und Doppel vec []

void foo1(double *vec, int n) 

und

void foo2(double vec[], int n) 

Aber es gibt keinen Unterschied in der Handhabung von der Parameter vec innerhalb der Methoden, zB:

void foo2(double vec[], int n){ 
    for(int i=0;i<n;i++) 
     do_something(vec[i]); 
} 

gibt es einen Unterschied zwischen der erste Version (double *) und die zweite (double ..[])? In welchen Situationen sollte eine Version gegenüber der anderen bevorzugt werden?

Edit: Nach dem Hinweis von @ Khaled.K Ich habe versucht zu kompilieren:

void foo(double *d, int n){} 
void foo(double d[], int n){} 

und bekam einen Compiler-Fehler aufgrund Neudefinition der Leere foo(double *d, int n). Also double *vec und double vec[] bedeuten das Gleiche.

Die noch offene Frage ist, welche Version wann verwendet werden sollte.

+2

Nein, es gibt keinen Unterschied. In einem Parameter wird '[]' als '*' eingestellt. –

+0

['char *' und 'char arr []' Unterschied] (http://stackoverflow.com/q/16677858/995714) –

+1

@ LưuVĩnhPhúc, er möchte Unterschiede, wenn sie als Parameter an eine Funktion übergeben werden. – Haris

Antwort

1

Hier ist der relevante Zitat von K & R 2. (*), am unteren Rand der Seite 99 beginnen:

Als formale Parameter in einer Funktionsdefinition,

char s[]; 

und

char *s; 

sind gleichwertig; wir bevorzugen das letztere, weil es mehr explizit besagt, dass der Parameter ein Zeiger ist. Wenn ein Array-Name an eine Funktion übergeben wird, kann die Funktion an ihrer Bequemlichkeit davon ausgehen, dass sie entweder ein Array oder einen Zeiger verwendet hat, und sie entsprechend manipulieren. Es kann sogar beide Notationen verwenden, wenn es angemessen und klar erscheint.

(*) Kernighan & Ritchie: "The C Programming Language" (zweite Auflage)

+0

Ich muss gestehen, ich weiß nicht was K & R bedeutet – ead

+0

@ead Geständnis angenommen, Antwort aktualisiert;) – fredoverflow

5

Es ist das gleiche. Von der Norm:

Nachdem die Art jedes Parameters Bestimmen beliebiger Parameter des Typs „array of T“ oder von Funktionstyp T wird so eingestellt, „Zeiger auf T“

so zu sein gibt es kein Unterschied. Ich würde * anstelle von [] verwenden, um Verwirrung zu vermeiden, es sei denn, es ist etwas wie char* argv[], dann könnte es passierbar sein.

+1

Ich würde sagen, beide verwenden, um die Absicht des Parameters besser zu dokumentieren: '*' wenn Funktion erwartet, dass Parameter ein einzelnes Element ist, und '[]', wenn es erwartet, dass es mehrere Elemente sind. – user694733

+0

Ich verstehe nicht, was du mit dem letzten Satz meinst. Kannst du es ausarbeiten? – 2501

+0

@ user694733 möchte sagen, dass 'void foo2 (double *)' "** helfen könnte **" bei der Entschlüsselung, dass eine doppelte Variable übergeben wird, da die einfache Bedeutung von 'double *' ist einfach ein Zeiger auf double oder Adresse bei dem Ein Doppel ist gespeichert. 'void foo2 (double [])' könnte bei der Entschlüsselung in 'foo2' helfen, dass ein Array von double übergeben wird. – sameerkn

-2

double *vec bedeutet, dass es nur einen doppelten Wert gibt, auf den vec zeigt. Und double []vec bedeutet, dass es eine Reihe von Doppelgänger gibt. Aus dem Code, den Sie zeigen, scheint das Double-Array das zu sein, was Sie wollen. Die Verwendung von double * vec für Array-Operationen führt zwangsläufig zu Problemen.

1

Es gibt keine Grenze Check in c.Wie Sie wissen, fungiert der Array-Name selbst als ein Zeiger (mit speziellen Eigenschaften). Wenn Sie ein Array als Argument an eine Funktion übergeben, wird es intern als Zeiger des entsprechenden Typs übergeben. Aus diesem Grund müssen Sie auch die Länge des Arrays übergeben, wenn Sie eine Operation für die gebundene Prüfung durchführen möchten. Der Compiler generiert die gleiche Signatur (Objektcode) für Zeiger und Array als formales Argument. Sie können beide unveränderlich nach Ihrer Wahl verwenden. Im Folgenden finden Sie ein einfaches Beispiel:

#include <iostream> 
void arrayParamTest(int arr[]) 
{ 
} 
int main() 
{ 
    int arr[] = {10, 20}; 
    arrayParamTest(arr); 
} 

Nun ist diese kompilieren und lässt die Symbole sehen:

[email protected]:myExperiments$ nm a.out | grep "arrayParamTest" 
00000000004006e7 t _GLOBAL__I__Z14arrayParamTestPi 
0000000000400674 T _Z14arrayParamTestPi 

Siehe Compiler generiert Symbol mit "Pi" als Argument. Pi bedeutet Zeiger vom Typ int. Hoffe das wird helfen. :-)

1

Array und Zeiger sind unterschiedlich, aber einige Eigenschaften von Array und Zeigern sehen ähnlich aus.

In diesem Fall gibt es keinen Unterschied zwischen double * vec und double vec [].

Aber immer wenn Sie Array genommen und mit einigen Werten initialisiert haben und dann haben Sie dieses Array als Funktionsargument übergeben.

In der Funktionssignatur, wenn Sie double * vec verwenden, dann würden Sie unerwartet versuchen, diesen Speicher in der Funktionsdefinition dynamisch freizugeben. Dann wird eine Ausnahme zur Laufzeit ausgelöst, d.

Beispiel:

#include<stdio.h> 
#include<stdlib.h> 
void foo1(int *arr); 
int main() 
{ 
    int arr[] = {10, 20}; 
    foo1(arr); 

    return 0; 
} 
void foo1(int *arr) 
{ 
    printf("in array\n"); 
    free(arr); 
} 

Warum bedeutet

-> Arrays in statischer Natur sind, wenn Sie Speicher zugewiesen Sie dynamisch nicht frei und die Größe können.

-> Dies ist der eine Fall, der mit Doppel * Vec verwirrt.

-> Außer wie diese Situationen sind beide Signaturen ähnlich.

Verwandte Themen