저자: Stephen Prata
배열, 구조체, 포인터 → C++ 의 복합 데이터형
초기화 형식은 배열을 정의하는 곳에서만 사용할 수 있다.
int yamcosts[3] = {20, 30, 5}; (o)
책 내용은 C++11 배열 초기화에 대해 다루는데, 내가 수행할 과제는 C++98에 맞춰야 해서 C++98허용 규칙 내용 위주로 정리.
선언 시점에만 배열 초기화 가능
크기 생략 가능
int yamcost[] = {20, 30, 5};
컴파일러가 배열 원소의 개수를 결정하도록 위임하는 건 좋지 않다고는 하지만, 상황에 따라 다르다고 함.
부분 초기화 가능
int yamcost[5] = {20, 30}; //나머지는 0으로 자동 초기화
배열 중에서도 문자열을 구분하는 방법 → 끝에 꼭 ‘\0’
if char dog[8] = { ‘b’, ‘e’, ‘a’, ‘u’, ‘x’, ‘ ‘, ‘I’, ‘I’} → 문자열 아니다.
cout으로 출력한 경우, 우연히 널 문자를 만날 때까지 출력이 이어진다.
char fish[] = "Bubbles"; # 컴파일러가 알아서 '\0'을 넣는다.
char bird[11] = "Mr. Cheeps"; # 여기서도 '\0'이 저장된다.
문자열 입력
getline()
get()
// 이를 해결하려면 ..
cin.get(name, ArSize);
cin.get();
cin.get(dessert, Arsize);
# 아니면
cin.get(name, ArSize).get();
cin.get(dessert, Arsize).get();

헤더 간의 의존성, 계층적 설계
cin.getline(arr, size): cin이라는 객체 내부에 있는 기능을 꺼내 쓰는 것 (멤버 함수)getline(cin, str): 외부의 독립된 함수에 cin과 str이라는 재료를 던져주고 "둘이 협력해서 한 줄 읽어와!"라고 시키는 것 (전역 함수)
struct inflatable // structure declaration
// inflatable은 태그라고 불리는 새로운 데이터형의 이름이 된다.
{
char name[20];
float volume;
double price;
};
int main()
{
using namespace std;
inflatable guest =
{
"Glorious Gloria", // name value
1.88, // volume value
29.99 // price value
}; // guest is a structure variable of type inflatable
열거형 → 정수
포인터의 요약
cout 을 비롯한 대부분의 C++표현에서, char형의 배열 이름, char형을 지시하는 포인터, 큰따옴표로 둘러싸인 문자열 상수는 모두 문자열의 첫 번째 문자의 주소로 해석된다
#include <iostream>
#include <cstring> // declare strlen(), strcpy()
int main()
{
using namespace std;
char animal[20] = "bear"; // animal holds bear
const char * bird = "wren"; // bird holds address of string
char * ps; // uninitialized
cout << animal << " and "; // display bear
cout << bird << "\n"; // display wren
// cout << ps << "\n"; //may display garbage, may cause a crash
cout << "Enter a kind of animal: ";
cin >> animal; // ok if input < 20 chars
// cin >> ps; Too horrible a blunder to try; ps doesn't
// point to allocated space
ps = animal; // set ps to point to string
cout << ps << "!\n"; // ok, same as using animal
cout << "Before using strcpy():\n";
cout << animal << " at " << (int *) animal << endl;
cout << ps << " at " << (int *) ps << endl;
ps = new char[strlen(animal) + 1]; // get new storage
strcpy(ps, animal); // copy string to new storage
cout << "After using strcpy():\n";
cout << animal << " at " << (int *) animal << endl;
cout << ps << " at " << (int *) ps << endl;
delete [] ps;
// cin.get();
// cin.get();
return 0;
}

코드는 당연한 소리 하는 것 같은…데? 말이 어렵다.
어쨋든 배열에 문자열을 대입할 때에는 대입 연산자를 사용할 것이 아니라, strcpy() 또는 strncpy()를 사용하란다.
포인터와 배열과의 관계
→ 이건 c도 이러했다.
ar[i] = *(ar + i)
컴파일 단계에서 철저하게 차단vector 템플릿 클래스
#include <vector>
vector<int> vi;
vector<double> vd(n); // n개의 더블 배열을 만들어라
array 템플릿 클래스 → C++98에서는 안됨 C++11부터 가능.
| 구분 | 일반 배열 (int a[n]) | std::vector | std::array (C++11) |
|---|---|---|---|
| 메모리 위치 | 스택(Stack) | 힙(Heap) | 스택(Stack) |
| 크기 결정 | 컴파일 타임 | 런타임 (가변) | 컴파일 타임 |
| 속도 | 최상 | 보통 (동적 할당 비용) | 최상 |
| 안전성 | 낮음 (경계 검사 없음) | 높음 | 높음 |
접두어 방식과 접미어 방식
for (n = lim; n > 0; --n)
for ( n = lim; n > 0; n--)
숫자가 아닌 객체라면 후위연산자의 객체가 훨씬 무겁다!
🔎 C++ 에서 성능 최적화 관점에서 객체를 다룰 때는 전위연산자를 선호한다.
→ 후위 연산자는 증가 전의 원래 값을 기억하기 위해 임시 복사본을 만드는 과정이 필요함.
→ 정수형(int)에서는 차이가 없지만 반복자나 복잡한 객체를 다룰 때 성능상 유리함
while(1)
for (;;)
그런데 말입니다 cin은 EOF(end of file)을 어떻게 알 수 있을까?
cin.get(ch);
while(cin.fail() == false)
{
cin.get(ch);
}
조금 더 깔끔하게 개선하면,
while (cin.get(ch)) // 입력이 성공했으면 루프를 실행해라
{
}
cin.get은 문자가 아닌 객체를 리턴하는데, 혹시 문자 출력을 하고 싶으면 cin.put(ch)를 사용하면 된다. → cin.put(ch)에서 EOF의 의미는 더이상 문자가 없어요~ 라는 신호
이전에 기록한 내용 >
cin >> ch # 의미 있는 데이터만. whitespace는 무시
cin.get(ch) # whitespace까지 포함하여 모든 것을 1바이트씩 읽음
#undef isalnum
#undef isalpha
#undef iscntrl
#undef isdigit
#undef isgraph
#undef islower
#undef isprint
#undef ispunct
#undef isspace
#undef isupper
#undef isxdigit
#undef tolower
#undef toupper
// cinfish.cpp -- non-numeric input terminates loop
#include <iostream>
const int Max = 5;
int main()
{
using namespace std;
// get data
double fish[Max];
cout << "Please enter the weights of your fish.\n";
cout << "You may enter up to " << Max
<< " fish <q to terminate>.\n";
cout << "fish #1: ";
int i = 0;
while (i < Max && cin >> fish[i])
// 숫자가 아닌게 들어와서 실패하면 while을 빠져나감.
// q가 아니라 다른 숫자가 아닌 것을 입력해도 cin이 종료된다.
// cin 은 while문 안에서 bool 타입으로 자동 변환된다.
{
if (++i < Max)
cout << "fish #" << i+1 << ": ";
}
// calculate average
double total = 0.0;
for (int j = 0; j < i; j++)
total += fish[j];
// report results
if (i == 0)
cout << "No fish\n";
else
cout << total / i << " = average weight of "
<< i << " fish\n";
cout << "Done.\n";
// code to keep VC execution window open if q is entered
// if (!cin) // input terminated by non-numeric response
// {
// cin.clear(); // reset input
// cin.get(); // read q
// }
// cin.get(); // read end of line after last input
// cin.get(); // wait for user to press <Enter>
return 0;
}
주석 처리 된 부분이 입력 버퍼에 남아 있는 q에 대한 내용이다.