전혀 아닙니다. 문자든 문자열이든 주소는 동일하니 코드 자체에 하자 없습니다.
다만, 질문하신 분의 경우엔, 문자열의 내용을 수정하고 싶은 것이 아니라 주소를 수정하는 것이 목적이었으므로, 주소를 담고 있는 변수의 주소를 넘겨야 하기 때문에 결과적으로 이중 포인터의 모양새를 취해야 한다는 겁니다.
C언어는 모두 call by value입니다. 즉, parameter값이 모두 복사되서 넘어가는 것이죠.
포인터 값도 복사되서 넘어 갔기 때문에 복사된 포인터를 바꿔봐야 원본 포인터와는 무관한 것이죠.
그래서 beggarstart님의 예처럼 이중 포인터를 사용하는 경우가 생깁니다.
잘못알았다기 보다는 원론적으로 C는 call by value만 지원하는 것이 맞습니다.
단 pointer가 value로 가능하기 때문에, 수동으로 저수준 reference 처리를 할 수 있습니다.
C++에 와서야 call by value 외에 call by reference를 명시적으로 지원합니다.
레퍼런스란 개념을 설명하고 그의 구현방법을 설명하고 그를구현가능한데도..
궂이 표현법이 다르다는이유가 지원하지 않는게 된다니 이상하군요...
이것은 다분히 주관적인 판단이라봅니다.
어떤언어가.. "이언어는 레퍼런스 표현법은 *를붙여 선언 하는것이다" 고 하였다면
이언어는 레퍼런스를 지원하는건가요 그래도 안하는건가요?
반대로"이언어는 레퍼런스는 &붙여선언하면된다"고 하면 이건 레퍼런스지원이 되나요?
레퍼런스가 전혀 값을 복사하지 않는게 아니라.. 주소값을 복사하여 그주소값을 참조하여 쓰는것인데...
포인터(주소)를 복사한다는건 레퍼런스의 주소값을 복사하는것에 주소를참조하여 쓰는.. 전혀 어긋남이 없는데 어째서.. 레퍼런스가 아닌것인지...
그럼 C++ 이나 Java 는 주소값을 복사하지 않는다는 말인지...
그렇다면 과연 레퍼런스다 아니다 라는정확한 구분의 기준은 무엇이되는 건가요?
님 생각데로라면..
기어 오토가 나오자 옛날(스틱)자동차는 자동차가아니라 수동차가되는건가요? 오토파킹이 나왔으니 이제 기존자동차들은 자동차가 아닌건가요...
현재의 C++/Java 보다 더 표현상(레퍼런스적인) 조금더 추가된 언어가 나오면..
C++이나Java는 더이상 레퍼런스를 지원하는언어가 아닌게됩니까?
기존 Class 문법에 좀더 추가된 언어가 나온다면.. 현재의 OOP 언어들은 더이상 OOP 언어가 아닌게 되는건가요?
C++/자바가 레퍼런스 할 때는 주소값을 복사하는데 이것또한 그러면 레퍼런스가 아니겠군요.
흉내가 가능하다는 말에 이론을 제기해야 하나요? 그럴이유는 없을듯합니다.
멀쩡한 사람에게 거지라면 이론을제기하라면 아무도 이론을 제기할 사람이 없겠죠..
당연히 C는 레퍼런스가 가능합니다. 가능하니 있는것이죠..
이글타래의 애초 내용도 레퍼런스로 구현한 것이라는거죠.
그런데 레퍼런스가 아니라는 주장에대해 반론한것 뿐입니다.
"C 로는 call by reference 흉내가 불가능 하다고 말하는 분을 데려오세요."
좀 심기가 불편한 상태로 쓰신듯 보입니다만.
님이 왜 심기가 불편해야할 이유가있는지 좀 이해가 안됩니다.
만일 저와 토론을 하고 싶지 않으시면 그냥 두시면됩니다.
먼저 댓글 주신건 님이라.. 저도 답변 드린것 뿐입니다.
심기가 불편한것이 아닌데 제가 오해한 것 이라면 (님이요구한) 그런님을 데려올 필요는 없습니다.
레퍼런스가 불가여부에 흉내내기라는 일종의 논의자체를 저급기능(?)의 논의로 격하 시키려는 의도가 보이기 때문이죠
글타래를 하나 따로 여시는 게 좋겠습니다.
나중에 원하실 때 글타래 전체를 아예 지울 수 있도록요.
발제자의 글에 예시된 코드는...
pointer 가 reference 인 줄 아는, call by reference 가 저절로 되는 줄 아는, 포인터 초보가 겪는 실수입니다.
C 에서의 call by reference 는 전적으로 프로그래머의 능력에 달려있습니다.
C 컴파일러는 reference 따위 모릅니다.
이 두 가지에 대해 powersys 님도 분명히 이해하고 동의하시리라 생각하는데,
어째서 계속 사람들이 잘못 알고 있다고 말씀하시고 '흉내'라는 말에 반감을 가지시는 지 모르겠습니다.
혹시 C 가 모욕당했다고 느끼시는건가요 ?
우리가 관심있는 것은 절대적인 기준에 의해 분류될 수 있는 '다른 점'들이지,
상황에 따라 상대적으로 다르게 평가될 수 있는 '장단점'들이 아닙니다.
아 네, 그럼 딱 하나만 부탁드리겠습니다.
C 를 모욕 할 생각을 가지고 댓글다는 분은 없고,
댓글다시는 분들 중엔 C 로 수십년 째 부모님 부양하고 처자식 먹여살리는 분들도 계시니,
섣불리 감정싸움으로 몰아서 본인 무덤을 파는 일은 없었으면 합니다.
이미 말했지만,
call by address value 라는 개념의 call by reference 는 assembly 에서도 살아 숨쉬고 있습니다.
게다가,
call by address value 라는 개념의 call by reference 가 C 에서 불가능하다라고 댓글다신 분도 없습니다.
C 문법엔 call by reference 가 없습니다.
포인터를 이용하면 call by address value 로 call by reference를 프로그래머가 쉽게 흉내낼 수 있습니다.
뭔가 긍정적인 표현을 원하신다면 이렇게 말해도 되겠습니다.
C 엔 call by reference 를 하기 위해 더 배워야 할 문법이 없습니다.
pointer를 이용하면 call by reference 흉내내기 뿐 아니라, 수많은 다른 연산도 할 수 있습니다.
전 감정 싸움할 생각이 전혀 없습니다. 오히려 전 님이 감정적으로 나오시는게 아닌가 생각했습니다.
C에는 call by reference가 없는게 아닙니다.
엄연히 구현의 방법을 의미하고 구현이 되니 있다고 말해야죠
C표준에는 그런문구 자체는 나와있진 않을겁니다. 하지만 C언어(프로그래밍책이나 기타)에는 많이 나옵니다.
님이 말씀하신 문법이란게 어디까지를 말하는지 몰라도 님처럼말하면
초보자들은 call by reference가 안된다고 생각하겠죠
그래서 call by reference는 안된다고 착각하는사람이 많이 나오는겁니다.
구현할수 있는데 없다니 그렇게 말하는건 분명 이상하죠 말또한 잘못됬다고 봅니다.
(망치를 손에쥐고 호두깨는 것이 없다라고 하는격입니다.)
call by reference는 어떤 구현의 방법이지 문법자체에 존재해야 쓸수있는게 아닙니다.
(망치의 정의에는 호두깨는 말은 안나오겠지만 호두를 깰수 있는건 당연한 일이죠)
확실히 선언시 &기호 (C++의 reference)는 없습니다. 하지만 없어도 call by reference가 안되는게 아니죠.
"reference"는 reference이고 "call by reference"는 call by reference 입니다. 둘을 혼동하면 안되죠
어떻게보면 C++이 C의 call by reference 를 따라한것 이죠..
그냥 조금더 보기좋게 다듬은 정도 라고나 할까요..
오히려 부탁은 제가 드려야겠습니다. C에 call by reference가 안된다거나 없다고 말하지 마시고
레퍼런스(&)가 없다고 말씀하세요.. 그렇지 않으면 오해의 소지가 다분히 있습니다.
언어가 call-by-reference를 지원하냐 않느냐에 대해 이미 합의된 기준이 있는데, 그렇게 끊임없이 환원해서 말씀하시면 아무런 구분도 의미가 없어지는 걸요. 계속 환원하면 모든것이 오토마타고 범용 프로그래밍 언어의 표현력은 수학적으로 동치다라는 맞지만 별의미없는 얘기 밖에 안되잖아요. 누가 그거 몰라서 말 안하나요.
One aspect of C functions may be unfamiliar to programmers who are used to some other languages, particularly Fortran. In C, all function arguments are passed "by value." This means that the called function is given the values of its arguments in temporary variables rather than the originals. This leads to some different properties than are seen with "call by reference" languages like Fortran or with var parameters in Pascal, in which the called routine has access to the original argument, not a local copy.
The main distinction is that in C the called function cannot directly alter a variable in the calling function; it can only alter its private, temporary copy.
출처: C Programming Language (2nd Edition) by Brian W. Kernighan & Dennis M. Ritchie
저 밑에 제가 쓴 댓글을 보셨으면 좋겠습니다. 누가 다른 언어의 Call by reference의 구현이 주소값 복사로 이루어 진다는 것을 부정하였나요? 그런데 언어적으로 지원하지 않고 사용자가 직접 주소값을 복사하는 것을 Call by reference라고 부를 수는 없다니까요...
주관적인 판단이라고 하니 참 그렇군요. 계속 주장하시는 것처럼 주소값을 Call by value로 전달하는 것을 Call by reference 라고 부르실 수는 있겠지요. 문제는 이 세상에 powersys님 혼자 그렇게 부른다는 거지요. 프로그래밍 언어론은 들어 보셨나요? 그런식의 명명법은 프로그래밍 언어론 자체를 무시하는 처사입니다.
그리고 위의 소스에서 C에서 어떻게 된다는 것인지 모르겠군요. 제가 C99 표준까지는 잘 아는데 그 선에서는
혼자그렇게 부른다고 단정할수없죠... 그또한 님의 과장된 표현입니다.
C++이나Java또한 C와 같은원리로 Call by reference 하고 있으며 (님말씀데로 이들도 "주소값을 Call by value로 전달" 합니다. )
C++이나Java가 Call by reference 라고하면 C또한 마찬가지 라는겁니다.
하지만 엄밀히 따져보면 C++이나 Java나 C나 모두 진정한 local copy 없이 참조하는 방식이 아닙니다.
아마 local copy 없이 하는 언어가 있겠죠.. 충분히 가능할테니까요..오히려 간단한 언어일수록 그럴가능성이 높을겁니다.
이들에 비하면 모두 C++/Java/C 모두 Call by reference 가 아닌겁니다.
위 예시는 매크로함수에 의해 구현가능하고.
C++의 Call by reference 가 포인터복사로 변환되어 컴파일됩니다.. 이것이 매크로 전처리나 무슨차이일까요...
아래 제글링크 중간쯤 읽어보세요.
This leads to some different properties than are seen with "call by reference" languages like Fortran or with var parameters in Pascal, in which the called routine has access to the original argument, not a local copy.
좀 무리해서 직역하면 이런 뜻입니다:
이로 인하여 [C에서는 call by value만 지원됨을 말함 - 역주], 호출된 루틴에서 local copy 대신 원래의 인자값에 접근할 수 있는 포트란 같은 "call by reference" 언어나 파스칼의 var 파라미터와 달리 C 언어는 다른 특성을 보이게 된다.
in which 절은 "포트란이나 파스칼의 var 파라미터에서 보이는 특성"을 수식합니다. "C 언어의 특성"을 설명하는 절이 아니구요. (than are seen = "than properties that are seen"으로 해석하시면 됩니다.)
죄송합니다. 독해의 안습이네요..
그런데 포트란이나 파스칼은 실제로 local copy 없이 다르게 동작하나요? 그런의미인데.
그럼 포트란이 나 파스칼은 "call by reference" 라할수 있어도
C++/Java는 call by reference 라 하면 안되자나요...
포트란이나 파스칼의 실제 call by reference 되는부분이 정말 로컬카피없이.. inLine 같은방식이라면..
C++/Java의 call by reference도 역시..짜가라고 밖에 볼수없는데요...
C++ 언어 표준 어디에서도 Call by reference를 주소값의 전달로 구현해야 한다고 말한 적 없습니다. 다만 원래 C에서 스택을 이용해 함수인자를 전달하였으니 그 이유로 그렇게 구현 한 것이고요, 파스칼의 경우 함수인자를 복사하는 과정이 없기 때문에 재귀호출을 지원하지 못합니다. 그렇다면 C++컴파일러중 하나가 파스칼처럼 Call by reference를 구현한다면 저 위의 C는 Call by reference를 지원하지 않는다고 하실건가요?
6.5.2.2. Function calls
...
4. An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.
...
아 댓글을 보니 좀 그러네요. 프로그래밍 언어의 표현력은 구현이 가능한 것이 아니라 언어적으로 지원하는 것에 따라 결정됩니다. 구현으로 따지면 OOP, 함수형 언어 이런거 구분하는 이유가 전혀 없죠. 분명히 말씀드리지만, 프로그래밍 언어론적으로 보았을때 C가 Call by reference를 지원한다는 것은 완벽한 *개소리*입니다.
만약 C가 Call by reference를 지원한다고 하면 튜링머신이 Call by reference를 지원한다거나, Context-free grammar가 Call by reference를 지원한다거나 라고 말할 수 있습니다.
C에서 포인터를 사용해서 Call by reference를 흉내내는 것과 C++에서 참조자를 사용해서 Call by reference를 하는것이 결국 내부적으로 똑같이 작동한다 하더라도 C는 Call by reference를 지원 안한다고 하고 C++은 지원 한다고 합니다. 위키피디아 (http://en.wikipedia.org/wiki/Evaluation_strategy) 에도 분명 명시되어 있고 제가 봐왔던 책들에서도 그렇습니다. 그리고 매크로 함수 호출은 단지 문자열 치환일 뿐 이것을 Call by reference라고 하지 않습니다.
그리고 자꾸 Java에서 Call by reference를 한다고 하시는데 명백히 틀린 소리입니다.
C++에서 Call by reference를 하면...
#include <iostream>
class A
{
public:
int a;
};
void swap(A &a, A &b)
{
A temp = a;
a = b;
b = temp;
}
int main()
{
A a;
A b;
a.a = 1;
b.a = 2;
std::cout << "a.a = " << a.a << " b.a = " << b.a << std::endl;
swap(a, b);
std::cout << "a.a = " << a.a << " b.a = " << b.a << std::endl;
}
결과는
a.a = 1 b.a = 2
a.a = 2 b.a = 1
가 되서 정말로 swap함수에서 main함수의 두 지역변수가 바뀐것을 확인할 수 있습니다.
반면 Java에서는
class A
{
public int a;
}
public class Main
{
public static void swap(A a, A b)
{
A temp;
temp = a;
a = b;
b = a;
}
public static void main(String [] args)
{
A a = new A();
A b = new A();
a.a = 1;
b.a = 2;
System.out.println("a.a = " + a.a + " b.a = " + b.a);
swap(a, b);
System.out.println("a.a = " + a.a + " b.a = " + b.a);
}
}
결과는
a.a = 1 b.a = 2
a.a = 1 b.a = 2
입니다. Java에서 C++같은 swap함수를 만들 방법이 없습니다. Java에서의 함수호출은 전부 Call by value이기 때문이죠. (또는 Call by sharing이라고 하기도 합니다.) 위의 swap함수에서의 a는 main함수에서의 a를 가리키는 reference가 아니라 단지 두 reference가 같은 object를 가리키고 있을 뿐입니다. 그리고 Java에서는 object에 대한 reference만 있고 변수에 대한 reference 같은것은 없기 때문에 C처럼 Call by reference를 흉내내는것 조차 불가능합니다.
논의가 의외로 길어지는군요.
Syntax 와 Semantics 는 구별하셔야 할 것 같습니다.
C 는 call by value 를 사용하지만, pointer parameter 를 통해 call by reference 를 표현할 수 있습니다.
대신 사용자가 explicit dereference 를 해야합니다.
Call by reference 의 Semantics 를 가질 수 있다고는 하나, Syntax 는 여전히 call by value 입니다.
C++ 는 추가적으로 reference type 이라는 special pointer type 를 지원한다고 되어 있습니다.
물론 내부적으로는 implicit dereference 를 하겠지만, 어쨌든 Syntax 에서 지원하고 있습니다.
Syntax 와 Semantics 가 일치하기 때문에, 둘 다 지원한다고 얘기할 수 있습니다.
일단 적어도 제가 배운 Programming Language 책에는 이런식으로 기술되어 있습니다.
오래되긴 했지만, Dennis Ritchie 영감님이 기술하신 파트로군요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
"C가 포인터를 통해 Call by Reference 가 구현된다." 는데 동의 하신걸로 이해 하겠습니다.
저또한 문법적 표현이 Call by Reference 아님은 동의하는 바입니다.
단지 C는 "Call by Reference " 가 안된다거나.. 하는말에 동의할수 없다는 것입니다.
어떤이는 C로 "Call by Reference " 가 구현 가능하다고 하면 펄쩍뛰는 사람 있습니다.
아마 언어를 모르는 사람이 보면.. 아예 안되는걸 우기는구나 할겁니다.
마치 망치를 손에들고 호두깰수 있다면 펄쩍 뛰면서 망치는 호두 깰수 없다고 할 사람이죠...
-------------------------------------------------------------------
여담 입니다만 C++ 이 문법적표현이 &를 통한 완전한 Call by Reference 이다.
좀의문이 듭니다... 윗글 에서도 잠시 언급 했습니다만..
C 에서 매크로함수에 의해 제공된 Call by Reference 형태의 함수는 어떠신가요..
적어도 이 글타래에서 "C가 포인터를 통해 Call by Reference 가 구현된다." 는 데에 반대하시는 분은 없을 겁니다.
그리고 "구현" 안 된다고 하시는 분 없습니다.
다만 문법적으로 reference 를 지원하지 않기 때문에..
C 가 reference 를 "지원"한다고 얘기하면 안된다는 것입니다.
C 는 call by reference 를 지원하지 않으며, call by value 만 된다고 하는 건 Syntax 이야기입니다.
그걸 Semantics 로 확장 가능하다고 해서, C 가 call by reference 가 된다고 한다면...
최소한 parameter 로 address 를 전달할 수 있는 모든 언어들은, call by reference 를 지원한다는 논리가 되어 버립니다.
(위에서 bushi 님께서 이미 언급하셨군요.)
C 는 pointer 를 쓰는 함수의 prototype 만으로는 in-mode 인지 inout-mode 인지 구별할 수 없습니다.
Call by reference 의 Semantics 를 가지게끔 구현했다 하더라도...
어디까지나 문법적으로 뜯어보면 address 를 call by value 로 subprogram 에 전달하는 것이고..
(subprogram 에서는 address 를 dereference 해서 사용할 수도 있고 아닐 수도 있겠죠.)
여기에서 해석의 차이가 발생하는게 아닐까 싶습니다.
포괄적으로 보면 call by reference 의 의미를 지닐 수는 있지만...
어차피 C 의 문법적 한계상 address 를 call by value 로 넘겼다는 해석밖에 나오지 않게 됩니다.
사실상 call by reference 를 지원하기 위해서는, address 를 parameter 로 넘기는 형태로 구현할 수 밖에 없겠지만...
그걸 문법적 형태로 제공하느냐, 아니냐의 차이가 C++ 의 call by reference 가 아닐까 합니다.
설령 C 에서 Macro 로 그걸 구현했다고 하더라도..
reference 의 semantics 를 갖는 syntax 로 포함되어 표준으로 나오기 전까지는.. 동의하기 어렵겠네요.
구현된 코드/라이브러리로 언어 설계의 한계를 넘을 수는 있지만, 그렇다고 해서 언어 자체의 특성이 변하지는 않을테니까요..
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
"C로 Call by Reference 가 구현된다." 고 다른 게시판에 올리면 분명 안된다는 사람 나올겁니다..
"지원한다" 라는것이 "문법적으로 지원한다"로만, 지원이란 의미를 반드시 문법적에만 국한 해야한다는게 어디에 명시되어 있는것도 아닌데..
C언어를 설명한 책들에서도 보면 종종 "참조호출" 등등의 소개를하며 구현방법을 설명하고 있습니다. "구현가능하다" "할수있다" 는 말은 써도되고.
"지원한다"는 쓰면안된다니 이상한 논리군요.
"지원" 이란 말자체가 문법에 한정한다는 게 어디에 정의된 내용도 아닌데 이건 대체누가 정한건지..
C언어의 포인터는 "Call by Reference"도 구현할수 있도록 제공되어 있다 라는것도 틀린말은 아닐겁니다.
C언어의 포인터는 "Call by Reference"도 구현할수 있도록 지원되어 있다 라는것은 어떤가요.
"여타 기능및 Call by Reference도 구현할수 있도록 C에서 포인터란 도구를 지원했다" 는것은 어떤가요..
"Call by Reference"를 구현할수 있는 포인터를 지원했으니.. 결국"Call by Reference"도 지원한것이지 않나요?
"인텔CPU 는 리눅스도 지원한다." 이상한가요? 아마도 인텔CPU에 리눅스만을위해 무언가를 넣어두진 않았을겁니다.
하지만 당연히 사용할수 있고 지원된다고 말하는게 하등의 문제가 없지 않나요?
"지원"이란 단어가 그렇게 사용이 (국한된)엄격한 단어 였던가요..
제가볼땐 일반적으로 "지원"이란 말을 쓰면 안된다란 것이 너무 국한된 해석이라 봅니다..
정 구분을 하고 싶다면 "Call by Reference의 문법적 표현에 차이가 있다"라고 하는것이 훨씬 정확하고 오해를 덜불러 일으킬것 같네요
제가 계속해서 구현 (가능)과 지원이란 단어를 구분해서 썼습니다.
지원이란 그 목적을 위해 "공식적으로 제공"되는 기능을 뜻합니다.
C 의 parameter passing method 는 공식적으로 by-value 만 사용하며..
pointer type 역시 마찬가지 입니다.
int func(int *p);
위와 같이 parameter 로 pointer 를 전달하는 함수가 있을때..
Syntax 및 Semantics 는 모두 address 를 by-value 로 전달하는 것입니다.
by-reference 의 문법적 표현이 아닙니다.
그래서 많은 분들이 C 의 pointer 를 이용해서 by-reference 를 구현할 수 있다 하더라도..
"C 는 call by reference 를 지원 또는 사용한다" 라는 문구에는 동의하지 않는 것입니다.
음.. 입장은 확인했지만, 저나 다른 분들에게 수긍할 의사가 없으시다면 글타래가 교착상태에 빠질 것 같습니다.
개인적으로 K&R 이나 수많은 프로그래머들, PL 책들에 문제가 있다고 지적하고 싶은 뜻이 없으니까요.
적어도 C 의 parameter passing method 는 by-reference 도 사용한다라는 의미로 오해받지 않을 만한 표현을 써주셨으면 하는 뜻을 남기고, 여기서 논의를 마치고자 합니다.
감사합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
글타래의 형식과 내용이 일치해가는 재밌는 글타래가 됐는데요. powersys님의 "지원"한다의 정의는 하기나름아니냐란 주장은 근본적으로 의사소통을 저해합니다. 어떤 서술이든 해석에 따라 다르게 받아들여질 수 있는 건 사실이지만, 의사소통이 가능한 건 비슷한 문맥이 주어졌을 때 어휘나 서술을 선택하고 이해하는 범위를 상당히 좁은 범위에서 일치시킬 수 있기때문이고 따라서 그 범위 밖으로 나가는 해석을 사용할 때는 부가적인 설명을 다는 것이 당연합니다. "C가 call-by-reference를 지원한다"라는 서술에선 두가지 문맥을 지적하고 싶습니다.
1. call-by-reference를 언어의 기능으로 가지는 언어들이 이미 존재합니다. 그러므로 "call-by-reference를 지원한다"는 서술은 자연스럽게 두 언어군을 구분하는 기능을 하게되고, 이 역활에서 벗어날때는 부가적인 조건을 다는 것이 자연스럽습니다.
2. C가 언어의 기능으로 call-by-reference를 지원하지 않지만 포인터를 call-by-value로 전달하고 명시적인 참조를 통해 call-by-reference에 준하는 효과를 낼 수 있다는 사실은 C 언어를 배우면 누구나 초기에 습득해야하고, 별다른 오해의 여지가 없는 내용입니다. "C는 call-by-reference를 지원한다"는 서술을 사용해 구분의 기능을 포기하면서까지 서술할 이유가 없습니다.
의사소통이 가능하려면 1, 2를 공통 문맥으로 가지고 있을 때 "C는 call-by-reference를 지원하지 않지만 포인터를 사용해 그에 준하는 효과를 낼 수 있다"는 대부분의 경우 거부감없이 받아들일 수 있는 서술이지만 "C는 call-by-reference를 지원한다"는 참이라고 받아들이기엔 근본적으로 문제가 있는 서술입니다.
powersys님은 "난 그런 건 다 필요없고, 이것도 지원이란 단어의 광의적 의미를 생각했을 때 그 서술이 꼭 거짓이라고 할 수는 없지 않느냐"라고 하시는건데, 그렇게 문맥을 무시하고 환원시켜나가면 의사소통은 불가능합니다. "C는 call-by-reference를 지원한다"와 비슷한 서술은 "북한은 민주주의 사회이다" 정도를 들 수 있겠군요. 그 자체만으론 언어의 기본 기능을 상당히 포기하는 서술들이죠.
먼저 제가 위에 제시한 몇가지 명제들에 대해서 어디까지 인정하는지 어디서부터 부정하는지 그이유는 무엇이며 무슨 차이 인지 님들이 제시한 기준으로도 왜 그렇게 구분되어야 하는지가 모호 하다는 겁니다.
님들이 제시한 “명시적참조” 라고 하셨는데 공식적 지원 그러니까 명시적으로 “이것은 call-by-reference를 위해 제공된 기능이다”라는 것의 의미일겁니다.
C++ 함수인자로 &를 제공합니다..
그럼 C는 무엇이 있나?? 명시적으로 *를 제공하고 있습니다.. 이것은 call-by-reference를 구현가능 하게합니다.(최소한 C++에서 처럼요).
C에서 는 그런식(call-by-reference와 같은구현)의 기능을 사용하라고 포인터를 제공해 둔겁니다.
C에서도 언급된 내용을보면 궂이 C++의것과 다르다고 해두진 않았습니다. local copy없는 언어(포트란,파스칼)들과 다르다고 하죠..
오히려 C++과는 동일하죠.. 여기서 주소값이 복사되어 넘어감은 local copy 없이 구현되는 포트란이나 파스칼 같은 언어와 다르다는 것이지.
C++의 call-by-reference 방식과 다르다고 보이지 않습니다.
더 직접적으로 말해.. C++의 구체적으로 무엇이 명시적이며 그것은 어떠한 차이가 있고.. 기타 call-by-reference 라는 언어들에는 어떻게 명시적인 것들이 있는지를 구분 할 수 있어야겠죠.
&라고 말씀하신다면 C는 *라고 말씀 드릴 수 있을 것 같군요.
문법적 표현상 인자를 넘길때 C++은 값을 넘겼지만.. 함수가 주소를 참조하기 때문이다.. 라고 한다면..
C역시 값을 넘겼지만 주소를 참조하는 것처럼 보이는 함수 구현이 되죠
물론 매크로 입니다. 하지만 그것은 C++역시.. &라는 연산자가 값을 넘기는 것처럼 보이지만
실상은 주소를 넘기도록 하는 일종의 매크로(물론매크로가 아니지만)와 별반 다를 것이 없습니다...
그럼 매크로에 의한 구현은 안되고.. 매크로와 비슷한것에 의한 구현은 된다는 것인가요..이는 매우 모호합니다.
분명히 명시적으로 call-by-reference 위해 & 를 제공 했겠지만.. C역시 여전히 명시적으로call-by-reference(C++의 그것과 같은 구현을 할 수 있도록) *를 제공하고 있습니다.
예를 들어 어떤 언어가 함수 인자전달시 %를 붙이면 local copy 없이 참조에 의해 호출될 수 있도록, 함수인자 전달에 사용하는 연산자 %를 제공했습니다.
int a;
aaa( %a );
로 표현되는.. 그래도 call-by-reference 가 아닐까요..
이왕 C++을 call-by-reference 지원한다라고 부르신다면 (그렇게 폭넓게 해석하신다면..) C역시 call-by-reference 를 지원한다고 해야되지 않을까요...
(C와 C++의 차이보다 C++과 local copy없이 호출되는 언어들과의 차이가 훨씬큽니다.)
tj님이 언급하신 C++이 call-by-reference 의 굴레에 포함된다고 보신다면.. C역시 call-by-reference에 포함된다고 보는 편이 맞을 겁니다.
궂이 여기서 구분을 하고자 한다면 표현을 &로하느냐 *로하느냐 정도의 차이가 있는정도 입니다.
call-by-reference의 용어는 언어의 구분에 사용하는 것이 아니라.. 그함수의 구현방법을 구분하는데 더 유용 하겠죠..
물론 call-by-reference가 불가여부의 언어들도 구분할수 있죠
제가 "지원" 이란단어를 광의적으로 해석해야한다 라고 주장하고 하려는게 아니라..(물론광의로 해석하는 게 더 낫다고 봅니다만)
광의든 협의든 그해석의 기준을 명확히 할 필요가 있다는 것입니다.
협의라고 한들 어디까지 협의인지. 그협의의 명확한 선이 무엇인지가 모호하다는 겁니다.
마무리하면 어쨋거나 말씀데로 오해를 덜불러 일으키기 위해
'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.' 라는 표현을 쓰죠..
하지만 이에도 반박하는 이가 있다면 님들도 'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.'고 말해주시면 좋겠네요.
* c는 call-by-value만을 지원한다.
* c는 포인터를 call-by-value로 전달하고 이를 명시적으로 참조해서 call-by-reference에 준하는 효과를 낼 수 있다.
* c++은 call-by-value와 call-by-reference 모두를 지원한다.
c++은 지원하는데 c는 지원안한다는 부분에 집착하시는 것 같은데, 그런 잡기능 없는게 c의 장점인걸요. 누가 c에 call-by-reference 추가한다고 하면 거꾸로 매달고 울 때까지 때릴 일이지 c에 없다고 흥분할 일은 아닌 거 같아요.
Call-by-Reference 정의는 함수 인자를 수정할수 있어야 합니다.
여기서 함수 인자란 함수호출식에서 사용한 수식들을 의미합니다.
C 언어에서 함수 인자는 예로 다음과 같습니다:
foo(a) ; // 함수 인자는 a입니다.
boo(ptr); // 함수 인자는 ptr입니다.
coo(&a); // 함수 인자는 &a입니다.
이 함수 인자들을 수정할수 있어야 하는데, C 언어에서는 수정할 방법이 존재하지 않습니다.
이것이 C 언어에서 Call-by-Reference를 구현할수 없다고 말하는 이유입니다.
또한 C++이 Call-by-Reference를 지원하는 방법은 다음과 같습니다:
#include <iostream>
using namespace std;
void foo(int & a) {
a = 20;
}
int main(void) {
int a = 30;
cout << a << '\n';
foo(a); // 함수 인자 a가 변경됩니다. 이것을 call-by-reference라고 합니다.
cout << a << '\n';
return 0;
}
[output]
30
20
C가 "Call by reference"를 지원하지 않는다는 것과 비슷한 예가, C는 I/O를 지원하지 않습니다.
언어의 명세할 때, 이식성을 고려해서, 입출력 부분을 언어 명세에서 빼고 라이브러리로 처리하도록 결정했다고 합니다.
반대로 일부 프로그래밍 언어는 I/O를 언어의 명세에 포함하고 있습니다.
(프로그래밍 언어 시간에 파스칼이 그랬다고 배웠는데, 기억이 가물가물 하군요.)
많은 프로그래머가 C 프로그래밍에서 "Call by reference"과 같은 효과와 입출력을 멀쩡히 잘 사용하고 있습니다.
그렇다고 하더라도 언어에서 지원하다는 것과는 다른 얘기입니다.
C를 어제 배운 분도 이를 접했고, 잘 익혔다면 알 수 있는 내용입니다.
C는 call by reference를 지원하지 않습니다.
powersys님의 프로그래밍 실력은 의심치 않습니다만, 한국어 능력은...
C로 call by reference를 구현할 수 있다는 것과 C가 call by reference를 지원한다는 것은 다릅니다.
C에서 call by reference를 지원한다는 말은 '지원'이라는 단어를 자신의 입맛에 맞게 구워삶아낸 것일 뿐입니다. powersys님 같은 분들처럼 단어를 오용하는 분들이 몇몇 존재해왔지만, 그렇다고 해서 '지원'이 갖고 있는 함의는 변하지 않습니다.
언어가 만들어진 히스토리를 보아 온다고 한다면 다음과 같습니다.
초기 c++은 c언어로 재구성하여 컴파일 되도록 구현이 되어 있습니다.
또한 컴퓨터 학문은 만들어진지 얼마 안되었으며 짧은 시간동안 많은 변화가 있어 왔습니다.
결론적으로 용어의 기준이 모호함으로 인해서 이러한 댓글이 많아 보입니다.
제가 보기엔 정답이 없습니다.
c언어가 어떻게 컴파일되어서 기계언어로 바꿔서 메모리를 어떤식으로 사용 하는지는 정확하게 돌아가는지는 위에 대다수분들이 모르실꺼라고 사료됩니다.
call by reference는 call by value는 결국엔 메모리 pool에서 놀고 있는 데이터를 어떤 방식으로 끄집어서 사용 하냐의 기준으로 삼아서 봐야할것으로 보입니다만
결론적으로 c언어나 c++나 메모리의 주소를 알고 또한 사용 할수 있도록 제공되는 언어이기도 하죠. 뭐가 처음이고 뭐가 우선이 다 따지는것 보다.
정확하게 동작을 어떻게 하고 어떤 방식의 개념으로 봐야할 것 같습니다.
따라서 제가 다음과 같이 call by reference , call by value를 제가 생각 하는 정의대로 나열 하면 다음과 같습니다.
1. call by reference 는 실질 적으로 돌아가는 환경(os level) 메모리의 주소의 값(index)을 알고 있으며 그 메모리 참조한 것을 프로그램적으로 직접 변경을 할 수 있는 형태면 call by reference로 보고요.
2. call by value 는 참조한 값을 복제하여 임시 메모리 환경(자바 환경에서 heap memory 겠네요)에 쌓아서 그 값을 변경을 못하는 형태의 접근으로 보는 것.
위와 같이 정의로 하면 되지 않을까 싶네요.
음 제가 알고 있는지식이 잘못 되었는지에 대해서 알려주시거나 그러면 감사드립니다.
C 이전의 call by reference 언어들이 reference 라는 용어를 안쓰고, call by l-value와 같이 다른 말을 사용했었다면 어땠을까 하는 생각을 해 보았습니다.
그러면 reference가 그냥 reference(참조)의 의미로 받아들여 진다면, l-value를 이용해서 구현 하거나 pointer를 이용해서 구현하거나 어느 것이든 구현 방법론 상에 있어서는 call by reference(참조)라고 말을 해도 아무런 혼선은 없었을 것 같습니다.
옛 교수님들이 저술하신 책이나, 프로그래밍 언어론이나 다 그렇게 C에서의 call by reference 설명을 하실때는 reference를 reference type으로 설명하신게 아니고, reference(참조)의 의미로 설명해 주시던데요.
다른 곳에서 동일한 주제로 논쟁을 벌이다가 이미 오래전에 격론이 펼쳐졌던 글을 보게 되었네요. 몇일전에 페이스북 생활코딩 방에서도 얘기가 나왔더군요. ^^
C언어는 Java처럼 파라마터 패싱할때 Call-by-value만 지원합니다.
Java에서 메모리 모델을 생각해보세요 어떻게 동작하는지.
actual 파라미터가 formal 파라미터로 카피가 되기 때문에
value semantics가 지켜집니다.
한마디로 formal 파라미터 변수의 값에 수정이 일어나도
actual파라미터로 패싱된 변수의 값은 변하지 않습니다.
아무래도 사람들이 callee 쪽에서 객체를 수정하면
caller의 객체 상태도 바뀌다보니까 혼동하는 것 같습니다.
C언어도 마찬가지로 Java랑 똑같은 테크닉을 사용합니다.
음
포인터가 가르키고 있는 string 자체가 넘어간게 아니라
포인터의 값 (주소값) 이 복사되어 넘어 가고요.
그래서 call by reference
char* 로는 문자열을 전달할수 없습니다.
오직 char 단일문자의 참조만 전달할수 있으니
의도하신 바와 달리 a 이후는 무시되거나 컴파일 에러가 날겁니다.
char로 문자열 전달은 아랫분이 예시한것처럼 char** 이렇게 이중 포인터로 하셔야만 합니다
전혀 아닙니다. 문자든 문자열이든 주소는 동일하니
전혀 아닙니다. 문자든 문자열이든 주소는 동일하니 코드 자체에 하자 없습니다.
다만, 질문하신 분의 경우엔, 문자열의 내용을 수정하고 싶은 것이 아니라 주소를 수정하는 것이 목적이었으므로, 주소를 담고 있는 변수의 주소를 넘겨야 하기 때문에 결과적으로 이중 포인터의 모양새를 취해야 한다는 겁니다.
부연설명좀 드리자면...
char* 자료형도 메인함수에서와 같이 선언과 동시에 대입하는 경우에 한해 문자열을 넣을수는 있습니다.
단 이때 문자열은 상수가 되어 절대 변경할수 없습니다.
그래서 나중에 대입하려 할때는 이중 포인터가 필수 입니다.
낚였네요 ㅠㅠ
얼마 전 글인줄 알았는데 2010년도 글이었다니.
Written By the Black Knight of Destruction
이렇게
#include
void add(char **padd)
{
(*padd)++;
}
int main()
{
char *p="abcdefg";
printf("p=%s\n",p);
add(&p);
printf("p=%s\n",p);
}
이렇게 해보시면?
원래 C언어에는 call by reference라는건 없어요.
C언어는 모두 call by value입니다. 즉, parameter값이 모두 복사되서 넘어가는 것이죠.
포인터 값도 복사되서 넘어 갔기 때문에 복사된 포인터를 바꿔봐야 원본 포인터와는 무관한 것이죠.
그래서 beggarstart님의 예처럼 이중 포인터를 사용하는 경우가 생깁니다.
그건 다른언어도 마찬가지 입니다. 포인터값이 복사되어
잘못알고 계신겁니다. 레퍼런스 맞습니다.
그건 다른언어도 마찬가지 입니다. 포인터값이 복사되어 넘어가지않고 레퍼런스되는 언어가 있나요?
원래 레퍼런스란 것이 포인터를 복사하는겁니다.
잘못알았다기 보다는 원론적으로 C는 call by
잘못알았다기 보다는 원론적으로 C는 call by value만 지원하는 것이 맞습니다.
단 pointer가 value로 가능하기 때문에, 수동으로 저수준 reference 처리를 할 수 있습니다.
C++에 와서야 call by value 외에 call by reference를 명시적으로 지원합니다.
원론적으로 C 가 지원하는게 맞습니다. 애초 참조호출
원론적으로 C 가 지원하는게 맞습니다. 애초 참조호출 값호출이란 말도 C에서 부터 나왔고
C에서 그방법에 따라 두가지 호출법이 있음을 설명하고 있습니다.
또한 용어그자체의 의미로보나.. 용법으로보나 분명히 참조호출하고 있는것이죠..
말하자면 C++에 와서 표현법을좀더 깔끔? 하게 처리했다고나 할까요.. 내부처리는 차이가 없습니다.
이에 C++ 의 후발주자로서 일부? 사람들이 뭔가좀 특별나보이게끔 과장되게 표현하다보니
오히려 원조격을 마치 "짜가"라는식의 매도하는격 이라봅니다.
하지만 실제원리는 동일하며 그이상도 그이하도 아닙니다..
(C++이 어떤원리로 레퍼런스하는지 알아보시기 바랍니다.)
납득하기 어렵네요. C언어 이전에
납득하기 어렵네요. C언어 이전에 call by reference라는 개념이 없었다는 주장도 이상하지만
개인적으로 언어를 비교할 때는 "실제원리" 니 "내부처리" 니 하는게 중요하다고 생각하지 않습니다.
C에서 함수 포인터를 이용해 OOP를 구현할수 있지만 C언어가 OOP를 지원한다고 말하지 않듯이,
call by reference도 마찬가지가 아닐까 합니다.
http://kldp.org/node/87375 여기에 관련된 논의가 더 있습니다.
링크걸어주신내용 읽어보았습니다..링크내용역시
링크걸어주신내용 읽어보았습니다..
링크내용역시 C/C++/Java 레퍼런스의 원리자체는 동일하다는 내용으로 알아들었습니다..
또한 마지막4번째댓글님 말에 저도 동의하는바입니다. 레퍼런스개념이 목적상 나타나는 개념으로 보는게 맞다고 봅니다.
제가볼때는 표현법상 편의성에도 거의 차이가 없어보입니다. 전오히려 포인터를 쓰는게 더간단명료 하게느껴지는데..
장도리가 못을박지만 망치가 못박는것이 더낫(?)기에(동의할수없지만) 장도리는 못박는것을 지원하지 않는다고 해야할까요...
제가 레퍼런스가 C에서부터 나왔다고한건 출처(출처는 정확히 모르겠습니다)를 의미한건 아니고..
그때도 나왔었다..라는의미로 적으려는게.. 제가 좀이상하게 적었네요..
레퍼런스란 개념을 설명하고 그의 구현방법을 설명하고 그를구현가능한데도..
궂이 표현법이 다르다는이유가 지원하지 않는게 된다니 이상하군요...
이것은 다분히 주관적인 판단이라봅니다.
어떤언어가.. "이언어는 레퍼런스 표현법은 *를붙여 선언 하는것이다" 고 하였다면
이언어는 레퍼런스를 지원하는건가요 그래도 안하는건가요?
반대로"이언어는 레퍼런스는 &붙여선언하면된다"고 하면 이건 레퍼런스지원이 되나요?
레퍼런스가 전혀 값을 복사하지 않는게 아니라.. 주소값을 복사하여 그주소값을 참조하여 쓰는것인데...
포인터(주소)를 복사한다는건 레퍼런스의 주소값을 복사하는것에 주소를참조하여 쓰는.. 전혀 어긋남이 없는데 어째서.. 레퍼런스가 아닌것인지...
그럼 C++ 이나 Java 는 주소값을 복사하지 않는다는 말인지...
그렇다면 과연 레퍼런스다 아니다 라는정확한 구분의 기준은 무엇이되는 건가요?
님 생각데로라면..
기어 오토가 나오자 옛날(스틱)자동차는 자동차가아니라 수동차가되는건가요? 오토파킹이 나왔으니 이제 기존자동차들은 자동차가 아닌건가요...
현재의 C++/Java 보다 더 표현상(레퍼런스적인) 조금더 추가된 언어가 나오면..
C++이나Java는 더이상 레퍼런스를 지원하는언어가 아닌게됩니까?
기존 Class 문법에 좀더 추가된 언어가 나온다면.. 현재의 OOP 언어들은 더이상 OOP 언어가 아닌게 되는건가요?
그렇게 따지면... assembly 가 call by
그렇게 따지면...
assembly 가 call by reference 를 지원한다고 말씀하셔도 됩니다...
어셈플리도 물론 레퍼런스구현이 가능합니다. 지원이란
어셈플리도 물론 레퍼런스구현이 가능합니다.
지원이란 말자체가 모호합니다만 이말에대한답변은 윗에댓글다신님 댓글에다 적은내용이 될걸로 봅니다.
구현가능하다는 말에 이론을 제기한 분은 없다는 것을
구현(흉내)가능하다는 말에 이론을 제기한 분은 없다는 것을 이해하셨다면,
서로가 서로를 이해한 셈이니 소모적인 논쟁은 이 정도에 그치는 것이 어떨까요 ?
소모적이라 생각하진 않습니다.감정싸움이 아닌
소모적이라 생각하진 않습니다.
감정싸움이 아닌 논리적인 토론을하면 더정확한정보를 얻을수있겠죠.
-----------------
ps: 흉내란 남이 하는 말이나 짓을 그대로 옮겨서 하는것을 말하죠..
아마도 흉내는 C++이나Java 가 낸듯합니다. 먼저 있었던것이 나중의것을 흉내낼수가 없죠.
또한 흉내는 겉만따라하고 실상은다른 의미인데.. 실제구현은 동일하고 표현법이다른건 흉내가 아니라고봐야죠
논리적으로 C 문법엔 call by value 밖에
논리적으로 C 문법엔 call by value 밖에 없습니다.
그리고, call by reference 흉내가 가능하다는 말에 이론을 제기한 분은 없습니다.
이 글타래를 계속 이어가고 싶다면,
C 문법에 call by reference 가 있다고 말하시던가,
C 로는 call by reference 흉내가 불가능하다고 말하는 분을 데려오세요.
일단 C문법에 call by value 밖에
일단 C문법에 call by value 밖에 없다는근거는 어디서 나온건가요?
C++/자바가 레퍼런스 할 때는 주소값을 복사하는데 이것또한 그러면 레퍼런스가 아니겠군요.
흉내가 가능하다는 말에 이론을 제기해야 하나요? 그럴이유는 없을듯합니다.
멀쩡한 사람에게 거지라면 이론을제기하라면 아무도 이론을 제기할 사람이 없겠죠..
당연히 C는 레퍼런스가 가능합니다. 가능하니 있는것이죠..
이글타래의 애초 내용도 레퍼런스로 구현한 것이라는거죠.
그런데 레퍼런스가 아니라는 주장에대해 반론한것 뿐입니다.
"C 로는 call by reference 흉내가 불가능 하다고 말하는 분을 데려오세요."
좀 심기가 불편한 상태로 쓰신듯 보입니다만.
님이 왜 심기가 불편해야할 이유가있는지 좀 이해가 안됩니다.
만일 저와 토론을 하고 싶지 않으시면 그냥 두시면됩니다.
먼저 댓글 주신건 님이라.. 저도 답변 드린것 뿐입니다.
심기가 불편한것이 아닌데 제가 오해한 것 이라면 (님이요구한) 그런님을 데려올 필요는 없습니다.
레퍼런스가 불가여부에 흉내내기라는 일종의 논의자체를 저급기능(?)의 논의로 격하 시키려는 의도가 보이기 때문이죠
글타래를 하나 따로 여시는 게 좋겠습니다. 나중에
글타래를 하나 따로 여시는 게 좋겠습니다.
나중에 원하실 때 글타래 전체를 아예 지울 수 있도록요.
발제자의 글에 예시된 코드는...
pointer 가 reference 인 줄 아는, call by reference 가 저절로 되는 줄 아는, 포인터 초보가 겪는 실수입니다.
C 에서의 call by reference 는 전적으로 프로그래머의 능력에 달려있습니다.
C 컴파일러는 reference 따위 모릅니다.
이 두 가지에 대해 powersys 님도 분명히 이해하고 동의하시리라 생각하는데,
어째서 계속 사람들이 잘못 알고 있다고 말씀하시고 '흉내'라는 말에 반감을 가지시는 지 모르겠습니다.
혹시 C 가 모욕당했다고 느끼시는건가요 ?
우리가 관심있는 것은 절대적인 기준에 의해 분류될 수 있는 '다른 점'들이지,
상황에 따라 상대적으로 다르게 평가될 수 있는 '장단점'들이 아닙니다.
Call by reference 가 원래부터 C에서
Call by reference 가 원래부터 C에서 일반적으로 구현된다는 데는 동의 하신걸로 봅니다.
궂이 망치가 호두를깰수 있다고 명시하지 않아도.. 당연히 호두를 깰수 있는것처럼요..
호두를 깨는 행동은 전적으로 사용자의 사용 방법이며.. Call by reference 또한 말 그자체로 호출자체의(행동,구현)방법을 의미한다고 봐야죠.
또한 당연히 장단점이 존재하며, C든 C++/Java든 각구현방법또한 결코장점 으로만볼수 없는일이죠...
네.. 아마도 C가 모욕을 당했나봅니다.^^
C++이나 Java가 C보다 뭔가 대단한 차별화된 것이 있다고 주장하고 싶은건 이해하나..
아무리 그래도 되는걸 안된다고 할수 없는 거니까요..C++/Java도 허세 보다는 내실을 찾는게 옳아 보입니다.
아 네, 그럼 딱 하나만 부탁드리겠습니다. C 를
아 네, 그럼 딱 하나만 부탁드리겠습니다.
C 를 모욕 할 생각을 가지고 댓글다는 분은 없고,
댓글다시는 분들 중엔 C 로 수십년 째 부모님 부양하고 처자식 먹여살리는 분들도 계시니,
섣불리 감정싸움으로 몰아서 본인 무덤을 파는 일은 없었으면 합니다.
이미 말했지만,
call by address value 라는 개념의 call by reference 는 assembly 에서도 살아 숨쉬고 있습니다.
게다가,
call by address value 라는 개념의 call by reference 가 C 에서 불가능하다라고 댓글다신 분도 없습니다.
C 문법엔 call by reference 가 없습니다.
포인터를 이용하면 call by address value 로 call by reference를 프로그래머가 쉽게 흉내낼 수 있습니다.
뭔가 긍정적인 표현을 원하신다면 이렇게 말해도 되겠습니다.
C 엔 call by reference 를 하기 위해 더 배워야 할 문법이 없습니다.
pointer를 이용하면 call by reference 흉내내기 뿐 아니라, 수많은 다른 연산도 할 수 있습니다.
이제 좀 낫습니까 ?
전 감정 싸움할 생각이 전혀 없습니다. 오히려 전
전 감정 싸움할 생각이 전혀 없습니다. 오히려 전 님이 감정적으로 나오시는게 아닌가 생각했습니다.
C에는 call by reference가 없는게 아닙니다.
엄연히 구현의 방법을 의미하고 구현이 되니 있다고 말해야죠
C표준에는 그런문구 자체는 나와있진 않을겁니다. 하지만 C언어(프로그래밍책이나 기타)에는 많이 나옵니다.
님이 말씀하신 문법이란게 어디까지를 말하는지 몰라도 님처럼말하면
초보자들은 call by reference가 안된다고 생각하겠죠
그래서 call by reference는 안된다고 착각하는사람이 많이 나오는겁니다.
구현할수 있는데 없다니 그렇게 말하는건 분명 이상하죠 말또한 잘못됬다고 봅니다.
(망치를 손에쥐고 호두깨는 것이 없다라고 하는격입니다.)
call by reference는 어떤 구현의 방법이지 문법자체에 존재해야 쓸수있는게 아닙니다.
(망치의 정의에는 호두깨는 말은 안나오겠지만 호두를 깰수 있는건 당연한 일이죠)
확실히 선언시 &기호 (C++의 reference)는 없습니다. 하지만 없어도 call by reference가 안되는게 아니죠.
"reference"는 reference이고 "call by reference"는 call by reference 입니다. 둘을 혼동하면 안되죠
어떻게보면 C++이 C의 call by reference 를 따라한것 이죠..
그냥 조금더 보기좋게 다듬은 정도 라고나 할까요..
오히려 부탁은 제가 드려야겠습니다. C에 call by reference가 안된다거나 없다고 말하지 마시고
레퍼런스(&)가 없다고 말씀하세요.. 그렇지 않으면 오해의 소지가 다분히 있습니다.
언어가 call-by-reference를 지원하냐
언어가 call-by-reference를 지원하냐 않느냐에 대해 이미 합의된 기준이 있는데, 그렇게 끊임없이 환원해서 말씀하시면 아무런 구분도 의미가 없어지는 걸요. 계속 환원하면 모든것이 오토마타고 범용 프로그래밍 언어의 표현력은 수학적으로 동치다라는 맞지만 별의미없는 얘기 밖에 안되잖아요. 누가 그거 몰라서 말 안하나요.
C는 call-by-value만 지원합니다. 앞뒤에 뭐 더 달 것도 없어요.
죄송합니다만. 어디에서 합의되었고, 어디에 나오는
죄송합니다만. 어디에서 합의되었고, 어디에 나오는 내용인가요?
...
One aspect of C functions may be unfamiliar to programmers who are used to some other languages, particularly Fortran. In C, all function arguments are passed "by value." This means that the called function is given the values of its arguments in temporary variables rather than the originals. This leads to some different properties than are seen with "call by reference" languages like Fortran or with var parameters in Pascal, in which the called routine has access to the original argument, not a local copy.
The main distinction is that in C the called function cannot directly alter a variable in the calling function; it can only alter its private, temporary copy.
출처: C Programming Language (2nd Edition) by Brian W. Kernighan & Dennis M. Ritchie
* 아마존에서 내용 검색해서 보고 친 거라서 오타가 있을 수 있습니다.
이게 call by reference가 안된다는게
이게 call by reference가 안된다는게 아니죠...
값을 복사하는건 맞죠... (주소)값을 복사하죠.. 원래 콜바이 레퍼런스 한다는 다른언어도 (주소)값을 복사합니다.
(주소)값을 복사하여 "call by reference" languages 들에서 보이는 특성이 있다고 되어 있는데요.
"call by reference"가 된다는 말이자나요..
모든함수의 아규먼트는 값에 의존한다는 말에 너무 의식하는거 같은데요.. C++이나Java 도 아규먼트가 값에 의존하는거는 마찬가지거든요...
오히려 이글이 "call by reference"가 지원됨을 분명히 말하고 있는데요...
아 답이 없군요...
저 밑에 제가 쓴 댓글을 보셨으면 좋겠습니다. 누가 다른 언어의 Call by reference의 구현이 주소값 복사로 이루어 진다는 것을 부정하였나요? 그런데 언어적으로 지원하지 않고 사용자가 직접 주소값을 복사하는 것을 Call by reference라고 부를 수는 없다니까요...
부를수 없는게 아니죠.. 그건 님의
부를수 없는게 아니죠.. 그건 님의 주관적판단입니다.
표현법에서 value 를 대입해서.. 함수의 내부에서.. 주소값을 참조해서 사용했다해서 이것은
Call by reference 이고.. 아규먼트로 포인터를 대입했다해서..(사용자가 직접주소값을 복사했다고해서)
아니다라고 하는건 말이안됩니다.
자 그럼 C에서도.. value를 대입했는데.. 주소값을 참조해서 사용하게되면.. Call by reference 라할수 있는건가요?
이것또한 C에서 됩니다.
int a = 0;
aaa( a );
printf( "%d", a );
로 a 값이 바뀌어 출력될수 있습니다. 자 이러면 Call by reference를 인정하시겠습니까?
int a = 0; aaa( a ); printf(
int a = 0;
aaa( a );
printf( "%d", a );
에서 왜 a값이 바뀌어서 출력되나요? (설마 aaa가 #define으로 정의된 매크로는 아니겠죠?)
=_=
주관적인 판단이라고 하니 참 그렇군요. 계속 주장하시는 것처럼 주소값을 Call by value로 전달하는 것을 Call by reference 라고 부르실 수는 있겠지요. 문제는 이 세상에 powersys님 혼자 그렇게 부른다는 거지요. 프로그래밍 언어론은 들어 보셨나요? 그런식의 명명법은 프로그래밍 언어론 자체를 무시하는 처사입니다.
그리고 위의 소스에서 C에서 어떻게 된다는 것인지 모르겠군요. 제가 C99 표준까지는 잘 아는데 그 선에서는
int a = 0;
aaa( a );
printf( "%d", a );
에서 a값이 바뀌는게 가능하다는 말은 처음들어보네요.
혼자그렇게 부른다고 단정할수없죠... 그또한 님의
혼자그렇게 부른다고 단정할수없죠... 그또한 님의 과장된 표현입니다.
C++이나Java또한 C와 같은원리로 Call by reference 하고 있으며 (님말씀데로 이들도 "주소값을 Call by value로 전달" 합니다. )
C++이나Java가 Call by reference 라고하면 C또한 마찬가지 라는겁니다.
하지만 엄밀히 따져보면 C++이나 Java나 C나 모두 진정한 local copy 없이 참조하는 방식이 아닙니다.
아마 local copy 없이 하는 언어가 있겠죠.. 충분히 가능할테니까요..오히려 간단한 언어일수록 그럴가능성이 높을겁니다.
이들에 비하면 모두 C++/Java/C 모두 Call by reference 가 아닌겁니다.
위 예시는 매크로함수에 의해 구현가능하고.
C++의 Call by reference 가 포인터복사로 변환되어 컴파일됩니다.. 이것이 매크로 전처리나 무슨차이일까요...
아래 제글링크 중간쯤 읽어보세요.
...
죄송하지만 영문독해능력을 좀 더 키우시면 앞으로 커리어에 도움이 되실 것 같습니다.
This leads to some different properties than are seen with "call by reference" languages like Fortran or with var parameters in Pascal, in which the called routine has access to the original argument, not a local copy.
좀 무리해서 직역하면 이런 뜻입니다:
이로 인하여 [C에서는 call by value만 지원됨을 말함 - 역주], 호출된 루틴에서 local copy 대신 원래의 인자값에 접근할 수 있는 포트란 같은 "call by reference" 언어나 파스칼의 var 파라미터와 달리 C 언어는 다른 특성을 보이게 된다.
in which 절은 "포트란이나 파스칼의 var 파라미터에서 보이는 특성"을 수식합니다. "C 언어의 특성"을 설명하는 절이 아니구요. (than are seen = "than properties that are seen"으로 해석하시면 됩니다.)
죄송합니다. 독해의 안습이네요..그런데 포트란이나
죄송합니다. 독해의 안습이네요..
그런데 포트란이나 파스칼은 실제로 local copy 없이 다르게 동작하나요? 그런의미인데.
그럼 포트란이 나 파스칼은 "call by reference" 라할수 있어도
C++/Java는 call by reference 라 하면 안되자나요...
포트란이나 파스칼의 실제 call by reference 되는부분이 정말 로컬카피없이.. inLine 같은방식이라면..
C++/Java의 call by reference도 역시..짜가라고 밖에 볼수없는데요...
파스칼의 예를 들이시니 말하겠습니다.
C++ 언어 표준 어디에서도 Call by reference를 주소값의 전달로 구현해야 한다고 말한 적 없습니다. 다만 원래 C에서 스택을 이용해 함수인자를 전달하였으니 그 이유로 그렇게 구현 한 것이고요, 파스칼의 경우 함수인자를 복사하는 과정이 없기 때문에 재귀호출을 지원하지 못합니다. 그렇다면 C++컴파일러중 하나가 파스칼처럼 Call by reference를 구현한다면 저 위의 C는 Call by reference를 지원하지 않는다고 하실건가요?
물론 구현으로 보면 그렇지요.
하지만 프로그램 언어의 표현력으로 보았을때 C는 Call by reference를 지원하지 않는다고 보는 것이 맞습니다.
** -> call by reference * -> call by value in parameter>
이 경우가 인자(퍄라미터)일 때만 해당되는거죵?
아이고 C언어가 call by reference를
아이고 C언어가 call by reference를 지원한다고 하는 분이
아직도 계신가요. ㅠㅠ
네 물론있죠...알고보면 실상을 많은사람들이
네 물론있죠...
알고보면 실상을 많은사람들이 엉뚱하게 잘못알고 있는경우가 있죠..
레퍼런스에 대한
레퍼런스에 대한 내용입니다.
http://winapi.co.kr/clec/cpp2/15-4-5.png
(이미지인데 확대해서..)
...
이건 C++의 reference type 이야기이지 call by reference 이야기가 아닌데요...
(물론 C++에서 call by reference를 reference type을 이용해서 구현하므로 관련이 없는 건 아닙니다만...)
ISO/IEC 9899에, 6.5.2.2.
ISO/IEC 9899에,
6.5.2.2. Function calls
...
4. An argument may be an expression of any object type. In preparing for the call to a function, the arguments are evaluated, and each parameter is assigned the value of the corresponding argument.
...
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
...
아 댓글을 보니 좀 그러네요. 프로그래밍 언어의 표현력은 구현이 가능한 것이 아니라 언어적으로 지원하는 것에 따라 결정됩니다. 구현으로 따지면 OOP, 함수형 언어 이런거 구분하는 이유가 전혀 없죠. 분명히 말씀드리지만, 프로그래밍 언어론적으로 보았을때 C가 Call by reference를 지원한다는 것은 완벽한 *개소리*입니다.
만약 C가 Call by reference를 지원한다고 하면 튜링머신이 Call by reference를 지원한다거나, Context-free grammar가 Call by reference를 지원한다거나 라고 말할 수 있습니다.
powersys님께... C에서 포인터를 사용해서
powersys님께...
C에서 포인터를 사용해서 Call by reference를 흉내내는 것과 C++에서 참조자를 사용해서 Call by reference를 하는것이 결국 내부적으로 똑같이 작동한다 하더라도 C는 Call by reference를 지원 안한다고 하고 C++은 지원 한다고 합니다. 위키피디아 (http://en.wikipedia.org/wiki/Evaluation_strategy) 에도 분명 명시되어 있고 제가 봐왔던 책들에서도 그렇습니다. 그리고 매크로 함수 호출은 단지 문자열 치환일 뿐 이것을 Call by reference라고 하지 않습니다.
그리고 자꾸 Java에서 Call by reference를 한다고 하시는데 명백히 틀린 소리입니다.
C++에서 Call by reference를 하면...
결과는
가 되서 정말로 swap함수에서 main함수의 두 지역변수가 바뀐것을 확인할 수 있습니다.
반면 Java에서는
결과는
입니다. Java에서 C++같은 swap함수를 만들 방법이 없습니다. Java에서의 함수호출은 전부 Call by value이기 때문이죠. (또는 Call by sharing이라고 하기도 합니다.) 위의 swap함수에서의 a는 main함수에서의 a를 가리키는 reference가 아니라 단지 두 reference가 같은 object를 가리키고 있을 뿐입니다. 그리고 Java에서는 object에 대한 reference만 있고 변수에 대한 reference 같은것은 없기 때문에 C처럼 Call by reference를 흉내내는것 조차 불가능합니다.
위키에 나오는내용을 그런 정의된내용으로 볼수는 없죠.
위키에 나오는 내용을 그런 정의된 내용으로 볼수는 없죠. 누가 위키 수정하면 하루아침에 바뀔수도 있는건가요..
그리고 자바는 기본형으로 하니 그렇죠. 객체의 인스턴스를 매개변수로 너기면 스왑 됩니다.
제가 억지주장을 펼친다고 생각 하시겠지만 제가볼땐 님들도 마찬가지 입니다.
차라리 님이 call by reference 의 명확한 기준을 제시하며 이것이 아니면 안된다 식으로 내세우는게 설득력있어 보입니다.
java 코드 부탁드립니다.
위의 쓰레드를 따라가다, 위에 매크로 함수 언급과 독해 언급 부분에 약간 당황해서,
Java 쪽은 어떤 의도를 의미하시는 건지 함부로 생각할 수가 없네요.
검색해보니 많이 나오던데 하나 링크 해드립니다. 소스
검색해보니 많이 나오던데 하나 링크 해드립니다. 소스 예제까지 있네요.
http://blog.naver.com/wono77/140096006175
전 위의 swap 예제를 말하는 겁니다.
전 위의 swap 예제를 말하는 겁니다.
링크내 소스는 위의 예제를 설명할수 없습니다.
더욱이 글쓴이가 자신이 기존에 알고 있는 call by reference 개념으로 설명하려고 하지만, java spec에서는 저 상황을 글쓴이의 이야기대로 설명하지 않습니다.
(자세한 부분은 java spec의 type 설명 부분을 참고하시면 될것 같습니다. ~ http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.1 )
다른 분의 생각을 끌어 들이면 더 모호해 진다고 생각합니다. 그래서 전 powersys 님이 생각하는 예제를 부탁드리는 겁니다.
음 ..
논의가 의외로 길어지는군요.
Syntax 와 Semantics 는 구별하셔야 할 것 같습니다.
C 는 call by value 를 사용하지만, pointer parameter 를 통해 call by reference 를 표현할 수 있습니다.
대신 사용자가 explicit dereference 를 해야합니다.
Call by reference 의 Semantics 를 가질 수 있다고는 하나, Syntax 는 여전히 call by value 입니다.
C++ 는 추가적으로 reference type 이라는 special pointer type 를 지원한다고 되어 있습니다.
물론 내부적으로는 implicit dereference 를 하겠지만, 어쨌든 Syntax 에서 지원하고 있습니다.
Syntax 와 Semantics 가 일치하기 때문에, 둘 다 지원한다고 얘기할 수 있습니다.
일단 적어도 제가 배운 Programming Language 책에는 이런식으로 기술되어 있습니다.
오래되긴 했지만, Dennis Ritchie 영감님이 기술하신 파트로군요.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
"C가 포인터를 통해 Call by Reference
"C가 포인터를 통해 Call by Reference 가 구현된다." 는데 동의 하신걸로 이해 하겠습니다.
저또한 문법적 표현이 Call by Reference 아님은 동의하는 바입니다.
단지 C는 "Call by Reference " 가 안된다거나.. 하는말에 동의할수 없다는 것입니다.
어떤이는 C로 "Call by Reference " 가 구현 가능하다고 하면 펄쩍뛰는 사람 있습니다.
아마 언어를 모르는 사람이 보면.. 아예 안되는걸 우기는구나 할겁니다.
마치 망치를 손에들고 호두깰수 있다면 펄쩍 뛰면서 망치는 호두 깰수 없다고 할 사람이죠...
-------------------------------------------------------------------
여담 입니다만 C++ 이 문법적표현이 &를 통한 완전한 Call by Reference 이다.
좀의문이 듭니다... 윗글 에서도 잠시 언급 했습니다만..
C 에서 매크로함수에 의해 제공된 Call by Reference 형태의 함수는 어떠신가요..
이도 겉보기엔 완전한 Call by Reference 처럼 보이는데 말이죠..
정의에 혼돈이 존재하는것 같습니다.
함수 호출시 파라미터 패싱 방식과 특정 자료형(C언어에서는 pointer, Java에서는 Object)의 성격이 조합되어 이야기하고 있는데, 여기서는
함수 호출시 파라미터 패싱 방식에 대해서만 이야기 해야 하지 않을까 생각합니다.
-- 덧붙이는글 --
pointer든 object든 언어가 파라미터 패싱방식이 call by value만 제공한다면 call by reference는 구현될 수 없습니다.
음 ..
적어도 이 글타래에서 "C가 포인터를 통해 Call by Reference 가 구현된다." 는 데에 반대하시는 분은 없을 겁니다.
그리고 "구현" 안 된다고 하시는 분 없습니다.
다만 문법적으로 reference 를 지원하지 않기 때문에..
C 가 reference 를 "지원"한다고 얘기하면 안된다는 것입니다.
C 는 call by reference 를 지원하지 않으며, call by value 만 된다고 하는 건 Syntax 이야기입니다.
그걸 Semantics 로 확장 가능하다고 해서, C 가 call by reference 가 된다고 한다면...
최소한 parameter 로 address 를 전달할 수 있는 모든 언어들은, call by reference 를 지원한다는 논리가 되어 버립니다.
(위에서 bushi 님께서 이미 언급하셨군요.)
C 는 pointer 를 쓰는 함수의 prototype 만으로는 in-mode 인지 inout-mode 인지 구별할 수 없습니다.
Call by reference 의 Semantics 를 가지게끔 구현했다 하더라도...
어디까지나 문법적으로 뜯어보면 address 를 call by value 로 subprogram 에 전달하는 것이고..
(subprogram 에서는 address 를 dereference 해서 사용할 수도 있고 아닐 수도 있겠죠.)
여기에서 해석의 차이가 발생하는게 아닐까 싶습니다.
포괄적으로 보면 call by reference 의 의미를 지닐 수는 있지만...
어차피 C 의 문법적 한계상 address 를 call by value 로 넘겼다는 해석밖에 나오지 않게 됩니다.
사실상 call by reference 를 지원하기 위해서는, address 를 parameter 로 넘기는 형태로 구현할 수 밖에 없겠지만...
그걸 문법적 형태로 제공하느냐, 아니냐의 차이가 C++ 의 call by reference 가 아닐까 합니다.
설령 C 에서 Macro 로 그걸 구현했다고 하더라도..
reference 의 semantics 를 갖는 syntax 로 포함되어 표준으로 나오기 전까지는.. 동의하기 어렵겠네요.
구현된 코드/라이브러리로 언어 설계의 한계를 넘을 수는 있지만, 그렇다고 해서 언어 자체의 특성이 변하지는 않을테니까요..
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
아마 이글타래를 읽어본 사람이라면 이제 반대
아마 이글타래를 읽어본 사람이라면 이제 반대 안할겁니다.
하지만..
"C로 Call by Reference 가 구현된다." 고 다른 게시판에 올리면 분명 안된다는 사람 나올겁니다..
"지원한다" 라는것이 "문법적으로 지원한다"로만, 지원이란 의미를 반드시 문법적에만 국한 해야한다는게 어디에 명시되어 있는것도 아닌데..
C언어를 설명한 책들에서도 보면 종종 "참조호출" 등등의 소개를하며 구현방법을 설명하고 있습니다. "구현가능하다" "할수있다" 는 말은 써도되고.
"지원한다"는 쓰면안된다니 이상한 논리군요.
"지원" 이란 말자체가 문법에 한정한다는 게 어디에 정의된 내용도 아닌데 이건 대체누가 정한건지..
C언어의 포인터는 "Call by Reference"도 구현할수 있도록 제공되어 있다 라는것도 틀린말은 아닐겁니다.
C언어의 포인터는 "Call by Reference"도 구현할수 있도록 지원되어 있다 라는것은 어떤가요.
"여타 기능및 Call by Reference도 구현할수 있도록 C에서 포인터란 도구를 지원했다" 는것은 어떤가요..
"Call by Reference"를 구현할수 있는 포인터를 지원했으니.. 결국"Call by Reference"도 지원한것이지 않나요?
"인텔CPU 는 리눅스도 지원한다." 이상한가요? 아마도 인텔CPU에 리눅스만을위해 무언가를 넣어두진 않았을겁니다.
하지만 당연히 사용할수 있고 지원된다고 말하는게 하등의 문제가 없지 않나요?
"지원"이란 단어가 그렇게 사용이 (국한된)엄격한 단어 였던가요..
제가볼땐 일반적으로 "지원"이란 말을 쓰면 안된다란 것이 너무 국한된 해석이라 봅니다..
정 구분을 하고 싶다면 "Call by Reference의 문법적 표현에 차이가 있다"라고 하는것이 훨씬 정확하고 오해를 덜불러 일으킬것 같네요
...
이건 의미 공유라 말씀하신다면, 저는 이 전체 글을 읽은 후에,
'C언어는 call by reference를 지원한다'
이 문장의 의미가 행여
'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.'
라는 의도로 이야기 할지라도, 생략된 말없이는 문장을 절대로 쓰면 안되겠다는 생각이 들었습니다.
괜히 대부분의 글타래를 역은 분들이 powersys 님의 의도를 이해하지 못한게 아니라 생각합니다.
특히, 새로 진입하시는 분들에게 오해 불러 일으킬 수 있을 것 같습니다.
다른 분들의 생각도 궁금하네요.
음 ..
제가 계속해서 구현 (가능)과 지원이란 단어를 구분해서 썼습니다.
지원이란 그 목적을 위해 "공식적으로 제공"되는 기능을 뜻합니다.
C 의 parameter passing method 는 공식적으로 by-value 만 사용하며..
pointer type 역시 마찬가지 입니다.
int func(int *p);
위와 같이 parameter 로 pointer 를 전달하는 함수가 있을때..
Syntax 및 Semantics 는 모두 address 를 by-value 로 전달하는 것입니다.
by-reference 의 문법적 표현이 아닙니다.
그래서 많은 분들이 C 의 pointer 를 이용해서 by-reference 를 구현할 수 있다 하더라도..
"C 는 call by reference 를 지원 또는 사용한다" 라는 문구에는 동의하지 않는 것입니다.
음.. 입장은 확인했지만, 저나 다른 분들에게 수긍할 의사가 없으시다면 글타래가 교착상태에 빠질 것 같습니다.
개인적으로 K&R 이나 수많은 프로그래머들, PL 책들에 문제가 있다고 지적하고 싶은 뜻이 없으니까요.
적어도 C 의 parameter passing method 는 by-reference 도 사용한다라는 의미로 오해받지 않을 만한 표현을 써주셨으면 하는 뜻을 남기고, 여기서 논의를 마치고자 합니다.
감사합니다.
되면 한다! / feel no sorrow, feel no pain, feel no hurt, there's nothing gained.. only love will then remain.. 『 Mizz 』
글타래의 형식과 내용이 일치해가는 재밌는 글타래가
글타래의 형식과 내용이 일치해가는 재밌는 글타래가 됐는데요. powersys님의 "지원"한다의 정의는 하기나름아니냐란 주장은 근본적으로 의사소통을 저해합니다. 어떤 서술이든 해석에 따라 다르게 받아들여질 수 있는 건 사실이지만, 의사소통이 가능한 건 비슷한 문맥이 주어졌을 때 어휘나 서술을 선택하고 이해하는 범위를 상당히 좁은 범위에서 일치시킬 수 있기때문이고 따라서 그 범위 밖으로 나가는 해석을 사용할 때는 부가적인 설명을 다는 것이 당연합니다. "C가 call-by-reference를 지원한다"라는 서술에선 두가지 문맥을 지적하고 싶습니다.
1. call-by-reference를 언어의 기능으로 가지는 언어들이 이미 존재합니다. 그러므로 "call-by-reference를 지원한다"는 서술은 자연스럽게 두 언어군을 구분하는 기능을 하게되고, 이 역활에서 벗어날때는 부가적인 조건을 다는 것이 자연스럽습니다.
2. C가 언어의 기능으로 call-by-reference를 지원하지 않지만 포인터를 call-by-value로 전달하고 명시적인 참조를 통해 call-by-reference에 준하는 효과를 낼 수 있다는 사실은 C 언어를 배우면 누구나 초기에 습득해야하고, 별다른 오해의 여지가 없는 내용입니다. "C는 call-by-reference를 지원한다"는 서술을 사용해 구분의 기능을 포기하면서까지 서술할 이유가 없습니다.
의사소통이 가능하려면 1, 2를 공통 문맥으로 가지고 있을 때 "C는 call-by-reference를 지원하지 않지만 포인터를 사용해 그에 준하는 효과를 낼 수 있다"는 대부분의 경우 거부감없이 받아들일 수 있는 서술이지만 "C는 call-by-reference를 지원한다"는 참이라고 받아들이기엔 근본적으로 문제가 있는 서술입니다.
powersys님은 "난 그런 건 다 필요없고, 이것도 지원이란 단어의 광의적 의미를 생각했을 때 그 서술이 꼭 거짓이라고 할 수는 없지 않느냐"라고 하시는건데, 그렇게 문맥을 무시하고 환원시켜나가면 의사소통은 불가능합니다. "C는 call-by-reference를 지원한다"와 비슷한 서술은 "북한은 민주주의 사회이다" 정도를 들 수 있겠군요. 그 자체만으론 언어의 기본 기능을 상당히 포기하는 서술들이죠.
건필하시라는 말밖엔 드릴 말씀이 없근영;;; 건필하시라능;;;;;;;
위 ymir 님과 비슷한 말씀으로 두분 공통된
위 ymir 님과 비슷한 말씀으로 두분 공통된 답변으로 여기 달겠습니다.
저도 몇가지 말씀 드리고 여기서 마무리하고자 합니다.
먼저 제가 위에 제시한 몇가지 명제들에 대해서 어디까지 인정하는지 어디서부터 부정하는지 그이유는 무엇이며 무슨 차이 인지 님들이 제시한 기준으로도 왜 그렇게 구분되어야 하는지가 모호 하다는 겁니다.
님들이 제시한 “명시적참조” 라고 하셨는데 공식적 지원 그러니까 명시적으로 “이것은 call-by-reference를 위해 제공된 기능이다”라는 것의 의미일겁니다.
C++ 함수인자로 &를 제공합니다..
그럼 C는 무엇이 있나?? 명시적으로 *를 제공하고 있습니다.. 이것은 call-by-reference를 구현가능 하게합니다.(최소한 C++에서 처럼요).
C에서 는 그런식(call-by-reference와 같은구현)의 기능을 사용하라고 포인터를 제공해 둔겁니다.
C에서도 언급된 내용을보면 궂이 C++의것과 다르다고 해두진 않았습니다. local copy없는 언어(포트란,파스칼)들과 다르다고 하죠..
오히려 C++과는 동일하죠.. 여기서 주소값이 복사되어 넘어감은 local copy 없이 구현되는 포트란이나 파스칼 같은 언어와 다르다는 것이지.
C++의 call-by-reference 방식과 다르다고 보이지 않습니다.
더 직접적으로 말해.. C++의 구체적으로 무엇이 명시적이며 그것은 어떠한 차이가 있고.. 기타 call-by-reference 라는 언어들에는 어떻게 명시적인 것들이 있는지를 구분 할 수 있어야겠죠.
&라고 말씀하신다면 C는 *라고 말씀 드릴 수 있을 것 같군요.
문법적 표현상 인자를 넘길때 C++은 값을 넘겼지만.. 함수가 주소를 참조하기 때문이다.. 라고 한다면..
C역시 값을 넘겼지만 주소를 참조하는 것처럼 보이는 함수 구현이 되죠
물론 매크로 입니다. 하지만 그것은 C++역시.. &라는 연산자가 값을 넘기는 것처럼 보이지만
실상은 주소를 넘기도록 하는 일종의 매크로(물론매크로가 아니지만)와 별반 다를 것이 없습니다...
그럼 매크로에 의한 구현은 안되고.. 매크로와 비슷한것에 의한 구현은 된다는 것인가요..이는 매우 모호합니다.
분명히 명시적으로 call-by-reference 위해 & 를 제공 했겠지만.. C역시 여전히 명시적으로call-by-reference(C++의 그것과 같은 구현을 할 수 있도록) *를 제공하고 있습니다.
예를 들어 어떤 언어가 함수 인자전달시 %를 붙이면 local copy 없이 참조에 의해 호출될 수 있도록, 함수인자 전달에 사용하는 연산자 %를 제공했습니다.
int a;
aaa( %a );
로 표현되는.. 그래도 call-by-reference 가 아닐까요..
이왕 C++을 call-by-reference 지원한다라고 부르신다면 (그렇게 폭넓게 해석하신다면..) C역시 call-by-reference 를 지원한다고 해야되지 않을까요...
(C와 C++의 차이보다 C++과 local copy없이 호출되는 언어들과의 차이가 훨씬큽니다.)
tj님이 언급하신 C++이 call-by-reference 의 굴레에 포함된다고 보신다면.. C역시 call-by-reference에 포함된다고 보는 편이 맞을 겁니다.
궂이 여기서 구분을 하고자 한다면 표현을 &로하느냐 *로하느냐 정도의 차이가 있는정도 입니다.
call-by-reference의 용어는 언어의 구분에 사용하는 것이 아니라.. 그함수의 구현방법을 구분하는데 더 유용 하겠죠..
물론 call-by-reference가 불가여부의 언어들도 구분할수 있죠
제가 "지원" 이란단어를 광의적으로 해석해야한다 라고 주장하고 하려는게 아니라..(물론광의로 해석하는 게 더 낫다고 봅니다만)
광의든 협의든 그해석의 기준을 명확히 할 필요가 있다는 것입니다.
협의라고 한들 어디까지 협의인지. 그협의의 명확한 선이 무엇인지가 모호하다는 겁니다.
----------------------------------------------------------------------------
마무리하면 어쨋거나 말씀데로 오해를 덜불러 일으키기 위해
'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.' 라는 표현을 쓰죠..
하지만 이에도 반박하는 이가 있다면 님들도 'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.'고 말해주시면 좋겠네요.
긴 글 읽으시느라 수고하셨습니다.
합의의 선은 c++엔 &이 있고 c엔 &이
합의의 선은 c++엔 &이 있고 c엔 &이 없는거구요. 거기서 더 나갈 이유는 없어요.
* c는 call-by-value만을 지원한다.
* c는 포인터를 call-by-value로 전달하고 이를 명시적으로 참조해서 call-by-reference에 준하는 효과를 낼 수 있다.
* c++은 call-by-value와 call-by-reference 모두를 지원한다.
c++은 지원하는데 c는 지원안한다는 부분에 집착하시는 것 같은데, 그런 잡기능 없는게 c의 장점인걸요. 누가 c에 call-by-reference 추가한다고 하면 거꾸로 매달고 울 때까지 때릴 일이지 c에 없다고 흥분할 일은 아닌 거 같아요.
'C언어는 (포인터를 이용해서) call by
'C언어는 (포인터를 이용해서) call by reference를 구현할수 있다.' 라는 표현에 동의합니다.
비슷하게 C로 Garbage collection를 구현할 수 있지만, 지원하지는 않으니까요?
어찌 되었든, 좋은 글타래에서 많은 내용을 배웠습니다.
내 블로그: http://unipro.tistory.com
C 언어는 Call-by-Reference를 구현할 수 없습니다.
Call-by-Reference 정의는 함수 인자를 수정할수 있어야 합니다.
여기서 함수 인자란 함수호출식에서 사용한 수식들을 의미합니다.
C 언어에서 함수 인자는 예로 다음과 같습니다:
이 함수 인자들을 수정할수 있어야 하는데, C 언어에서는 수정할 방법이 존재하지 않습니다.
이것이 C 언어에서 Call-by-Reference를 구현할수 없다고 말하는 이유입니다.
또한 C++이 Call-by-Reference를 지원하는 방법은 다음과 같습니다:
밑에 제가 올린 자료도 좀 봐 주셨으면 감사하겠습니다..
...
일단 제가 가지고 있는 자료를 올리겠습니다.
서울대학교 2008년 1학기 학부과목 프로그래밍 언어 강의록입니다. 원래는 함부로 올리면 안되는거지만... 일단 확인 하시고 수긍을 해 주셨으면 좋겠네요.
첫그림에는 함수 호출시 주소를 넘기는 것도 Call by reference라는 것을 말하고 있고, 두번째 그림에는 C는 Call by value밖에 지원하지 않는다고 얘기하고 있습니다.
죄송합니다만. 누가 강의한 내용을 가지고 따지고 싶진
죄송합니다만. 누가 강의한 내용을 가지고 따지고 싶진 않습니다.
교수라해서 다 맞는말만 하는것도 아니고.. 교수마다도 다른말들을 하죠.
..
할말이 없군요. 그렇다면 powersys님이 반박하시는 자료를 가져오는게 순서라고 생각하는데요. 그렇게 원하시던 자료를 줘도 이렇게 말씀하시니 저는 그냥 이제 이 쓰레드에서 신경 끄겠습니다. 혼자 잘 사세요.
기본형으로 한거 아닌데요. 스왑 된다고 생각하시면
기본형으로 한거 아닌데요. 스왑 된다고 생각하시면 직접 짜서 코드로 보여주세요.
그에 관련해서 다른분들이 많이들 쓴글이
그에 관련해서 다른분들이 많이들 쓴글이 있고...(저는 궂이 그렇게 주장하고 싶진 않습니다)
논의 하고자 하는 핵심이 아닌것 같아 패스하겠습니다.
C가 "Call by reference"를 지원하지
C가 "Call by reference"를 지원하지 않는다는 것과 비슷한 예가, C는 I/O를 지원하지 않습니다.
언어의 명세할 때, 이식성을 고려해서, 입출력 부분을 언어 명세에서 빼고 라이브러리로 처리하도록 결정했다고 합니다.
반대로 일부 프로그래밍 언어는 I/O를 언어의 명세에 포함하고 있습니다.
(프로그래밍 언어 시간에 파스칼이 그랬다고 배웠는데, 기억이 가물가물 하군요.)
많은 프로그래머가 C 프로그래밍에서 "Call by reference"과 같은 효과와 입출력을 멀쩡히 잘 사용하고 있습니다.
그렇다고 하더라도 언어에서 지원하다는 것과는 다른 얘기입니다.
내 블로그: http://unipro.tistory.com
We can solve any problem by
We can solve any problem by introducing an extra level of indirection.
Butler Lampson
논의가 진행될수록 정답이 뭔지 알겠네요. 억지나
논의가 진행될수록 정답이 뭔지 알겠네요.
억지나 말장난보다는 더 확실한 근거를 바탕으로 한 주장이 필요해보입니다만...
오래된 글이지만 우연히 봤습니다.
C를 어제 배운 분도 이를 접했고, 잘 익혔다면 알 수 있는 내용입니다.
C는 call by reference를 지원하지 않습니다.
powersys님의 프로그래밍 실력은 의심치 않습니다만, 한국어 능력은...
C로 call by reference를 구현할 수 있다는 것과 C가 call by reference를 지원한다는 것은 다릅니다.
C에서 call by reference를 지원한다는 말은 '지원'이라는 단어를 자신의 입맛에 맞게 구워삶아낸 것일 뿐입니다. powersys님 같은 분들처럼 단어를 오용하는 분들이 몇몇 존재해왔지만, 그렇다고 해서 '지원'이 갖고 있는 함의는 변하지 않습니다.
예를 들어, 많은 언어에서는 다음과 같은 기능을 구현할 수 있습니다.
출력 "powersys님 제발!"
그렇다고 해서 powersys님에게 애원하는 기능을 '지원'한다고는 하지 않죠.
오래된 글이지만 재밌네요.
언어가 만들어진 히스토리를 보아 온다고 한다면 다음과 같습니다.
초기 c++은 c언어로 재구성하여 컴파일 되도록 구현이 되어 있습니다.
또한 컴퓨터 학문은 만들어진지 얼마 안되었으며 짧은 시간동안 많은 변화가 있어 왔습니다.
결론적으로 용어의 기준이 모호함으로 인해서 이러한 댓글이 많아 보입니다.
제가 보기엔 정답이 없습니다.
c언어가 어떻게 컴파일되어서 기계언어로 바꿔서 메모리를 어떤식으로 사용 하는지는 정확하게 돌아가는지는 위에 대다수분들이 모르실꺼라고 사료됩니다.
call by reference는 call by value는 결국엔 메모리 pool에서 놀고 있는 데이터를 어떤 방식으로 끄집어서 사용 하냐의 기준으로 삼아서 봐야할것으로 보입니다만
결론적으로 c언어나 c++나 메모리의 주소를 알고 또한 사용 할수 있도록 제공되는 언어이기도 하죠. 뭐가 처음이고 뭐가 우선이 다 따지는것 보다.
정확하게 동작을 어떻게 하고 어떤 방식의 개념으로 봐야할 것 같습니다.
따라서 제가 다음과 같이 call by reference , call by value를 제가 생각 하는 정의대로 나열 하면 다음과 같습니다.
1. call by reference 는 실질 적으로 돌아가는 환경(os level) 메모리의 주소의 값(index)을 알고 있으며 그 메모리 참조한 것을 프로그램적으로 직접 변경을 할 수 있는 형태면 call by reference로 보고요.
2. call by value 는 참조한 값을 복제하여 임시 메모리 환경(자바 환경에서 heap memory 겠네요)에 쌓아서 그 값을 변경을 못하는 형태의 접근으로 보는 것.
위와 같이 정의로 하면 되지 않을까 싶네요.
음 제가 알고 있는지식이 잘못 되었는지에 대해서 알려주시거나 그러면 감사드립니다.
제 생각엔 이게 잘못된 점인거 같아요
제 생각엔 댓글을 쓴 여러 사람들의 이해 정도를 너무 쉽게 단정하신게 문제 같습니다.
* 포럼 주제와 무관한 신변잡기를 반복해서 올리지 맙시다.
* 질문 게시판 만이라도 익명 글쓰기를 막아야 한다고 생각합니다.
제가 보기에도 이 스레드에서 c언어가 어떻게
제가 보기에도 이 스레드에서 c언어가 어떻게 컴파일되어서 기계언어로 바꿔서 메모리를 어떤식으로 사용 하는지는 정확하게 돌아가는지 모르시는 분은 거의 없는 것 같군요.
아버지를 아버지라 부르지 못하고...
홍길동전이 생각 납니다.
C 이전의 call by reference 언어들이 reference 라는 용어를 안쓰고, call by l-value와 같이 다른 말을 사용했었다면 어땠을까 하는 생각을 해 보았습니다.
그러면 reference가 그냥 reference(참조)의 의미로 받아들여 진다면, l-value를 이용해서 구현 하거나 pointer를 이용해서 구현하거나 어느 것이든 구현 방법론 상에 있어서는 call by reference(참조)라고 말을 해도 아무런 혼선은 없었을 것 같습니다.
옛 교수님들이 저술하신 책이나, 프로그래밍 언어론이나 다 그렇게 C에서의 call by reference 설명을 하실때는 reference를 reference type으로 설명하신게 아니고, reference(참조)의 의미로 설명해 주시던데요.
다른 곳에서 동일한 주제로 논쟁을 벌이다가 이미 오래전에 격론이 펼쳐졌던 글을 보게 되었네요. 몇일전에 페이스북 생활코딩 방에서도 얘기가 나왔더군요. ^^
call by value
C언어는 Java처럼 파라마터 패싱할때 Call-by-value만 지원합니다.
Java에서 메모리 모델을 생각해보세요 어떻게 동작하는지.
actual 파라미터가 formal 파라미터로 카피가 되기 때문에
value semantics가 지켜집니다.
한마디로 formal 파라미터 변수의 값에 수정이 일어나도
actual파라미터로 패싱된 변수의 값은 변하지 않습니다.
아무래도 사람들이 callee 쪽에서 객체를 수정하면
caller의 객체 상태도 바뀌다보니까 혼동하는 것 같습니다.
C언어도 마찬가지로 Java랑 똑같은 테크닉을 사용합니다.
댓글 달기