C/C++의 통사당
저는 루비를 조사해 보았는데 "까지"와 "그렇지 않으면"이라는 키워드가 매우 흥미롭다는 것을 알게 되었습니다.그래서 비슷한 키워드를 C/C++에 추가할 수 있는 좋은 방법이 무엇일까 생각했습니다.이것이 제가 생각해낸 것입니다.
#define until(x) while(!(x))
#define unless(x) if(!(x))
저는 이에 대한 몇 가지 제안을 찾고 있습니다.더 나은 대안을 제안해 줄 수 있는 사람?
다음은 제가 의도한 바를 설명하기 위해 작성한 프로그램의 예입니다.
#include <stdio.h>
#include <stdlib.h>
#define until(x) while(!(x))
#define unless(x) if(!(x))
unsigned int factorial(unsigned int n) {
unsigned int fact=1, i;
until ( n==0 )
fact *= n--;
return fact;
}
int main(int argc, char*argv[]) {
unless (argc==2)
puts("Usage: fact <num>");
else {
int n = atoi(argv[1]);
if (n<0)
puts("please give +ve number");
else
printf("factorial(%u) = %u\n",n,factorial(n));
}
return 0;
}
C 또는 C++에서 사용할 수 있는 유사한 방법에 대한 참고 자료를 알려주시면 감사하겠습니다.
더 나은 대안을 제안해 줄 수 있는 사람?
절대 마세요 . 절대 이러지 마세요.으로.while그리고.if직접적인 진술
C 또는 C++로 프로그래밍할 때 C 또는 C++로 프로그래밍합니다.하는 동안에until그리고.unless일부 언어에서는 자주 사용되고 관용적으로 사용될 수 있지만 C 또는 C++에는 없습니다.
당신이 한 방법은 제가 보기에는 옳은 방법인 것 같아요.매크로의 확장이 [1]을(를) 예상하는 것과 매우 유사하기 때문에 이 코드가 일반적인 구문을 따르지 않는다는 것을 보여주는 데 사용되는 일반적으로 권장되는 SCARY_UPERCASE_MACROS()가 아니라 매크로를 구문()처럼 만드는 것이 유효하다고 생각합니다.
[1] 유일한 결점은 변수를 선언할 수 없다는 것인데, 이는 어쨌든 가능성이 낮고, 이상한 일을 하는 것이 아니라 잘못 사용했을 때 올바른 위치에 오류가 발생할 가능성이 있습니다.
이라도 높이는 것도 하기 때문에 수 있습니다.until (while (!정말로 많은 루프를 읽기 쉽게 만듭니다.종료 조건이 예외적인 조건으로 더 쉽게 생각되는 경우(여부와 관계없이), 루프를 그렇게 둥글게 쓰면 읽기가 쉬워집니다.그래서 비록 통사당이라고는 하지만 고려해야 할 이유가 있다고 생각합니다.
하지만 저는 그럴 가치가 없다고 생각합니다.대부분의 프로그래머들이 읽기에 익숙해져 있기 때문에 이점은 적습니다.if (!비용은 실제 수준입니다.이 코드를 읽는 사람은 이것이 매크로인지 커스텀 컴파일러인지, 그리고 그들이 생각하는 대로 작동하는지 아닌지를 확인해야 할 것입니다.다 을 할 수 .i=5 unless xxxx;이러한 채택하는 이러한 작은 개선이 널리 퍼지면 언어가 파편화되기 때문에 표준적인 방법으로 작업을 수행하고 개선 사항을 천천히 채택하는 것이 가장 좋습니다.
하지만 잘 해낼 수 있습니다. 부스트와 tr1 전체, 특히 라이브러리의 확장처럼 보이도록 템플릿으로 수행하는 작업은 다양한 방식으로 C++를 확장하는 것을 포함합니다. 이 중 많은 부분이 가치가 없어 보여서 채택되지 않았지만, 실제 개선을 했기 때문에 많은 부분에서 차지하는 비중이 작거나 매우 광범위합니다.
이 말을 듣고 누군가의 코드에서 본 것이 생각났습니다.
#define R return;
게다가 코드를 이해하기 어렵게 만드는 것은 유지보수 비용을 증가시킵니다.
그것들을 사용하지 않는 것이 좋을 것 같습니다.
루비 스타일로는 사용할 수 없습니다.
`printf("hello,world") unless(a>0);`
불법입니다.
그리고 C 프로그래머들이 코드를 이해하는 것은 더 어려울 것입니다.한편 추가 매크로는 문제가 될 수 있습니다.
매크로를 정의하려면 정말 보기 흉하게 만드는 것이 좋습니다.특히, 그들은 모든 자본이어야 하고, 일종의 접두사를 가져야 합니다.이것은 네임스페이스가 없고 C++의 타입 시스템이나 오버로드 해상도와 조정이 없기 때문입니다.
그래서 만약 당신의 매크로가 불렸다면,BIGYAN_UNNECESSARY_MACRO_UNTIL그렇다면 'beyond의 창백함'은 아닐 겁니다
새로운 루프 구성으로 C++를 확장하려면 다음을 허용할 수 있는 C++0x에서 lambdas를 조사하는 것을 고려합니다.
until([&] { return finished; }, [&]
{
// do stuff
});
완벽하진 않지만 매크로보다는 낫습니다.
매크로는 자신의 코드 베이스에서만 사용한다면 특별히 나쁘지 않다고 생각합니다.이 기사는 당신에게 흥미로울지도 모릅니다.그렇기는 하지만, C++에서 매크로를 사용하면 매크로에 단점이 있습니다.
예를 들어 다음과 같이 쓸 수 없습니다.
until (T* p = f(x)) ...
unless (T* p = f(x)) ...
다른 한편으로는 다음과 같이 쓸 수 있습니다.
while (T* p = f(x)) ...
if (T* p = f(x)) ...
에 관해서는unless, 다음과 같이 정의할 경우:
#define unless(x) if (x) {} else
그러면 우리는 글을 쓸 수 있습니다.unless (T* p = f(x)) ... 이 를 할 수 .else그 뒤의 절
각각의 부스트가 어떻게 이루어지는지 보세요.
머리말은 BOOST_FOREACH(못생긴 접두사 매크로)를 정의합니다.넌 할 수 있다.
#define foreach BOOST_FOREACH
당신의 .cpp 파일에서 더 깨끗한 코드를 갖기 위해서 입니다.그러나 .h 파일에서 수행하면 안되며 대신 보기 흉한 BOOST_FOREACH를 사용해야 합니다.
다음은 "편리한" IF, ELSE 식에 대한 "기능-프로그래밍-ish" 매크로 세트입니다. (왜냐하면 ?: 못 생겼기 때문입니다.)
#define IF(x) (x) ?
#define ELSE :
지금이다
int x = IF(y==0) 1
ELSE IF(y<0) 2*y
ELSE 3*y;
당류를 제거하면 다음과 같습니다.
int x = (y==0) ? 1 : (y<0) ? 2*y : 3*y;
좋은 구문 설탕 예제(IMHO):
struct Foo {
void bar() {}
};
typedef std::vector<Foo*> FooVector;
typedef boost::ptr_vector<Foo> FooPtrVector;
FooVector v1;
for (FooVector::iterator it = v1.begin(); it != v1.end(); ++it)
(*it)->bar(); // ugly
FooPtrVector v2;
for (FooPtrVector::iterator it = v2.begin(); it != v2.end(); ++it)
it->bar(); // nice
사람들이 말했듯이, 그 단어를 추가하는 것은 유용한 통사적 설탕을 제공하지 않습니다. 왜냐하면 잠시 읽는 비용(또는 만약 (!가 작다면), 모든 C 개발자들은 익숙해져 있기 때문입니다. 그리고 이러한 매크로를 사용하면 대부분의 C 개발자들을 두렵게 할 것이기 때문입니다.또한, 언어를 다른 언어처럼 보이게 하는 것은 좋은 생각이 아닙니다.
하지만 통사적인 설탕이 중요합니다.이미 언급된 바와 같이, C++에서, boost는 템플릿을 통해 많은 양의 통사적 설탕을 추가하고, stl은 또한 Somme sugar(예를 들어,std::make_pair(a, b)는 의 통사적 당입니다.std::pair<decltype(a), decltype(b)>(a, b).
언어가 향상됨에 따라 기능성과 통사적 설탕이 추가되어 개발자의 가독성, 쓰기성, 효율성이 향상됩니다.예를 들어, C++11 사양에서는 "for (데이터 구조의 요소)"가 추가되었으며(아래 참조), 일주일 동안 유형을 추론할 수 있는 "auto" 키워드도 추가되었습니다(유형이 실제로 '명백하고' 중복되는 많은 곳에서 유형을 많이 입력해야 하므로 약하다고 말합니다).
또한, 하스켈에서는 도 표기(신통당)가 없는 모나드를 사용하는 것은 정말 고통스러울 것이고, 아무도 사용하지 않을 것입니다.
통사당이 없는 예:
//C++ < 11
std::vector<int> v;
v.push_back(3);
v.push_back(7);
v.push_back(9);
v.push_back(12);
for (std::vector<int>::iterator it = v.begin();
it != v.end();
it++)
{
std::cout << *it << std::endl;
}
그리고 통사당과 함께:
//C++ >= 11
std::vector<int> v {3, 7, 9, 12};
for (auto elm : v)
{
std::cout << elm << std::endl;
}
좀 더 읽을 만하지, 안 그래요?
IO 모나드에 대한 해스켈 예(HaskellWiki에서):
f :: IO String
f =
ask "What's your name ?" >>= \name ->
putStrLn "Write something." >>= \_ ->
getLine >>= \string ->
putStrLn ("Hello " ++ name ++ " you wrote " ++ string) >>= \_ ->
return name
g :: IO String
g = do
name <- ask "What's your name ?"
putStrLn "Write something."
string <- getLine
putStrLn ("Hello " ++ name ++ " you wrote " ++ string)
return name
다음은 ideo의 링크입니다. http://ideone.com/v9BqiZ
1: 실제로 언어는 C++보다 유연하고 생성 연산자(예를 들어 &^, +.:+:, ...)를 생성할 수 있으므로 누군가가 구문 당을 다시 빨리 도입할 것이라고 상상할 수 있습니다.
당신이 할 수 있겠지만, 소스 파일에 없는지 확인하세요.저는 최적화 생성 없이 자바스크립트에 커피스크립트 접근을 하는 것을 추천합니다.
일반적으로 당신은 당신의 언어를 쓰되 마치 당신이 C로 작성했을 것처럼 번역된 코드를 내보내고 주고 받아야 합니다.
조사해 보십시오.awk모든 파일을 다른 파일로 변환할 수 있게 해줍니다..cugar저장해 두거나 그와 비슷한 것으로.:)
행운을 빌어요.
언급URL : https://stackoverflow.com/questions/5607253/syntactic-sugar-in-c-c
'programing' 카테고리의 다른 글
| 오버플로된 Div 내의 요소로 스크롤하려면 어떻게 해야 합니까? (0) | 2023.10.06 |
|---|---|
| npm 설치 오류 - 로컬 발급자 인증서를 가져올 수 없습니다. (0) | 2023.10.06 |
| Angular UI Grid 3.x 버전의 Action 버튼 (0) | 2023.10.06 |
| Cython을 Python to C Converter로 사용 (0) | 2023.10.06 |
| 도커 컨테이너에서 호스트 데이터베이스 액세스 (0) | 2023.10.06 |