2013-06-13 2 views
0

Я новичок в C, и я ищу способы передать массив функции и получить доступ к элементам.Передача массива функции как массива vs как указатель

Я нахожу, что есть 3 способа сделать это.

  1. проход в массиве, а функция конкретных параметров, как тип массива
  2. проход в массиве, а функция конкретных параметров, как тип указателя
  3. проход в адрес из первого элемента (на самом деле этот адрес равен адресу массива, я думаю, что это то же самое, что и метод 2)

То, что я не понимаю, заключается в том, что с использованием метода 1. Addr ess передаваемого массива отличается от адреса параметра массива в функции. В чем разница применения метода 1 и метода 2.

код:

#include <stdio.h> 

void pass_by_array(int x[]); 
void pass_by_pointer(int *x); 
int main(void){ 
    int i; 
    int base[5] = {3, 7, 2, 4, 5}; 
    printf("address of first element in main %p\n", &base[0]); 
    printf("address of array in main %p \n\n", &base); 
    pass_by_array(base); 
    pass_by_pointer(base); 
} 

/* Pass in the array as type of int x [] */ 
void pass_by_array(int x[]){ 
    printf("address of first element passed in: %p \n", &x[0]); 
    printf("address of array passed in: %p \n\n", &x); 
} 

/* Pass in the array as type of int pointer*/ 
void pass_by_pointer(int *x){ 
    printf("passing in array by pointer, address: %p",x); 
} 

выход:

address of first element in main 0xbfcea3ac 
address of array in main 0xbfcea3ac 

address of first element passed in: 0xbfcea3ac 
address of array passed in: 0xbfcea390 

passing in array by pointer, address: 0xbfcea3ac% 

ответ

2

Эта линия:

printf("address of array passed in: %p \n\n", &x); 

неправильно. Вы не распечатав адрес массива, но адрес локальной переменной, что указатель массива хранится в (Да, x это указатель.) Просто распечатайте x:.

printf("address of array passed in: %p \n\n", x); 

Ответ заключается в том, что в этом случае не имеет большого значения, каким образом вы его заявляете. int[] и int* в C иногда взаимозаменяемы, и это один из случаев, когда они есть.

Дальнейшее чтение:

  • Are pointers and arrays equivalent in C? (. В частности, в разделе «массивы, передаваемые функции преобразуются в указатели» секции)
+0

спасибо за ваш быстрый ответ. Ой! Извините за ту глупую ошибку, которую я совершил. Я буду принимать ваш ответ как можно быстрее :) – code4j

+1

@ code4j Я бы не назвал это глупой ошибкой. C - сложный язык с очень специфическими и ситуационными правилами. Раньше или позже все сталкиваются с этим вопросом. – cdhowie

2

Хотя они имеют ту же семантику компилятора, есть хороший причина для использования с использованием формы []. В частности, когда вы ожидаете, что аргумент представляет массив определенного измерения (как статический, так и заданный в другом переданном аргументе), вы можете сделать запрос более ясным, чем использование синтаксиса *.

Это

int arraySum(int n, int ary[n]); 

документы значение аргумента n, а

int arraySum(int n, int *ary); 

нет.

Аналогично

void crossProduct(double result[3], double v1[3], double v2[3]); 

проясняет, что аргументы, как ожидается, будет 3-мерные векторы, а

void crossProduct(double *result, double *v1, double *v2); 

оставляет читателя гадать.

Опять же, компилятор рассматривает их как одно и то же, но человеческий читатель может получить больше информации из одной формы, чем другой.

+0

Я обычно пользуюсь самодокументирующим кодом, но лично я предпочел бы описывать ожидаемый размер массива в комментарии, а не использовать 'double result [3]'. Я думаю, что последнее вводит в заблуждение, поскольку компилятор вообще не проверяет его. – jamesdlin

+0

@jamesdlin Это не только правильная документация, но и дополнение. И да, компилятор не проверяет, неловко. – dmckee

+1

Правда, это не исключает правильную документацию, но я чувствую, что это неудобно, что она гарантирует * дополнительную * документацию (например, 'double result [3], // Компилятор не применяет размер массива и не использует sizeof на этом »), и этот момент, я считаю, что это не стоит усилий. – jamesdlin

Смежные вопросы