2014-12-28 4 views
2

first function 내에서 호출되거나 수행되는 second function에 구조체 배열을 전달하는 방법을 배우고 싶습니다. 내 목표는 수정/임의의 구조체의 내용을 second function에서 변경하는 것입니다. 아래의 코드는 작동하지만 불행히도 내가 원하는 것을 정확히 수행하지는 않습니다. second function 내의 임의의 구조체에 액세스해야합니다. 즉, second function 내에서 main 만 번을 호출하고/실행하여 for 루프를 사용하지 않고 모든 구조체 (for 루프 사용)를 처리하려고합니다.구조체 배열을 함수에 전달 하시겠습니까?

아래 코드의 second functionpassByReference_inner입니다.

array_of_struct.h :

struct card 
{ 
    int face; 
    int nose; 
}; 

typedef struct card HEAD ; 

/* prototype */ 
extern void passByReference(HEAD **c);  /* first function */ 
extern void passByReference_inner(HEAD *c); /* second function */ 

제 기능 : (passByReference)

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference(HEAD **c) 
{ 
    passByReference_inner (*c); /* second function */ 
} 

초 기능 : (passByReference_inner)

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference_inner(HEAD *c) 
{ 
    c->face = (c->face) + 1000; 
    c->nose = (c->nose) + 2000; 
} 

주 : 당신이 무엇을하려고 생각

#include <stdio.h> 
#include "array_of_struct.h" 

int main(void) 
{ 
    int    i; 
    static HEAD  c[12]; 
    static HEAD *cptr[12]; 

    for (i = 0; i < 12; i++) 
    { 
     c[i].face = i + 30; 
     c[i].nose = i + 60; 
     cptr[i] = &c[i]; 
    } 

    for (i = 0; i < 12; i++) 
    { 
     passByReference(&cptr[i]); /* first function */ 
    } 
    return 0; 
} 
+0

I는 C 언어 만 값, 참고로 통과 할 수있는 모든 질문 –

+0

...이 같은 있었으면; 그러나 포인터를 전달할 수 있습니다. main()에서 – user3629249

+0

, 변수 'cptr'및 모든 사용법을 main()의 '& c [i]' – user3629249

답변

1

두 번째 기능이 정확합니다.

배열의 첫 번째 요소에 대한 포인터는 실제로 배열 자체에 대한 포인터와 동일한 것입니다.

passByReference(c, sizeof(c)/sizeof(c[0])); 
:

당신이해야 할 것은이 같은 배열의 첫 번째 요소와 배열의 요소 수, 뭔가 포인터를 전달할 수 있습니다, 그래서

void passByReference_inner(HEAD *c, size_t n) 
{ 
} 

입니다

이 배열은 c 배열의 첫 번째 요소에 대한 포인터와 배열의 요소 수를 passByReference_inner()로 전달합니다. sizeof (c)는 바이트 단위의 전체 배열 크기입니다. sizeof (c [0])는 배열에있는 요소의 크기입니다. 예를 들어 각 구조체가 10 바이트 길이 (예제)인데 12 개의 구조체 배열이있는 경우 전체 배열의 크기는 120 바이트이고이 값은 120/10 = 12, 어레이의 요소 수를 자동으로 계산합니다.

배열 객체의 이름을 사용하면 C/C++에서 자동으로 배열의 첫 번째 요소에 대한 포인터가됩니다. 함수에서

, 당신은 다음과 같은 방식으로 배열로 작업 할 수 있습니다 :

void passByReference_inner(HEAD *c, size_t n) 
{ 
    for (size_t i=0; i<n; i++) 
    { 
     HEAD *p=c+i; 

     // p is now a pointer to the ith element of the array 
    } 
} 

배열의 다음 nth 요소에 대한 포인터 포인터를 정수 n 진보 추가. 정수 값을 포인터에 추가해도 포인터는이 바이트 수만큼 증가하지 않지만 포인터가 가리키는 개체의 바이트 수에 추가 할 숫자를 곱합니다 (또는 빼기). 포인터 연산이 옳은 일을합니다.

+0

"C/C++에서 배열 객체의 이름을 사용하면 자동으로 포인터가됩니다."C++에서는 포인터가 필요한 상황에서만. 주어진 크기의 배열에 대한 포인터 또는 참조를 전달할 수 있습니다. (C에서 배열에 대한 포인터는 이전 포인터에 바인드하는 것처럼 보입니다. 표준 또는 컴파일러 확장인지 확실하지 않습니다.) – juanchopanza

+0

@juanchopanza이 질문에는 C++이 없습니다. 그리고 "_ 오래된 포인터에 구속력이있는 것 _"은 무엇을 의미합니까? –

+0

@iharob 필자는이 답변에서 "C/C++"(하이브리드 C/C++ 언어가 없기 때문에 두 언어 모두에 적용될 것을 제안 할 수도 있음)를 언급했습니다. "... 어떤 오래된 포인터"에 관해서는, 나의 표현은 가난하지만, C에서 당신은'int'가'int (* p) [2] = & a;'라고 말할 수있는 것처럼 보입니다. C++에서'a'는 int [2]이어야합니다. – juanchopanza

3

은 당신이 알아야 할 것은이

#include <stdio.h> 

struct card 
{ 
    int face; 
    int nose; 
}; 

typedef struct card HEAD ; 

/* prototype */ 
void passByReference(HEAD *c, int count);  /* first function */ 
void passByReference_inner(HEAD *c); /* second function */ 

void passByReference(HEAD *c, int count) 
{ 
    int i; 
    for (i = 0 ; i < count ; i++) 
     passByReference_inner (&(c[i])); /* second function */ 
} 

void passByReference_inner(HEAD *c) 
{ 
    c->face = (c->face) + 1000; 
    c->nose = (c->nose) + 2000; 
} 

int main(void) 
{ 
    int i; 
    HEAD c[12]; /* you don't need static here (do you know what static is for?) */ 

    for (i = 0; i < 12; i++) 
    { 
     c[i].face = i + 30; 
     c[i].nose = i + 60; 
    } 
    /* 
    * the element count of the array is sizeof(c)/sizeof(c[0]) 
    * (totalSizeOfArray)/(indivudualElementSizeOfArray). 
    */ 
    passByReference(c, sizeof(c)/sizeof(c[0])); /* first function */ 

    return 0; 
} 

입니다 자신의 첫 번째 요소 경우를 가리키는 포인터 c 붕괴의 배열 함수에 매개 변수로 전달됩니다.

두 번째 기능의 모든 구조체를 처리 할 때문에, 내가 첫 번째 함수에 대한 필요성이 표시되지 않는 어쨌든이 효과적으로 전달하기 때문에 당신이 다음

#include <stdio.h> 

struct card 
{ 
    int face; 
    int nose; 
}; 

typedef struct card HEAD ; 

/* prototype */ 
void passByReference(HEAD *const c, int count);  /* first function */ 
void passByReference_inner(HEAD *const c, int count); /* second function */ 

void passByReference(HEAD *const c, int count) 
{ 
    passByReference_inner(c, count); /* second function */ 
} 

/* HEAD *const c prevents the pointer c to be changed 
* this way it will never point anywhere else. 
* 
* And you can be sure to alter the original data. 
*/ 
void passByReference_inner(HEAD *const c, int count) 
{ 
    for (int i = 0 ; i < count ; ++i) 
    { 
     c[i].face = (c[i].face) + 1000; 
     c[i].nose = (c[i].nose) + 2000; 
    } 
} 

int main(void) 
{ 
    int i; 
    HEAD c[12]; /* you don't need static here (do you know what static is for?) */ 

    for (i = 0; i < 12; i++) 
    { 
     c[i].face = i + 30; 
     c[i].nose = i + 60; 
    } 
    /* 
    * the element count of the array is sizeof(c)/sizeof(c[0]) 
    * (totalSizeOfArray)/(indivudualElementSizeOfArray). 
    */ 
    passByReference(c, sizeof(c)/sizeof(c[0])); /* first function */ 

    return 0; 
} 

그것을 할 것입니다 방법입니다 포인터를 사용하면 첫 번째와 두 번째 함수에서 내용을 직접 변경할 수 있습니다.

한가지 더, 당신은 정말 특별 main()에, static 함수 호출 사이의 변수의 값을 유지하고, main() 때문에 일반적으로 프로그램의 일생에 한 번만 호출 될 것이라고 static 키워드가 필요하지 않습니다 .. 거기에 static을 사용하는 것은별로 의미가 없습니다.

+0

왜'HEAD'를'static'으로 만들겠습니까? 너는 지나가 다. –

+0

OP는'passByReference_inner' 내부에서'for' 루프를 원합니다. 답변의 본질을 실제로 바꾸지는 않지만 조금 재정렬해야합니다. – user3386109

+0

@ DavidC.Rankin'static'과'const'를 혼동하고 있습니까? – user3386109

0
  • 다음 코드는 정상적으로 컴파일됩니다.
  • 다음 코드는 증분 값 루프
    을 passByReference() 함수 내부로 이동합니다.

/* 
* Note: guard code is used in a header file 
*  so the header file can only be included once 
*  in each compilation unit 
*/ 

// note the inclusion of a 'guard' wrapper 
// begin: array_of_struct.h file 
#ifndef ARRAY_OF_STRUCT_H 
#define ARRAY_OF_STRUCT_H 

struct card 
{ 
    int face; 
    int nose; 
}; 

// dont obsecure the code with useless typedef statements 
//typedef struct card HEAD ; 

#define MAX_CARDS (12) 

/* prototype */ 
extern void passByReference(struct card *pCards);  /* first function */ 
extern void passByReference_inner(struct card *pCard); /* second function */ 
#endif 
// end: array_of_struct.h 


//first function: (passByReference), in different file 

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference(struct card *pCards) 
{ 
    int i=0; // loop index 

    for(i=0;i<MAX_CARDS;i++) 
    { 
     passByReference_inner (&pCards[i]); /* second function */ 
    } // end for 
} // end function: passByReference 

// second function: (passByReference_inner), in different file 

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference_inner(struct card *pCard) 
{ 
    pCard->face = (pCard->face) + 1000; 
    pCard->nose = (pCard->nose) + 2000; 
} // end function: passByReference_inner 

//main, in a different file 

#include <stdio.h> 
#include "array_of_struct.h" 

int main() 
{ 
    int i = 0; // loop index 
    static struct card  cards[MAX_CARDS]; 

    for (i = 0; i < MAX_CARDS; i++) 
    { 
     cards[i].face = i + 30; 
     cards[i].nose = i + 60; 
    } // end for 

    passByReference(&cards[0]); /* first function gets ptr to whole array*/ 
    // could also be written as: 
    // passByReference(cards); 

    return 0; 
} // end function: main 
0

나는 모든 세 가지 솔루션 (iharob, user3629249, 샘 Varshavchik)을 분석 한 샘 Varshavchik 및 iharob에서 두 번째 솔루션은 바로 돈에 있다고 결론에 도달했다. 첫 번째 iharob의 솔루션과 user3629249 솔루션은 본질적으로 동일합니다. 그들은 for 루프를 main에서 first function으로 이동했습니다. iharob의 게시물의 두 번째 솔루션은 초기 게시물의 요구 사항을 충족시킵니다. 샘의 솔루션은 'for 루프를 메인에서 second function으로 이동하는 방법에 대한 충분한 힌트/지침을주었습니다. (기본적으로, 어떻게 수행했는지 모르고 무엇 때문에 도움을 요청했는지).

그래서 짧은 이야기를하기 위해 모든 기여자의 거의 모든 제안을 구현하는 소스 코드가 있습니다. 코드는 깔끔하게 컴파일되므로 나처럼 초보자도 그대로 사용할 수 있으며 포인터에 대한 포인터, 포인터 산술 및 구조체 배열에 대해 자세히 알지 못합니다.

array_of_struct.h (헤더 파일)

#ifndef ARRAY_OF_STRUCT_H 
#define ARRAY_OF_STRUCT_H 

/* HEAD structure definition */ 
typedef struct 
{ 
    int face; 
    int nose; 
} HEAD;  // end structure HEAD 

#define MAX_HEADS (12) 

/* prototype */ 
extern void passByReference(HEAD **c, size_t n); 
extern void passByReference_inner(HEAD *c, size_t n); 

#endif 

passByReference.c (제 1 기능)

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference(HEAD **c, size_t n) 
{ 
    passByReference_inner (*c, n); 
} 

passByReference_inner.C (제 작용)

#include <stdio.h> 
#include "array_of_struct.h" 

void passByReference_inner(HEAD *c, size_t n) 
{ 
    int i; 
    HEAD *p; 

    printf("\nPOINTER ARITHMETIC: The value of struct's members after PASS BY REFERENCE \n"); 
    for (i = 0; i < n; i++) 
    { 
     p = c + i; 

     p->face = (p->face) + 1000; 
     p->nose = (p->nose) + 2000; 
     printf("struct[%i].face = %d \n",i, p[0].face); 
     printf("struct[%i].nose = %d \n",i, p[0].nose); 
    } 

    printf("\nARRAY INDEX MATH: The value of struct's members after PASS BY REFERENCE\n"); 
    printf("[NOTE: structs were updated in the for loop above]\n"); 
    for (i = 0; i < n; i++) 
    { 
     printf("struct[%i].face = %d \n",i, c[i].face); 
     printf("struct[%i].nose = %d \n",i, c[i].nose); 
    } 
} 

을 main.c

#include <stdio.h> 
#include "array_of_struct.h" 

int main(void) 
{ 
    int  i; 
    HEAD c[MAX_HEADS]; 
    HEAD *cptr; 
    size_t n; 

    n = (sizeof(c)/sizeof(c[0]); 

    printf("\nINITIALIZATION of all struct's members\n"); 
    for (i = 0; i < n; i++) 
    { 
     c[i].face = i + 30; 
     c[i].nose = i + 60; 
     printf("struct[%i].face = %d\n",i, c[i].face); 
     printf("struct[%i].nose = %d\n",i, c[i].nose); 
    } 

    cptr = &c[0]; 
    passByReference(&cptr, n); 

    return 0; 
} 
관련 문제