C++ 기본적이면서 필수적인 것들을 정리해보겠습니다.
질문의 정답은 맨 아래에 기재해놨습니다.
1~4 : 프로그래밍기초
5~6 : 함수와 활용
7~9 : 클래스와 활용
#include <stdio.h>
printf("hello\n");
#include <iostream>
using namespace std;
int main(){
cout << "hello world" << endl;
return 0;
}
#include <iostream> // 전처리 지시자
C++에서 함수를 사용하고자 한다면,
반드시 그 함수의 원형을 미리 정의하여야 합니다.
C++에서 ;
는 종결자의 역할(한 문장의 끝)
endl
줄바꿈을 의미
<<
데이터의 방향
원래는 std::cout
를 써야하는데 using namespace std;
를 사용해줌으로써
std::
를 안쓰고 cout
만 사용 가능.
이렇게 사용하면 에러 발생 출력문 작성시 각각 사용해야함.
int a; //선언
a=7; //대입
int b=7; // 초기화
cout << "a=" << a << ", b=" << b << endl;
include <climits>
를 선언해주면 최대 값 함수 사용가능.
#include <iostream>
#include <climits>
using namespace std;
int main(){
// short, int, long, long long
int n_int = INT_MAX;
short n_short = SHRT_MAX;
long n_long = LONG_MAX;
long long n_llong = LLONG_MAX;
cout << "int는 " << sizeof n_int << "바이트입니다." << endl;
cout << "최대값" << n_int << "." << endl;
cout << "short는 " << sizeof n_short << "바이트입니다." << endl;
cout << "최대값" << n_short << "." << endl;
cout << "long는 " << sizeof n_long << "바이트입니다." << endl;
cout << "최대값" << n_long << "." << endl;
cout << "long long는 " << sizeof n_llong << "바이트입니다." << endl;
cout << "최대값" << n_llong << "." << endl;
return 0;
}
Visual Studio Code에서 Clang 컴파일러를 사용할 경우, 경로에 한글이 포함되어 있을 때 문제가 발생할 수 있습니다. 이러한 경우에는 다음과 같이 경로를 영문으로 변경하거나, 컴파일러에서 인식할 수 있는 경로로 명시해주어야 합니다.
clang -o ex2 ~/study/ex2.c
예를 들어, 작업 폴더를 ~/study로 설정하고 다음과 같은 명령어를 실행할 경우:
clang -o ex2 ex2.c
이 경우, 컴파일러는 작업 폴더 내에 있는 ex2.c 파일을 찾아 컴파일합니다. 이 방법을 사용하면 경로를 한글로 지정해도 문제없이 컴파일이 가능합니다.
unsigned
short b = -2;
해주면 양수만 출력됨.#include <iostream>
#include <climits>
using namespace std;
int main(){
float a =3.14;
int b = 3.14;
cout << a.f << " " << b << endl;
return 0;
}
여기서 문제, 어떤 점이 잘못되었는지 알 수 있습니까?
#include <iostream>
using namespace std;
int main(){
// char : 작은 문자형
char b = 'a'; // char= "a" 로 작성하면 'a' + '\0' 을 포함하게된 것이라서 char을 사용하지 못함.
// null 문자 '\0'을 꼭 작성해줘야함 그래야지 여기까지 내가 출력하는구나 를 인지할 수 있음.
// '\0' 을 만나면 여기까지만 출력해야겠구나 라고 인지함
// 즉, '\0'은 null 문자를 나타내며, 문자열의 끝을 나타내며, 표시하는 용도로 쓰임.
// 계속 null을 쓰긴 귀찮으니까 문자열을 " "로 감싸주게 된다면, 명시적으로 null 문자가 포함됨. -> string
char a[] = {'a','b','c', '\0'};
cout << b << endl;
cout << a << endl;
return 0 ;
}
#include <iostream>
using namespace std;
int main(){
// bool : 0 혹은 1 만 사용가능.
// 참고로 0은 FALSE 1 은 TRUE
bool a = 0;
bool b = 1;
bool c = 10;
// 0 이외의 모든 값은 1로 저장하기 때문에 출력할 때는 당연지사 0 1 1로 출력됨.
cout << a << " "<< b << " " << c << endl;
return 0;
}
const 데이터타입 변수명 = 값 ;
#include <iostream>
/* c에서 상수 선언
#define PIE 3141592
*/
using namespace std;
int main(){
// 원의 넓이를 구하는 프로그램
float r = 3.14;
float sum = r*r*r;
/* c++ 에서 상수 선언
const float PIE = 3.1415;
*/
int r2 = 3;
float s = r2*r2*3.14;
cout << sum << endl;
cout << s << endl;
return 0;
}
#include <iostream>
using namespace std;
int main(){
// 데이터 형 변환
/*
1. 특정 데이터형의 변수에 다른 데이터형의 값을 대입했을 때
2. 수식에 데이터형을 혼합하여 사용했을 때
3, 함수에 매개변수를 전달할 때
*/
int a = 3.141592;
cout << a << endl;
//강제적으로 데이터형 변환
// typeName(a) || (typeName)a
// 바꿀 데이터형이름 선언하고 소괄호를 써서 변수이름 씀
char ch = 'M';
cout << (int)ch << " " << int(ch) << endl;
// c++ 에선,
// static_cast<typeName>
cout << static_cast<int>(ch) << endl;
return 0;
}
}
자동으로 데이터형 변환하고 결정함.
복잡한 변수형을 다룰 때 좋음.
but, 너무 맹신하는 것은 안좋음. (아래 예시)
#include <iostream>
using namespace std;
int main(){
// c++가 복잡한 산술 연산을 수행할 수 있을까?
// => c++의 연산 수행법을 알아야 할 수 있습ㄴ디ㅏ.
// float a =9.0;
// int b = 5;
// cout << a/b << endl;
auto x = 0.0; // float 형
float y = 0; // float 형
auto z =0; // int 형
return 0;
}
int arr1[3]= {1,2,3};
int arr2[12] = {2,4,6,7,9};
arr2 = arr1; // 불가능
#include <iostream>
using namespace std;
int main(){
short month[12]={1,2,3};
cout << month[3] << endl;
return 0;
}
" "
사용시 \0
자동으로 포함함. 따라서 따로 쓸 필요 없이 문자열로 인식. 그래서 아래와 같이 사용함.#include <iostream>
using namespace std;
int main(){
//short month[12]={1,2,3};
//cout << month[3] << endl;
char arr[] = "Hello";
cout << arr << endl;
return 0;
}
sizeof()
: 변수의 바이트 크기를 반환함strlen()
: 문자열의 길이 반환 -> #include <cstring>
에 정의되어 있음.#include <iostream>
#include <cstring>
using namespace std;
int main(){
const int Size = 15;
char name1[Size]; // 비어있는 배열
char name2[Size] = "C++Programaing"; // 문자열 상수로 초기화
cout << "안녕하세요. 저는 " << name2 << "입니다 ! 성함이 어떻게 되십니까?\n";
cin >> name1;
cout << "음, " << name1 << "씨, 당신의 이름은" << strlen(name1) << " 자입니다만\n";
cout << sizeof(name1) << "바이트 크기의 배열로 저장되었습니다.\n";
cout << "이름이" << name1[0] << "자로 시작하시는군요.\n";
name2 [3]='\0'; // \0 을 넣어줌으로써 문자열이 끝남을 알림.
cout << "제 이름의 처음 세 문자는 : ";
cout << name2 << endl;
return 0;
}
와우, cout 분리 잘 해야겠다는 생각이 듭니다.
#include <iostream>
#include <cstring>
using namespace std;
int main(){
const int Size = 15;
char name1[Size]; // 비어있는 배열
char name2[Size] = "C++Programaing"; // 문자열 상수로 초기화
cout << "안녕하세요. 저는 " << name2;
cout << "입니다 ! 성함이 어떻게 되십니까?\n";
cin >> name1;
cout << "음, " << name1 << "씨, 당신의 이름은";
cout << strlen(name1) << " 자입니다만\n";
cout << sizeof(name1) << "바이트 크기의 배열로 저장되었습니다.\n";
cout << "이름이" << name1[0] << "자로 시작하시는군요.\n";
name2 [3]='\0'; // \0 을 넣어줌으로써 문자열이 끝남을 알림.
cout << "제 이름의 처음 세 문자는 : ";
cout << name2 << endl;
return 0;
}
따라서,
// 변수와 사용자의 입력을 받을 최대 크기를 명시해준다면 공백을 포함해서 저장할 수 있습니다.
cin.getline(name1, Size);
#include <iostream>
using namespace std;
int main(){
char char1[20];
char char2[20]= "jaguar";
string str1;
string str2= "panda";
// char1= char2; //틀림.
str1 = str2; //가능함. -> 복합데이터 string의 장점.
cout << str1[0] << endl;
return 0;
}
->하나의집합으로 넣으면 좋음
#include <iostream>
using namespace std;
struct ex12{
string name;
string position;
int height;
int weight;
} B;
int main(){
// 1번 방식 , 멤버연산자 사용해서 각각 입력
// ex12 A;
// A.name = "Son"; // 변수명.ㅇㅇ 방식으로 접근할 수 있음
// A.position = "WorldClass";
// 2번 방식
ex12 A = {"Son","WorldClass",183,73};
cout << A.name << endl;
cout << A.position << endl;
cout << A.height << endl;
cout << A.weight << endl;
// 모든 값을 대입할 필요는 없음. 빈 값은 0으로 대입됨
B = {
};
cout << "B struct " << B.height << endl;
// 구조체 배열
ex12 C[2]={
{"A","A",1,1},
{"B","B",2,2}
};
cout << C[1].height << endl;
return 0;
}
#include <iostream>
using namespace std;
int main(){
// 열거체 enum
// 열거체에 정수를 대입할 수 있음. 즉, red =0, orange= 2, 이렇게 대입하고 나면 yellow 는 3이됨.
// 이유 : +1씩 해주기 때문 = > 열거체 특성.
enum spectrum {red,orange, yellow, green, blue, violet, indigo, ultraviolet};
/*
1. spectrum을 새로운 데이터형 이름으로 만듭니다.
2. spectrum 에서 정의된 0에서부터 7까지 정수 값을 각각 나타내는 기호 상수로 만듭니다.
-> 즉, spectrum에 있는 red 는 0 , orange 는 1 ... (이런식)
*/
// 열거체에서 특징이 사용된 열거자들을 상수로서(기호상수) 관리 해야하기 때문에, 산술연산 적용 불가능.
// EX) spectrum a = orange + yellow; 이건 불가능.
spectrum a = orange;
cout << a << endl;
int b;
b = blue;
b = blue + 3; // int형 변수에 값을 대입하고자 할때는, 열거자들의 값은 int형 정수자로 계산됨, 이떄 blue 는 4를 가지고 있기 때문에
cout << b << endl;
return 0;
}
#include <iostream>
using namespace std;
int main(){
/*
int *a; // C 스타일
int* b; // C++ 스타일
int* c, d; // c는 포인터 변수 , d는 int형 변수로 선언됨.
*/
int a =6; // 수
int* b; // 포인터는 위치를 나타냄.
b = &a;
cout << "a의 값 " << a <<endl;
cout << "*b의 값" << *b <<endl; // 포인터로 선언된 변수의 값을 확인할 때는 * 를 붙여서 출력
cout << "a의 주소" << &a <<endl;
cout << "*b의 주소" <<b <<endl; // 포인터로 선언된 변수의 주소를 확인할 때는 아무런 표시없이 변수명만으로 출력
*b = *b +1; // 포인터의 주소의 값에 변화를 줘서 값을 수정
cout << "이제 a의 값은" << a << endl;
return 0;
}
int* p = new int;
// new int 형 데이터를 지정할 수 있는 새로운 메모리가 필요하다고 초기화.int* ps = new int; // 메모리 사용
delete ps;
new[]
로 메모리를 대입할 경우, delete[]
로 해제합니다. 예제
#include <iostream>
using namespace std;
int main(){
double* p3 = new double[3]; // double 형 데이터 3개를 저장할 수 있는 공간을 대입합니다.
p3[0] = 0.2; // p3를 배열 이름처럼 취급합니다.
p3[1] = 0.5;
p3[2] = 0.8;
cout << "p3[1] is " << p3[1] << ".\n";
p3 = p3 +1; // 포인터를 증가시킵니다.
cout << "Now p3[0] is " << p3[0] << " and ";
cout << "p3[1] is " << p3[1] << ".\n";
p3 = p3 - 1; // 다시 시작 위치를 지시합니다
delete[] p3; // 배열 메모리를 해제합니다. new에서 대괄호 사용했으니 당연지사 delete도 대괄호 사용
// cin.get();
return 0;
}
해당 코드중 제일 중요한 부분이 있습니다.
p3 = p3+1;
배열에 이 값을 더하는 행위는, 지금 예제처럼 p3가 포인터라면 맞는 표현이고,
p3가 단순한 배열 이름이라면, 틀린것입니다.
왜냐? 배열이름이라면 값을 변경할 수 없기 때문입니다.
포인터는 변수처럼 사용할 수 있어서 값을 변경할 수 있음.
즉, 다시 말해 포인터 변수에 1을 더하게되면 그 포인터가 지시하는 데이터의 바이트 수만큼 증가하게됨.
new를 사용한 후에는 반드시 delete를 사용해야 합니다.
그렇지 않은 경우에는 대입은 되었지만, 나중에 사용되지 않는 메모리 누수가 발생할 수 있고,
메모리 누수의 규모가 매우 커지게 될 수 있고, 이런 경우 프로그램은 먹통이 됩니다.
예시)
배열 생성,
재래적 / 절차적 프로그래밍 : 배열의 크기가 (컴파일 시간에)미리 결정
객체지향 프로그래밍 : 배열의 크기를 실행 시간에 결정
#include <iostream>
#define SIZE 20
using namespace std;
int main(){
char animal[SIZE];
char* ps;
cout << "동물 이름을 입력하세요\n";
cin >> animal;
//동적 구조체 생성하는게 더 나을 것 같음. -> 다음 예제
ps = new char[strlen(animal+1)];
// stren 소괄호로 둘러싸인 이 변수의 크기를 반환하는 함수 , +1은 넉넉한 공간을 확보하기 위해 더해줌. 실행시간에 배열읰 크기 정해줌
strcpy(ps, animal); // animal의 값을 ps에 복사하는 역할
cout << "입력하신 동물 이름을 복사하였습니다." << endl;
cout << "입력하신 동물 이름은 " << animal << "이고, 그 주소는 " << (int*)animal << " 입니다." << endl;
cout << "복사된 동물 이름은" << ps << "이고, 그 주소는 "<< (int*)ps << " 입니다." << endl;
return 0;
}
.
멤버 연산자를 " -> " 로 바꿈
#include <iostream>
using namespace std;
struct My{
char name[20];
int age;
};
int main(){
My* temp = new My;
cout << "당신의 이름을 입력하세요 \n";
cin >> temp -> name;
cout << "당신의 나이를 입력하세요 \n";
cin >> (*temp).age; // -> 가 싫으면 이렇게 접근해도 됨.
cout << "안녕하세요 ! " << temp -> name << "씨!\n";
cout << "당신은 " << temp -> age << "살 이네여.";
return 0;
}
b++
: ++가 앞에 붙으면 변수의 값을 판단하고 나중에 증가
++b
: b초기화 값에 1을 추가하고 판단
#include <iostream>
using namespace std;
int main (){
char a[10] = {'a','b','c','d','e'};
for (size_t i = 0; i < 5; i++){
cout << a[i] <<endl;
} return 0;
}
// 1
#include <iostream>
using namespace std;
int main(){
string str ="Panda"; //개행 문자를 포함하고 있음.
int i=0;
// null 문자가 아닐 때 동안 반복함 - > 자바로는 while (st.hasMoreTokens()) 라고 보면 될듯.
while (str[i] !='\0'){
cout << str[i] << endl;
i++;
}
return 0;
}
// 2 do while
#include <iostream>
using namespace std;
int main(){
int j=false;
do{
cout << "while문 입니다.\n";
j++;
} while (j);
return 0;
}
for(a:b)
: a= 출력하고 싶은 데이터 형과 똑같은 데이터형 선언 / b= 콜론 다음에 배열의 이름을 대입
해당 반복문은, 배열의 사이즈 끝까지 출력하기 때문에, 0으로 초기화된 나머지 값을 출력하게 됨. (주의)
#include <iostream>
using namespace std;
int main(){
int a[5] = {1,3,5,7,9};
for ( int i = 0; i < 5; i++){
cout << a[i];
}
cout << "\n";
cout << "강화 for문" << "\n";
for(int i : a){
cout << i;
}
return 0;
}
#include <iostream>
using namespace std;
int main(){
cout << "당신의 나이를 입력";
int age;
cin >> age;
if(age <0||age >100){
cout << "구라치지마\n";
}else if (20 <=age && age<30){
cout << "20대군요,\n";
}else cout << "당신의 나이를 잘 모르겠습니다\n";
return 0;
}
#include <iostream>
using namespace std;
int main(){
int n = 0;
while (true){
cout << "n 의 값은" << n << "입니다" << endl;
if (n>10)
break;
n++;
}
cout << "while 종료" << endl;
return 0;
}
#include <iostream>
using namespace std;
const int SIZE =30;
int main(){
cout << " 문장을 입력" << endl;
char line[SIZE];
cin.get(line,SIZE);
cout << "입력하신 문장은\n";
int spaces =0;
// 개행 문자를 받기 전까지 반복
for (int i=0; line[i]!='\0';i++){
cout << line[i];
//만약 공백 입력시 spaces 늘어나지 않고 반복문으로 돌아감.
if (line[i] != ' ')
continue;
spaces++;
}
cout << "입니다.\n";
cout << "입력하신 문장에서 공백을 제외한 문자 수는" << spaces << "개 입니다.\n";
cout << "while문 종료" << endl;
return 0;
}
강의로만 c++을 공부를 진행한 필자는 문득, 궁금했습니다.
왜 c++ 에서는 void main()이 아닌, int main() 함수로 시작을 하는 것일까?
- 그냥 간단히 반환값 때문일까?
- 에러 발생유무를 확인하려고 그러는 것일까?
라는 생각들을 했었습니다.
하지만, 이유는 간단했습니다. void main()은 반환값이 없는 함수를 의미하며,
C++ 표준에서는 main() 함수가 반드시 반환값을 가져야 한다고 명시되어 있습니다.
따라서, void main()을 사용하는 것은 C++ 표준을 위반하는 것이게 됩니다.
결론 : int main() 함수 사용 후 return 해주자.
정답: 식에 클래스 형식이 있어야하는데
float
형식이 있습니다.한마디로
cout << a
를 해줘야 실수형이 출력 가능하다는 것입니다.c 언어는
printf 변수명.f
해줬어야 했으나, c++ 은 변수명만 작성하면 출력됩니다.