로그인하고 있지 않습니다. 편집하면 당신의 IP 주소가 공개적으로 기록됩니다. 계정을 만들고 로그인하면 편집 시 사용자 이름만 보이며, 위키 이용에 여러 가지 편의가 주어집니다.스팸 방지 검사입니다. 이것을 입력하지 마세요!== 연산자 == * + : 더하기 * - : 빼기, 더하기와 빼기는 곱셈, 나눗셈, 나머지 연산보다 우선 순위가 낮다. {{취소선|2+2*2는 8이 아니라 6이라는 거다.}} * *: 곱하기, x가 아니라 이 기호를 쓴다. * /: 나누기, 보통 쓰는 나누기 기호가 아니라 슬래시를 쓴다. * %: 나머지 연산. A%B라고 쓰면 A를 B로 나누었을 때의 나머지를 반환한다. 예를 들면 5%2 = 1 이런식으로. 당연히 만약 B가 A보다 더 크면 그냥 A를 반환한다. * =: 대입연산자. 일상에서 사용하는 등호와 방식이 조금 다르다. 좌항에는 반드시 대입이 가능한 변수가 있어야 하고, 우항에는 변수에 대입할 값이 있어야 한다. * +=, -=, *=, /=, %=: A+=B라 할 때, A = A + B와 같다. (수학적으로는 말도 안되지만 프로그래밍 언어의 =는 수학의 등호와는 다르다. 변수 A의 자리에 A+B의 값을 대입한다고 봐야한다.) 예를 들어서, a=1; a+=2;를 하면 a가 3이 된다. -=는 이하도 해당 연산자 버전으로 마찬가지이다. * ++, --: 각각 '+=1, '-=1'과 같다. 때문에 연산자 양쪽 모두 변수가 위치하지는 않는다. a++ 또는 ++a로 쓰는데, 적용되는 방식이 미묘하게 다르다. ===조건문과 반복문=== 조건문과 반복문에 대하여 설명한다. 코딩을 하다 보면 상황에 따라 처리를 달리 해야 하는 것이나 반복 작업이 많기 때문에 자주 쓰게 될 것이다. {{취소선|goto}}는 사용하는 것이 권장되지 않고 실제로도 거의 쓰이지 않는다. 절차지향 프로그래밍의 핵심인 '절차'를 깨트리기도 하고, goto를 쓰면 코드 내에서 왔다갔다 해대니 코드 분석에도 어려움을 주기 때문. ====if==== *소괄호 안의 값을 확인하여 0이면 그냥 지나가고 0이 아니면, 블록 안의 코드를 실행하는 문법. {{취소선|조건을 검사하는 기능같은거 없다.}} *평범한 사용법 <syntaxhighlight lang="c"> if(0) { //실행 안 된다. } if(2312) { // 실행된다. } </syntaxhighlight> *비범한 사용법 <syntaxhighlight lang="c"> int a = 10; if(a - 10) { //a가 10이 아니면 실행된다. } </syntaxhighlight> *좀 더 비범한 사용법 ** C에서 1 == 1 -> 1이고, 1 == 2 -> 0 이다. ** 1 < 2 -> 1이고, 1 > 2 -> 0이다. {{취소선|어떻게 되먹은 산수지...?}} <ref>산수라기 보다는, 논리에 가깝다. 진실일때 1을 출력하고, 거짓일때 0을 출력한다고 가정하자, 1==2는 "1과 2가 같다"라는 말이므로 거짓이 된다. 그러므로 0을 출력한다. 반대로, 1==1은 1은 1이다라는 진실이므로 1을 출력한다. 그리고 1보다는 2가 크므로 진실, 1을 출력하고, 1이 2보다 큰것은 거짓이므로 0을 출력한다.</ref> <syntaxhighlight lang="c"> int a = 10; if(a < 11) { //a가 11보다 작으면 실행된다. } </syntaxhighlight> ====switch==== 여러 선택지에 따라 다른 동작을 수행하는 문법이다. 조건이 여러 개 붙어 있을 때 유용하다. 선택지로 int나 char형의 변수를 받을 수 있다. 다음은 switch문의 예시이다. * 정수형 선택지 <syntaxhighlight lang="c"> #include <stdio.h> int main(void){ int no; //이 변수로 switch문을 제어한다. printf("어떤 치킨을 주문하시겠습니까?: \n1. 후라이드 2. 양념 3. 간장\n답 입력: "); scanf("%d",no); switch(no) //이렇게 { case 1: printf("17000원이 결제됩니다.\n"); break; //1을 고르면 실행됨 case 2: printf("18000원이 결제됩니다.\n"); break; //2를 고르면 실행됨 case 3: printf("17500원이 결제됩니다.\n"); break; //3을 고르면 실행됨 default: printf("번호를 다시 입력해주세요.\n"); //나머지 경우 } return 0; } </syntaxhighlight> 모든 case마다 <syntaxhighlight lang="c>break;</syntaxhighlight>를 쓴 것을 알 수 있는데 만약 break를 써서 case에서 빠져나오지 않으면 그 case 아래의 내용도 모조리 실행되기 때문이다. default에는 break가 붙지 않았는데, 그것은 default문이 맨 아래에 있으므로 break문을 쓰지 않더라도 더 이상 실행될 것이 없기 때문에 굳이 붙이지 않아도 되기 때문이다. 만약 default를 쓰지 않는 switch문이라면 마지막 case에 break를 쓰지 않아도 된다. ====while==== <syntaxhighlight lang="c"> while(조건식) </syntaxhighlight> *조건식이 참(또는 값이 1)이면 반복한다. *무한 반복 <syntaxhighlight lang="c"> while(1)printf("당신의 CMD는 반달당했습니다?\n"); </syntaxhighlight> 이 소스대로 작동시키면, 당신이 창을 닫지 않는 이상 printf에 있는 글로 도배가 될 것이다. ====for==== <syntaxhighlight lang="c"> for(초기식;조건식;증가식) </syntaxhighlight> *조건문 안에서 사용할 변수 정의, 반복 조건, 반복할 때만 실행할 코드까지 정의하기에 알맞다. *단순 반복 <syntaxhighlight lang="c"> int sum = 0; for(int i = 1;i<=1000;i++)sum += i; // sum = sum + i </syntaxhighlight> 1부터 1000까지 더하는 코드이다.<ref>참고로, 고등학교 수학을 배웠다면 알겠지만 코드 길이나 속도나 1000*1001/2 를 계산하는 편이 빠르고 효율적이다.</ref> ====삼항연산자==== if/else 문과 같은 용도로 쓰인다. 간단한 조건문의 경우 짧은 코드로 작성할 수 있다는 장점이 있지만 반면 가독성이 떨어진다는 문제가 있기 때문에 상황에 맞게 조건문과 삼항연산자를 쓰는 것이 좋다. *{{취소선|참이면 앞에거, 거짓이면 뒤에거..}} *소괄호 안의 값을 확인하여 0이면 뒤에 것을 실행하고 0이 아니면, 앞에 것을 실행한다. (1==2) ? 실행안됨 : 실행됨 ===사용자정의변수=== C언어에서는 typedef 키워드로 사용자 변수 타입을 정의할 수 있다. 즉 typedef int bool; 을 이용해 int와 같은 성질을 갖는 자료형을 bool 자료형의 이름으로 사용 가능하다. 또한 여러 자료형과 변수를 한 단위로 묶기 위한 구조체와 공용체, 상수의 집합을 보다 알아보기 쉽게 정의할 수 있는 열거형 또한 사용자 정의 자료형으로 취급한다. *구조체 <syntaxhighlight lang="c"> struct xxx_t { int index; int age; int id; }; int main() { struct xxx_t x; x.index = 1; x.age = 2; x.id = 3; printf("%d %d %d\n",x.index,x.id,x.age); return 0; } </syntaxhighlight> *공용체 공용체와 구조체의 가장 큰 차이점은, 구조체는 각 속성들의 메모리 영역이 독립적으로 나뉘어 있고 공용체는 모두 같은 공간을 공유한다는 점이다. <syntaxhighlight lang="c"> union my_union{ int age; char gender; }; int main(){ union my_union un; un.age = 20; printf("%d", un.age); un.gender = 'f'; printf("%c", un.gender); printf("%d", un.age); return 0; } </syntaxhighlight> *열거형 열거형은 위의 두 자료형과는 조금 다르며 정수 상수의 집합을 선언해 다음과 같이 프로그래밍 과정을 좀 더 쉽게 하기 위해 주로 사용된다. 예를 들면 다음과 같다. <syntaxhighlight lang="c"> int main(){ int day = 3; if(day == 0 || day == 6){ printf("weekend!\n"); } else{ printf("weekdays!\n"); } return 0; } </syntaxhighlight> 위와 같은 코드를 아래와 같이 바꿀 수 있다. <syntaxhighlight lang="c"> enum daykind { sunday = 0, monday, tuesday, wednesday, thursday, friday, saturday}; int main(){ enum daykind day = thursday; if(day == sunday|| day == saturday){ printf("weekend!\n"); } else{ printf("weekdays!\n"); } return 0; } </syntaxhighlight> 위의 예시보다 이해하고 읽기 쉬움을 알 수 있다. ===포인터=== ====포인터==== C언어를 배우면서, 조건문, 루프문등 기초적인 문법에 대해서 학습할때까지는 큰 장벽을 못 느끼다가, 포인터로 넘어오면서 C언어를 포기하는 경우가 많다. 그 이유는 앞에서의 문법들은 사실 사람의 말을 배우듯이 따라가면 되는 것이고, 또한 논리적인 추론능력만 충분하다면 컴퓨터를 처음 하는 사람들도 쉽게 배울 수 있다. 하지만, 포인터가 시작되면 거창하게 얘기하면 컴퓨터의 구조, 좁게 보면 메모리의 구조에 대한 이해와 C언어가 메모리를 어떻게 다루는가, 메모리 계층 구조가 어떻게 되는가에 대한 이해가 없다면 포인터의 개념을 이해하고 활용하는 데에 상당한 어려움을 겪게 될 것이다. 다음은 포인터를 사용한 간단한 예시이다. <syntaxhighlight lang="c"> #include <stdio.h> int main() { int a=5; int *pa; pa=&a; printf("%d %d %d",a,pa,*pa); return 0; } </syntaxhighlight> 위의 예제에서 어떤 값이 출력되는지 알아보자. 우선 첫번째 값은 당연히 a가 출력될 것이다. 그러면 2, 3번째 값은 어떤 값이 출력되는가? 먼저, 2번째 값은 <b>a가 저장된 주소</b>가 출력된다. 여기에서 알 수 있듯이 포인터 변수 pa에 저장된 값이 a의 주소임을 알 수 있다. &a가 바로 a의 주소를 나타낸다. 왜 그런지는 다음 단락에 설명하겠다. 그리고 3번째 값은 a의 값인 5가 출력되는데, 왜 그런 것일까? 우선 주소 참조와 관련된 두 가지 연산자를 알아둘 필요가 있다. 이 둘은 이미 위에서 모두 나왔다. 그렇다, &과 *이다. 이 두 연산자의 사용법은, 변수명 앞에 이 두 연산자를 붙이는 것이다. 이 둘의 기능은 정반대라고 생각하면 되는데, &를 사용할 경우 결과는 그 변수가 저장되어 있는 주소가 되고, *를 사용할 경우 결과는 그 변수에 저장된 주소값에 위치한 변수에 저장된 값이 된다. 즉 간단히 말하자면 *의 경우 변수에 저장된 주소값을 통해 다른 변수를 참조하게 해주고, &의 경우 그 반대의 기능을 수행하는 것이다. 그래서 *을 참조 연산자, &의 이름을 역참조 연산자라고 부르기도 한다. 이제 포인터에 대한 기본적인 내용을 익혔으니 그 응용으로 넘어가 보자. *array를 이용한 string <syntaxhighlight lang="c"> #include <stdio.h> int main() { char str[20] = "hello? librewiki!\n"; printf("%s",str); str[5] = '!'; str[16] = '?'; printf("%s",str); return 0; } </syntaxhighlight> *pointer를 이용한 string <syntaxhighlight lang="c"> #include <stdio.h> int main() { char *str = "hello? librewiki!\n"; printf("%s",str); str[5] = '!'; str[16] = '?'; printf("%s",str); return 0; } </syntaxhighlight> 이 중에서 어느 프로그램은 정상적으로 작동하고 어느 프로그램은 런타임 에러가 걸리는지 이해 하기 힘들 것이다. 메모리의 구조는 크게 5개의 영역으로 나뉜다. CODE, DATA, BSS, HEAP, STACK 일단 이것을 두개로 쪼개면 컴파일시 결정되는 CODE, DATA, BSS(CODE는 프로그램의 코드, DATA,BSS는 전역변수와 문자열 static 변수들이 저장된다. 완전히 정확한 것은 아니지만 ROM영역이라 실행 이후에는 접근 권한이 없다고 생각 하면 된다.) 실행 하는 동안에(Run time동안에)결정되는 HEAP, STACK 그리고 (stack은 지역변수들이 저장되고, HEAP은 동적 메모리이다. 이곳은 RAM영역이다.) 일단, 첫번째 소스가 왜 작동이 잘되는 이유를 알아보자. 일단 문자열은 DATA영역에 컴파일이 되면서 먼저 기록되고, char array는 main함수 안에 있으므로 stack영역에 들어있다. char array는 실제 메모리의 연속된 덩어리 이므로 여기에 DATA영역에 있던 문자열을 그대로 복사하는 것이다. 그렇기에 실제 "hello? librewiki!\n" 라는 문자열은 지금 stack 과 data 영역 모두에 존재라게 된다. 그렇기에 str[5]= '!'; 이런식으로 접근하여 수정해도 아무런 오류가 없다. 하지만 두번째 소스에서 char *str = "hello? librewiki!\n"; 이 선언은 포인터 즉, DATA 에 있는"hello? librewiki!\n" 문자열의 주소만을 가져 온것이다. 실제 stack영역에은 DATA영역의 "hello? librewiki!\n" 주소만 있지, 실제 이 문자열 내용은 존재 하지 않는다. 그렇기에 str[5]= '!' 로 접근하는 것은 ROM영역을 침범한다는 뜻이므로 런타임 에러가 나는 것이다. ====메모리의 동적 할당==== 메모리에는 CODE, DATA, BSS, HEAP, STACK이 있고, 이 중 CODE, DATA, BSS는 컴파일 과정에서 결정되고 HEAP, STACK은 실행 중에 결정되는 메모리라고 윗 문단에서 언급했다. 그런데 HEAP과 STACK 중에서도 사실 우리는 STACK만을 써왔다. HEAP 메모리에 접근하는 방법은 바로 이 문단에서 다룰 메모리의 동적 할당 뿐이기 때문이다. 그러면 메모리의 동적 할당 방법을 예시로 알아보자. <syntaxhighlight lang="c"> #include <stdio.h> int main() { int *ptr; ptr=(int *)malloc(sizeof(int)); *ptr=4; printf("%d",*ptr); free(ptr); ptr=0; return 0; } </syntaxhighlight> malloc 함수를 통해 int 포인터인 ptr에 int 자료형의 크기만큼의 HEAP 메모리를 할당한다. malloc 함수 앞에 (int *)가 붙은 것을 알 수 있는데, malloc함수는 기본적으로 void 포인터 형태로 값을 반환하기 때문에 자료형을 casting해주는 것이다. Visual Studio C++ 2010까지는 꼭 이 casting을 해주어야만 컴파일이 되었으나, 그 다음 버전부터는 굳이 casting을 해주지 않아도 자동으로 변환해 준다. 하지만 코드의 호환성을 위해서라도 가급적 casting을 해 주자. 그리고 HEAP메모리에 할당하고 그 메모리를 다 사용한 후에는 꼭 할당을 해제해 주어야 하는데, 이 때 free 함수를 사용한다. 주의할 것이, free로 해제한 후에 <b>포인터의 값이 자동으로 지워지지 않는다</b>는 것이다. 즉, 할당을 해제한 이후에는 포인터에 저장되어 있는 주소값을 STACK 메모리의 주소로 인식하여 그 주소를 가리키게 된다는 뜻이다! 따라서, 예기치 못한 오류를 막기 위해서는 할당 해제 후 포인터 변수를 반드시 NULL 상태로 두어야 한다. ====다중 포인터==== 다중 포인터는 포인터 변수의 주소를 가지고 있는 포인터이다. 다음은 다중 포인터의 사용 예시이다. <syntaxhighlight lang="c"> #include <stdio.h> int main(void) { int a=5; int* pa; int** ppa; //이중 포인터 pa=&a; //포인터 pa에 a의 주소 저장 ppa=&pa; //이중 포인터 ppa에 pa의 주소 저장 printf("%d %d %d",*pa,*ppa, **ppa); return 0; } </syntaxhighlight> 이 코드의 실행 결과는 어떻게 될까? 이미 우리는 윗 문단을 통해 첫 번째 값은 pa에 저장된 a의 주소를 통해 참조한 a의 값인 5임을 알고 있다. 다중 포인터에서도 똑같은 논리가 그대로 적용되는데, 2번째 값의 경우 ppa에 저장된 pa의 주소를 통해 참조한 pa의 값, 그러니까 a의 주소가 출력될 것이다. 3번째 값은 ppa에서 2번 참조한 것이 출력되는데, 이것은 2번째 경우에서 참조를 한 번 더 실행한 경우를 뜻하므로, ppa에 저장된 pa의 주소를 통해 pa를 참조하고, pa에 저장된 a의 주소를 통해 a를 참조하여 첫 번째 값과 같은 a의 값인 5가 출력될 것이다. 이를 통해 C++의 Call By Reference를 비슷하게 흉내내는것 또한 가능하다. <syntaxhighlight lang="c"> // 할당된 메모리 주소는 이해를 돕기 위한 임의의 값. #include <stdlib.h> int AllocMe(void **ptr, size_t sz) { if(!*ptr) // 3. **ptr은 2번 *myInt 의 주소인 0x01를 가르키고 있으므로 이를 dereferencing 하면 *myInt가 가르키고 있는 값인 NULL값을 읽음. { *ptr = malloc(sz); // 4. *myInt의 주소의 값에 malloc(); 1.번의 myInt는 malloc()이 반환한 0x10주소를 저장. (메모리 주소 0x1에는 0x10이라는 값이 들어 있음) return *ptr ? 1 : 0; // 5. *ptr에 malloc()이 반환한 주소(0x10)가 들어있다. } } int main() { int *myInt = NULL; // 1. NULL 포인터 - *myInt := 스택 메모리 0x01, 0x01에 저장된 값은 0 (NULL) if(AllocMe(&myInt, 8)) // 2. 1번의 포인터가 위치한 주소를 전달 (Call by value) 주소값인 0x01이 전달 { free(myInt); // 6. AllocMe()에서 할당한 메모리 주소(0x10)를 해제 myInt = NULL; // myInt (0x1)의 값은 다시 NULL return 0; } return -1; } </syntaxhighlight> 그러면 다중 포인터는 대체 어디에 쓰는가? 다중 포인터는 보통 다차원 동적 배열을 만들 때 쓴다. 이 다차원 배열중 흔히 볼 수 있는 예시는 프로세스 진입 지점인 int main()에서 찾을 수 있다. <syntaxhighlight lang="c"> #include <stdio.h> int main(int argc, const char **argv) { for (int i = 0; i < argc; ++i) { printf("%d: %s\n", i, argv[i]); // *(argv + 1)과 동일 } } </syntaxhighlight> C언어에서 문자열(String)또한 단순 1차원 배열에 불과하지만 이런 배열을 포함하는 또다른 배열을 만드는 것이 가능하다. 이를 통해 char* 는 배열의 주소를 담고 있지만 이 배열의 주소를 담고 있는 또다른 포인터를 만듬으로써 2차원의 배열을 만드는 것이 가능하다. 이를 통해 3차원은 물론 그 이상의 다차원 배열을 만드는 것 또한 가능하다. ====함수포인터==== 함수 포인터는 말 그대로 함수를 가르키는 포인터이며 이 값은 함수 심볼의 진입 주소가 된다. 주로 플러그인과 같이 동적 라이브러리에서 링킹 없이 동적으로 심볼만 가져다 쓰는 상황에서 주로 사용되며 C에서 객체지향을 흉내낼 때도 사용하는것이 가능하다. 문법은 일반 함수 선언과 비슷하다. <syntaxhighlight lang='c'> <반환 자료형> (*<함수 포인터 이름>)(<매개변수>); </syntaxhighlight> 예를 들어 void* MyFunction(int, void*) 꼴의 함수를 담을 수 있는 함수 포인터는 다음과 같이 선언할 수 있다. <syntaxhighlight lang='c'> void* (*MyFunction_ptr)(int, void*); </syntaxhighlight> <syntaxhighlight lang='c'> void* (*MyFunction_ptr)(int, void*) = &MyFunction; MyFunction_ptr(0, NULL); // MyFunction(0, NULL)과 동일 </syntaxhighlight> ===매크로=== <syntaxhighlight lang='c'> #define <매크로 이름> <매크로 값(옵션)> </syntaxhighlight> 변수나 상수와 달리 매크로는 단순히 컴파일단계 중 전처리기에 의해 값이 단순히 치환된다. 예를 들어 <syntaxhighlight lang='c'> #define SIZE 64; int myArray[SIZE]; </syntaxhighlight> 는 전처리기에 의해 SIZE 부분이 64로 치환되며 결과적으로 int myArray[64]; 가 된다. 매크로 값은 생략하는것이 가능한데 보통 생략하는 경우 해당 매크로는 0이 아닌 값(true)로 바뀐다. 이를 통해 다음과 같이 응용할 수 있다. <syntaxhighlight lang='c'> #define BUILD_PRINT_DEBUG_MESSAGE ... #ifdef BUILD_PRINT_DEBUG_MESSAGE printf("[DEBUG] Print Debug Message!\n"); #endif // BUILD_PRINT_DEBUG_MESSAGE </syntaxhighlight> 또한 매크로는 코드의 일부가 될 수 있다. <syntaxhighlight lang='c'> #include <stdio.h> #define PROCEDURE(x) int x #define PRINTHELLOWORLD printf("Hello World!\n"); #define BEGIN { #define END } PROCEDURE(main) // int main (int argc, const char *argv[]) BEGIN // { PRINTHELLOWORLD; // printf("Hello World!\n); return 0; END // } </syntaxhighlight> {{각주}} {{프로그래밍}} [[분류:프로그래밍 언어]] 요약: 리브레 위키에서의 모든 기여는 크리에이티브 커먼즈 저작자표시-동일조건변경허락 3.0 라이선스로 배포됩니다(자세한 내용에 대해서는 리브레 위키:저작권 문서를 읽어주세요). 만약 여기에 동의하지 않는다면 문서를 저장하지 말아 주세요. 글이 직접 작성되었거나 호환되는 라이선스인지 확인해주세요. 리그베다 위키, 나무위키, 오리위키, 구스위키, 디시위키 및 CCL 미적용 사이트 등에서 글을 가져오실 때는 본인이 문서의 유일한 기여자여야 하고, 만약 본인이 문서의 유일한 기여자라는 증거가 없다면 그 문서는 불시에 삭제될 수 있습니다. 취소 편집 도움말 (새 창에서 열림) | () [] [[]] {{}} {{{}}} · <!-- --> · [[분류:]] · [[파일:]] · [[미디어:]] · #넘겨주기 [[]] · {{ㅊ|}} · <onlyinclude></onlyinclude> · <includeonly></includeonly> · <noinclude></noinclude> · <br /> · <ref></ref> · {{각주}} · {|class="wikitable" · |- · rowspan=""| · colspan=""| · |} {{lang|}} · {{llang||}} · {{인용문|}} · {{인용문2|}} · {{유튜브|}} · {{다음팟|}} · {{니코|}} · {{토막글}} {{삭제|}} · {{특정판삭제|}}(이유를 적지 않을 경우 기각될 가능성이 높습니다. 반드시 이유를 적어주세요.) {{#expr:}} · {{#if:}} · {{#ifeq:}} · {{#iferror:}} · {{#ifexist:}} · {{#switch:}} · {{#time:}} · {{#timel:}} · {{#titleparts:}} __NOTOC__ · __FORCETOC__ · __TOC__ · {{PAGENAME}} · {{SITENAME}} · {{localurl:}} · {{fullurl:}} · {{ns:}} –(대시) ‘’(작은따옴표) “”(큰따옴표) ·(가운뎃점) …(말줄임표) ‽(물음느낌표) 〈〉(홑화살괄호) 《》(겹화살괄호) ± − × ÷ ≈ ≠ ∓ ≤ ≥ ∞ ¬ ¹ ² ³ ⁿ ¼ ½ ¾ § € £ ₩ ¥ ¢ † ‡ • ← → ↔ ‰ °C µ(마이크로) Å °(도) ′(분) ″(초) Α α Β β Γ γ Δ δ Ε ε Ζ ζ Η η Θ θ Ι ι Κ κ Λ λ Μ μ(뮤) Ν ν Ξ ξ Ο ο Π π Ρ ρ Σ σ ς Τ τ Υ υ Φ φ Χ χ Ψ ψ Ω ω · Ά ά Έ έ Ή ή Ί ί Ό ό Ύ ύ Ώ ώ · Ϊ ϊ Ϋ ϋ · ΐ ΰ Æ æ Đ(D with stroke) đ Ð(eth) ð ı Ł ł Ø ø Œ œ ß Þ þ · Á á Ć ć É é Í í Ĺ ĺ Ḿ ḿ Ń ń Ó ó Ŕ ŕ Ś ś Ú ú Ý ý Ź ź · À à È è Ì ì Ǹ ǹ Ò ò Ù ù · İ Ż ż ·  â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û · Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ · ǘ ǜ ǚ ǖ · caron/háček: Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž · breve: Ă ă Ğ ğ Ŏ ŏ Ŭ ŭ · Ā ā Ē ē Ī ī Ō ō Ū ū · à ã Ñ ñ Õ õ · Å å Ů ů · Ą ą Ę ę · Ç ç Ş ş Ţ ţ · Ő ő Ű ű · Ș ș Ț ț