ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 03. 제어구조와 배열2
    C++ 2021. 1. 22. 13:46

    제어구조와 배열 (2)

     


    < ex19_multi_array.cpp >

     

    #include <iostream>
    
    using namespace std;
    
    #define WIDTH 9
    #define HEIGHT 3
    
    
    int main(int argc, char const *argv[]) {
    
    int table[HEIGHT][WIDTH];
    int r, c;
    
    for (r = 0; r < HEIGHT; r++){
    	for (c = 0; c < WIDTH; c++){
    		table[r][c] = (r+1) * (c+1);
    	}
    }
    
    for (r = 0; r < HEIGHT; r++){
    	for (c = 0; c < WIDTH; c++){
    		cout << table[r][c] << ", ";
    	}
    
    	cout << endl;
    }
    
    return 0;
    
    
    }

     

     

    • 다차원 배열

      • 데이터타입 배열이름[행][열];
    • 바깥 루프가 보통 높은 차원의 배열, 안쪽 루프가 보통 낮은 차원의 배열
    • c++에서는 배열의 연산 불가능
    • sizeof() -> 해당 변수에 할당된 메모리의 크기를 byte단위로 리턴해준다

     


     

    < ex18_2_advanced_for.cpp >

     

    #include <iostream>
    
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    
    int list[] = {1,2,3,4,5,6,7,8,9,10};
    
    int list2[10];
    
    // int 하나는 4byte
    
    int length = sizeof(list) / sizeof(int); // 40 / 4 -> 10 (엘리먼트 개수)
    
    // list 메모리 크기 : int 크기(4) * 10개 -> 40byte
    
    cout << length << endl;;
    
    // 복사 전 list2 출력, 초기화 안 된 배열
    
    // 출력 -> 14292736 0 16 0 0 0 4200206 0 4199744
    // 지역변수는 초기화되지 않으면 임의의 값을 가진다
    // 0으로 초기화되지 않는다
    for(auto i: list2){
    cout << i << " ";
    }
    // 복사
    
    for (int i = 0; i < length; i++){
    list2[i] = list[i]; // 엘리먼트 단위로 복사
    
    }
    
    // 복사 후 lsit2 출력
    
    for(auto i: list2){
    
    cout << i << " ";
    
    }
    
    return 0;
    
    
    cout << list << endl
    
    // 0x61fda0 출력, 주소값 출력
    
    }
    
    

     


     

    < ex01_func.cpp >

     

    #include <iostream>
    
    using namespace std;
    
    // 함수의 존재 밝혀준다, 함수 원형, 뒤에 나올 것이다
    
    // 매개변수의 이름은 생량 가능하다
    
    int max(int x, int y);
    
    
    int max(int x, int y){
    if (x > y){
    return x;
    }
    else
    {
    return y;
    }
    
    }
    
    int main(int argc, char const *argv[]) {
    
    int n;
    
    n = max(2,3);
    
    // C++는 함수를 정의 전에 호출해도 요즘 컴파일러는 돌아간다, 컴파일러에 따라 상이
    
    // 컴파일러는 매개변수가 매칭이 잘 되고 있는가, 리턴값 맞는가를 체크
    
    // 컴파일러가 해석할 수 있는 정보는 int max(int x, int y); 에 다 있다
    
    cout << "result : " << n << endl;
    
    return 0;
    
    }

     

     

    • 함수의 구조

      • 반환형 함수이름(매개변수){}

      • ex) int max(int x, int y){}

      • 반환형 생략시 디폴트로 int 배정

      • void -> 리턴데이터가 없는 때

         


     

    • 함수 인자 전달 방법

      • call by value

        • 값 복사
      • call by reference

        • &(참조변수), 원본에 대한 참조로 매개변수 넘기는 것
        • 참조변수 -> 기존 변수에 새로운 운영 이름 추가하는 것, 저장공간은 하나
        • 참조변수는 초기화문과 같이 써야 한다, 분리되어 있으면 안 된다 (이름을 붙여야 하는데 이름을 붙일 곳이 없는 상황)
        • 참조변수는 주로 매개변수 처리할 때 사용한다
        • 원본을 다른 함수에서 참조매개변수를 통해서 수정할 수 있다
      • call by address (pointer)

      • 사용자가 선택해서 쓰면 된다

      • 파이썬은 call by value, call by reference가 일어나는 데이터타입이 정해져 있다

     


     

    < ex04_overload.cpp >

     

    #include <iostream>
    using namespace std;
    
    
    int square(int i){
    
    cout << "square(int) : " << endl;
    
    return i*i;
    }
    
    double square(double i){
    cout << "square(double) : " << endl;
    return i*i;
    }
    
    int main(int argc, char const *argv[]) {
    cout << square(10) << endl;
    cout << square(2.0) << endl;
    return 0;
    }

     


     

    < ex05_default_param.cpp >

     

     

    #include <iostream>
    using namespace std;
    
    void display(char c = '*'){
    for (int i = 0; i < 20; i++){
    cout << c;
    }
    
    cout << endl;
    }
    
    void display(char c = '*', int n = 10){
    for (int i = 0; i < n; i++){
    cout << c;
    }
    cout << endl;
    }
    
    int main(int argc, char const *argv[]) {
    
    display(); // 허용 X, 둘 다 호출가능한 형태
    
    display('#'); // 허용 X, 둘 다 호출가능한 형태
    
    display('#', 5); //후자의 display
    
    return 0;
    
    }

     

    • 중복 함수 (overload)

      • 함수의 이름은 동일하지만 함수의 인자가 다르면 다른 함수로 인식

      • 동일한 이름의 함수를 여러개 만들 수 있다

      • 함수 중복 체크할 때 리턴타입을 보지 않는다 (함수의 이름과 매개변수만 체크한다)

         


     

    < ex05_2_array_func.cpp >

     

    #include <iostream>
    using namespace std;
    
    void initArray(int array[], int size, int value = 0){
    
    // int value = 0는 call by value, & 없기 때문, 대입연산을 통해서 값이 대입될 수 있어야 한다
    // int array[] -> 비워두면 초기화식의 엘리먼트의 개수에 따라 결정된다, 범용함수
    // 호출될 때 결정된다, 배열의 크기 한정짓지 않았다
    
    // int size = sizeof(array) / sizeof(int);
    int array[] -> call by address (원본으로 작업)
    for (int i = 0; i < size; i++){
    array[i] = value;
    }
    }
    
    void printArray(int array[], int size){
    
    // int size = sizeof(array) / sizeof(int);
    
    for(int i = 0; i < size; i++){
    cout << array[i] << " ";
    }
    cout << endl;
    }
    
    int main(int argc, char const *argv[]) {
    const int ARRAY_SIZE = 40;
    int intList[ARRAY_SIZE];
    
    initArray(intList,ARRAY_SIZE, 100); // 두 번째 인자 값으로 초기화
    printArray(intList, ARRAY_SIZE);
    initArray(intList, ARRAY_SIZE); //인자 하나, 0으로 초기화
    printArray(intList, ARRAY_SIZE);
    
    return 0;
    
    }

     

    • 배열의 개수는 상수로 운영하는 걸 추천
    • 배열은 call by value 불가능! call by address 방식으로 전달한다 (배열1 = 배열2; 불가능)
    • 배열1 = 배열2; 허용되면 call by value 가능, 안 되면 call by value 불가능

     


     

    < ex06_string.cpp >

     

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    string s1 = "Slow", s2 = "steady";
    // s1은 string 객체의 인스턴스
    string s3 = "the race.";
    string s4;
    s4 = s1 + " and " + s2 + " wins " +s3;
    cout << s4 << endl;
    
    return 0;
    }

     

    • string 클래스

      • 문자열 데이터 저장 및 처리 함수(메서드) 제공
      • #include <string>을 먼저 지정 후 사용</string>
    • 파이썬의 문자열은 조작 불가능 (불변)

    • c++ 문자열은 조작 가능

      • s.empty(), s.insert(), s.remove(), s.find(), s.reverse()

     


     

    < ex07_string.cpp >

     

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    
    string s1, addr;
    
    cout << "name : ";
    cin >> s1;
    
    // enter를 치면 "홍길동\r\n" 입력된다
    
    // \r 입력되면 문자열이 끝났다고 생각함, 홍길동이 s1에 들어간다
    
    // getline은 줄바꿈 문자열이 있을 때까지, \n이 남아있으니 새로운 문자열 받지 않고 자동으로\n을 받는다
    // ignore()을 사용하게 되면 \n을 제거하고 쓰라는 뜻
    cin.ignore(); // 엔터키 제거
    // 주소는 공백이 들어가니
    
    cout << "address : ";
    getline(cin, addr);
    
    cout << addr << "'s " << s1 << " sir hello" << endl;
    
    return 0;
    }

     


     

    < ex08_string.cpp >

     

     

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    string s = "when in rome, do as the romans";
    
    int size = s.size();
    int index = s.find("rome");
    
    cout << size << endl;
    cout << index << endl;
    s. insert(0, "hello"); // 맨 앞에 문자열 추가
    cout << s << endl;
    
    s += "end of world" // 맨 뒤에 문자열 추가
    cout << s << endl;
    s.append("\n-------------\n"); // 맨 뒤에 문자열 추가
    cout << s;
    
    
    return 0;
    
    }
    • sizeof(s) -> 항상 32 리턴, 스트링 객체의 크기는 항상 32 바이트

      • string 객체의 인스턴스에 데이터가 있다는 것이 아니라 다른 곳에 데이터가 있다는 뜻
      • 스택에는 자신의 데이터의 주소를 가지고 있다
      • 힙에 실제 데이터 저장, 관리
    • s.size -> 문자열의 사이즈 리턴

      • size는 힙에 있는 실제 데이터의 길이를 리턴해주는 것
    • 파이썬은 해당 인스턴스가 힙에 만들어진다

    • c++은 실제 데이터의 저장공간이 힙에 만들지 스택에 만들지 선택할 수 있다

    • 스트링 객체 내부 관리 데이터의 크기가 32바이트라는 뜻

     


     

    < ex09_string.cpp >

     

     

     

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    string s = "when in rome, do as the romans";
    // 읽기
    
    for(auto& ch : s){ // char &ch = s[i], 참조, 속도 더 빠름
    cout << ch << ' ';
    }
    cout << endl;
    for (auto ch : s){ // char ch = s[i], 새로운 변수 만들고 값 복사
    cout << ch << ' ';
    }
    
    cout << endl;
    
    // 읽을 때는 참조변수로 하나 값 복사하나 결과 똑같다
    
    // 쓰기 (참조와 값복사가 다름)
    for(auto& ch : s){ // char &ch = s[i], 이름만 추가, T를 위한 공간 할당 X, 원본으로 작업
    ch = 'T';
    }
    cout << s << endl;
    for (auto ch : s){ // char ch = s[i], ch를 위한 별도의 메모리 공간을 만들고 운영(1byte), 값 복사
    ch = 'W'; // 메모리 공간에 W 입력
    }
    cout << s << endl; // 원본에는 변화 X
    
    // 쓰기 작업은 속도의 문제가 아니라 원본을 수정할 것인지 아닌지의 문제
    // 속도 자체는 참조변수가 더 빠르다
    return 0;
    
    }

     


     

    < ex10_string.cpp >

     

    #include <iostream>
    using namespace std;
    
    int main(int argc, char const *argv[]) {
    string list[] = {"홍길동", "고길동", "둘리"};
    // string list[] -> 지역변수, 스택에 지정
    // 배열명 list는 상수이다, 배열명도 스택에 독자적인 메모리 공간을 가진다, 배열명은 배열의 첫 번째 엘리먼트의 주소값을 가진다 (스택), 이 값을 수정할 수 없다 (상수이기 때문에)
    // 배열1 = 배열2의 표현은 배열명을 바꾸겠다는 표현이기 때문에 불가능하다
    // 실제 배열의 데이터는 힙에 있다
    for(auto& name : list){
    cout << name << endl;
    }
    
    return 0;
    }

     

    • 내가 지금 작업중인 데이터가 어디에 있냐? 내가 복사본으로 작업하고 있는지 아니면 원본으로 작업하고 있는지 (스택 or 힙) -> 항상 신경쓰기

    'C++' 카테고리의 다른 글

    04. 클래스와 객체  (0) 2021.01.27
    [열혈 C++] 02. C언어 기반의 C++ 2  (0) 2021.01.22
    [열혈 C++] 01. C언어 기반의 C++ 1  (0) 2021.01.22
    02. 제어와 배열  (0) 2021.01.21
    01. C++ 기초사항  (0) 2021.01.21

    댓글

Designed by Tistory.