45강. 매크로를 자세히 알아보자
#define PI 3.14159
PI라는 값 자체는 변수처럼 사용할 수 없음. 상수를 #define으로 정의해 별명처럼 사용한다. 그런데 매크로는 상수 뿐만 아니라 식도 들어갈 수 있음.
#define PRINT_HELLO print("hello! world");
식도 매크로로 별명을 붙여줄 수 있다.
#include <stdio.h>
#include <stdio.h>
int square(int a) {
return a * a;
}
int main() {
int a;
scanf_s("%d", &a);
}
함수를 작성하면 이렇게 작동하는데, 만약 함수기능을 매크로로 실행하고 싶다면?
#include <stdio.h>
#define SQUARE(X) X*X
//square라는 X라는 매크로를 갖는다.
int main() {
int a;
scanf_s("%d", &a);
printf("%d\n", SQUARE(a));
}
#define SQUARE(X) X*X 는 square는 X라는 매크로를 갖는데 이때 X*X로 계산하라. 라는 의미.
그런데 문제점이 있다. SQUARE(a)는 단순이 a*a로 교체가 되는데, 100/SQUARE(a)가 있다면?
나눗셈을 먼저 계산하고 거기에 *연산이 들어감. 안전하게 계산하려면 처음 정의할 때 부터 연산 순서를 맞게 적어주는 게 좋다. --> #define SQUARE(X) (X*X)
df
46. 비트 연산
22= 10110(2)
8비트니까 00010110(2)으로 저장되겠다.
비트연산을 종류로 나눠보면
1) 비트 논리 연산: 논리연산을 비트 논리연산으로 계산하는 것.
논리연산: && || !
비트연산: & | ~ ^
2)시프트 연산 : 비트를 이동하고(왼쪽, 오른쪽) 옮기는 것
왼쪽 시프트 <<
오른쪽 시프트 >>
47강. 파일 입출력
input.txt라는 파일을 생성
output.txt 파일도 생성
cpp파일에 간단한 int main()프로그램 작성.
scanf_a()에서 input.txt라는 파일을 입력받아와서 -> 콘솔창에 출력해보자.
int n;
1) 파일을 가리키는 포인터를 만든다. EX) FILE *in;
2) in = fopen("input.txt","r"); : fopen이란 파일을 가리키는 포인터를 반환하는 함수를 사용
3)fscanf_s(in, "%d", &n); : fscanf라고 써야하고 in이라는 매개변수 하나 추가
4) out = fopen("output.txt", "r");
5) fprintf(out, "%d\n", n);
6) fclose(in);
7) fclose(out);
48강. 유용한 함수들
- 입출력과 관련된 유용한 함수들
//getchar 문자를 받는다/ putchar 문자를 출력받는다.
//gets 문자열을 입력받고/ puts 문자열을 출력하는
//getchar 문자를 받는다/ putchar 문자를 출력받는다.
//gets 문자열을 입력받고/ puts 문자열을 출력하는
#include <stdio.h>
int main() {
char ch; //입력받을 변수
ch = getchar(); //getchar(c)라고 쓸 필요 없음
putchar(ch); //putchar()로 출력
}
#include <stdio.h>
int main() {
char str[100];
gets(str); //매개변수로 받아와야됨. getchar만 매개변수 필요없음.
puts(str);
}
문자열 자체를 printf하거나 문자열 자체를 scanf할 수 있음
sscanf / sprintf
#include <stdio.h>
int main() {
char str[] = "450"; //문자열을 정의
int n;
sscanf(str, "%d", &n); //n에 450이 들어감
printf("%d\n", n);
}
C++ 스타일 입출력
C++ 첫시간!
#include <iostream>
int main() {
std::cout << "Hello, World" << std::endl;
}
std::cout : name space (이름에 성이 들어가는 부분)
<< "Hello, World" <<: 출력이 나오는 곳
std::endl; end line이라는 의미로 줄바꿈이라는 뜻
그런데 계속 std::치는 게 너무 귀찮다. 이걸 생략하려면
#include <iostream>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
cout << "Hello, World" << std::endl;
}
using namespace std;
을 매번 써주면 된다. 마치 #include <stdio.h>처럼!!
입력을 받는 방법: cin >> >> ;
#include <iostream>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
int a, b;
cin >> a >> b;
cout << a << "+" << b << a + b << endl;
}
장점:
1) 배열의 길이가 자유로움, 정해놓지 않아도 됨.
2) +기호로 string들을 연결할 수 있음.
EX)
string name;
cin >> name;
string message = "안녕" + name + "아." ;
#include <iostream>
#include<string>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
string str; //배열형태가 아님, 길이를 굳이 정해놓지 않아도 됨. 길이가 무한정
str = "Hello";
cout << str << endl;
}
50강. C++ 스타일 기본 문법
#include <iostream>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
int a(10); //int a=10;
a = 5; //변수의 대입 a(5);라고 쓸 수는 없음.
int b(a);
cout << "a =" << a << endl; //cout은 출력
cout << "b =" << b << endl; //cout은 출력
}
- 범위 기간 for문 : n의 값은 for문안의 일반적인변수이다.
//범위 기반 for문: 배열내에서 편하게 for문 사용가능
#include <iostream>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
int arr[10] = { 3,1,4,1,5,9,2,6,5,3 };
for (int n:arr) {
cout << n << endl;
}
}
- &과 r-value &&
#include <iostream>
using namespace std; //std라는 이름공간을 사용하겠다.
int main() {
int a(5);
int& r1 = a;
//int& r2 = 3; 포인터가 상수를 가리키기는 불가능
//int& r3 = a * a; 식 값 가리키기도 불가능
//수정할 수 없는 값들은 &&을 붙여주면 됨.
int&& r2 = 3;
int&& r3 = a * a;
}
- overload : 다중 정의, 여러개로 정의
#include <iostream>
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
void swapd(double& a, double& b) {
double tmp = a;
a = b;
b = tmp;
}
void swapp(int* (&a), int* (&b)) {
int *tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 20, b = 30;
double da = 2.222, db = 3.333;
int* pa = &a, *pb = &b;
swap(a, b);
swapd(da, db);
swapp(pa, pb);
}
그런데 자료형이 다양할 수록 함수를 많이 써야하니까 불편함. C++에서는 함수이름을 갖게 해도 된다.
#include <iostream>
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
void swap(double& a, double& b) {
double tmp = a;
a = b;
b = tmp;
}
void swap(int* (&a), int* (&b)) {
int *tmp = a;
a = b;
b = tmp;
}
int main() {
int a = 20, b = 30;
double da = 2.222, db = 3.333;
int* pa = &a, *pb = &b;
swap(a, b);
swapd(da, db);
swapp(pa, pb);
}
함수이름을 갖게해도, 매개변수의 자료형이 다르면 --> C++이 알아서 구분해서 분류함.
53강. 네임스페이스
어떤 변수나 함수의 이름이 같을 때, 네임 스페이스를 써주면 구별이 가능하다.
#include <iostream>
using namespace std;
int n; //전역변수
void set() {
::n = 10; //명시적 전역변수
}
namespace doodle {
int n;
void set() {
doodle::n = 20;
}
}
namespace google {
int n;
void set() {
google::n = 30;
}
}
int main() {
::set(); //전역 10
doodle::set(); //20
google::set(); //30
}
특정한 네임스페이스 안에서 변수,함수의 소속을 밝히지 않은 경우, 자기가 속한 네임스페이스 안의 변수이다.
즉 소속을 굳이 밝혀주지 않고 변수나 함수의 이름만 써주면 된다.
#include <iostream>
using namespace std;
int n; //전역변수
void set() {
n = 10; //명시적 전역변수
}
namespace doodle {
int n;
void set() {
n = 20;
}
}
namespace google {
int n;
void set() {
n = 30;
}
}
int main() {
::set(); //전역 10
doodle::set(); //20
google::set(); //30
}
'컴퓨터과학 > C언어 C++스터디' 카테고리의 다른 글
두들낙서 C/C++ 1주차 1-18강 (0) | 2022.03.05 |
---|