내 C 라이브러리에서 작업하는 C 기술을 제거하고 있습니다. 처음으로 작업을 구현 한 후에는 코드를보다 효율적으로 만들려고합니다. 현재 함수 매개 변수를 참조 또는 값으로 전달하는 주제가 있습니다.C에서 함수 매개 변수를 값으로 전달하는 이유는 무엇입니까?
제 질문은 왜 C로 값으로 함수 매개 변수를 전달할 수 있습니까? 코드가 더 깨끗해 보일 수도 있지만 참조로 전달하는 것보다 항상 효율적이지는 않습니까?
내 C 라이브러리에서 작업하는 C 기술을 제거하고 있습니다. 처음으로 작업을 구현 한 후에는 코드를보다 효율적으로 만들려고합니다. 현재 함수 매개 변수를 참조 또는 값으로 전달하는 주제가 있습니다.C에서 함수 매개 변수를 값으로 전달하는 이유는 무엇입니까?
제 질문은 왜 C로 값으로 함수 매개 변수를 전달할 수 있습니까? 코드가 더 깨끗해 보일 수도 있지만 참조로 전달하는 것보다 항상 효율적이지는 않습니까?
C에서 모든 인수는 값으로 전달됩니다. 당신이 전혀 명시 적 간접없이 변경의 효과를 볼 때 참조로 진정한 패스는 다음과 같습니다
이int sum(int a, int b) {
return a + b;
}
당신은 쓸 것이다 :
void f(int c, int *p) {
c++; // in C you can't change the original paramenter passed like this
p++; // or this
}
하지만 대신 포인터의 값을 사용하여 자주 바람직하다 예 :
int sum(int *a, int *b) {
return *a + *b;
}
안전하지 않으며 비효율적이기 때문에. 추가적인 간접 지정이 있기 때문에 비효율적입니다. 또한 C에서 포인터 인수는 포인터를 통해 값이 수정된다는 것을 호출자에게 알립니다 (특히 뾰족한 유형의 크기가 포인터 자체보다 작거나 같은 경우).
이것은 어리석은 질문 일 수 있지만, 왜''int sum (int * a, int * b) {return * a + * b; }'''함수가 안전하지 않습니까? – c00kiemonster
포인터를 사용하지 않고 절대로 NULL/dangling 포인터를 간접적으로 사용할 위험이 있기 때문입니다. – perreal
발신자는 이제 a 및 b에 대한 변수를 만들어야하며 상수는 전달할 수 없습니다. 호출자는 값을 'malloc'할 필요가 있는지 또는 변수의 주소를 전달해야하는지 결정해야하며, 변수가 'const'가 아니기 때문에 (값을 복사 할 필요가있을 수 있음) 값을 수정할 수 있다고 가정해야합니다. 역 참조 포인터는 호출자가 'NULL', 초기화되지 않은 포인터 및/또는 잘못된 메모리 위치에 대한 포인터를 전달하는 경우 안전하지 않습니다. – Joe
Passing by reference in C을 참조하십시오. 참조에 의한 전달은 C에서 잘못된 이름입니다. 변수 대신 변수의 주소를 전달하는 것을 말하지만 변수 에 대한 포인터를 값으로 전달하고 있습니다.
즉, 변수를 포인터로 전달하면 예가 더 효율적이지만 주된 이유는 포인터가 가리키는 원래 변수를 수정할 수 있기 때문입니다. 이 작업을 수행하고 싶지 않은 경우 의도를 명확히하기 위해 값으로 가져 오는 것이 좋습니다.
물론이 모든 것은 Cs 무거운 데이터 구조 중 하나의 관점에서는 의미가 없습니다. 배열은 포인터에 의해 첫 번째 변수에 전달됩니다.
** ** ** ** 정보 **에 대한 ** ** 감사합니다. – Joe
두 가지 이유 :
종종 당신이 많은 시간에 통과 한 포인터 역 참조 (대한 루프 긴 생각)해야합니다. 해당 주소의 값을 조회하고 싶을 때마다 역 참조를 원하지는 않습니다. 직접 액세스가 빠릅니다.
때로는 함수 내에서 전달 된 값을 수정하려고하지만 호출자에서는 수정하지 않으려합니다. 예 : 당신이 참조에 의해 전달 뭔가 위를하고 싶었다 경우
void foo(int count){
while (count>0){
printf("%d\n",count);
count--;
}
}
, 당신은 먼저 저장하는 함수 내부에 또 다른 변수를 만들 수 haev 것이다.
변수에 대한 직접 참조를 역 참조하는 성능상의 불이익은 무엇입니까? 그것은 크기가 큰 토지에 있습니까? – c00kiemonster
3 사이클 대 1 사이클이 될 수 있습니다. 쿼드 코어 머신을 프로그래밍하는 경우 누가 (주로) 신경을 씁니까? 성능 기반 (실시간 애플리케이션, 임베디드 시스템)을 구축하는 경우 큰 차이가 발생할 수 있습니다. – Phonon
프로필, 프로필, 프로필! 이 답변의 1 부는 매우 추측적이고 컴파일러 최적화를 고려하지 않습니다. – Dan
컴퓨터를 코드하는 것이 다음 사람의 코드 작성만큼 중요하지 않기 때문에. 참조를 전달하는 경우 모든 독자는 호출 된 함수가 매개 변수의 값을 변경할 수 있다고 가정해야하며 호출하기 전에 매개 변수를 검사하거나 매개 변수를 복사해야합니다.
함수 서명은 계약이며 코드를 위로 나눕니다. 따라서 코드 기반을 작성하는 참조를 전달하여 일부 영역에서 무슨 일이 벌어지고 있는지 파악할 수 있습니다. 다음 사람의 삶은 더 나빠질 것입니다. 프로그래머로서의 가장 큰 일은 다음 사람의 삶을 더 좋게 만들어야한다는 것입니다. 왜냐하면 다음 사람이 아마 당신이기 때문입니다.
좋은 답변입니다. 또한 (다른 것들 중에서) 컴파일러는 인수가 서로 별칭이 아니므로 더 나은 코드를 생성 할 수 있으므로 값 전달은 실제로 더 빠를 수 있습니다. – Nemo
"다음 사람의 삶을 악화시키는"예는 좋은 것입니다. 그것은 내가 간과 한 것입니다. – c00kiemonster
그리고 나는 항상 다음 사람이 당신의 주소를 아는 살인 광인이라고 생각했습니다. –
** 모든 ** 인수는 C에서 값으로 전달됩니다. 포인터보다 크지 않으면 복사본을 전달하는 것이 덜 효율적이지는 않습니다. –
불편한 점은 말할 것도 없습니다 :'int get_int(); void process_int_A (const int x); void process_int_B (const int * const x);'. 비교 :'void foo() {process_int_A (get_int()); }'vs'void foo() {const int result = get_int(); process_int_A (& result); }'. 모든 반환 값에 대해 명시적인 중간 저장 공간이 필요하면 킬러가됩니다. C++에서 임시 값에 바인딩 할 수있는 "실제"참조가있는 문제는 적습니다. – GManNickG