C++ 클래스와 객체




안녕하세요 열코입니다.

저번 시간에 C/C++ 구조체에 대해 알아보았습니다. (구조체 공부하러가기)

이번시간에는 구조체와 비슷한 형태의 구조를 가진 클래스에 대해 알아보겠습니다.

(여담으로 C++이 세상에 나오기 전 C의 구조체를 모티브로 만든것이 C++의 클래스라고합니다.)


C++은 객체지향 프로그래밍의 대표적인 언어로써 객체지향 프로그래밍 언어의 구성요소인 클래스를 사용할 수 있습니다.


☞ 클래스(class)란?

사용자 정의 데이터 유형으로 데이터 멤버 및 멤버 함수가 포함되어 있으며, 

해당 클래스의 객체(Object 또는 Instance)를 생성하여 접근(Access)하고, 사용할 수 있습니다.


예를들어, 자동차라는 데이터 타입(변수)를 만들고자 할 때, 우리는 여러가지 변수와 함수 중 

바퀴의 수, 속도 제한, 주행 거리 등의 공통 속성을 찾아 만들어야 합니다.


또한 클래스가 정의 될 때 메모리에 할당되지 않으며 객체가 생성될 때 메모리가 할당됩니다.



 클래스 정의 및 객체 선언 방법?

클래스의 정의 방법은 구조체의 정의 방법과 유사합니다.

아래의 예제를 확인하세요.


1
2
3
4
5
6
7
8
9
10
11
12
using namespace std;
 
// 클래스 정의
class member {
 
};
 
int main(void) {
    member m1; // 객체 생성
    
    return 0;
}
cs


class라는 키워드를 사용하여 클래스를 정의하고, 일반 변수 선언하듯이 (int a;) 객체를 생성해서 사용할 수 있습니다.

하지만 구조체와 다른 점으로는 데이터 멤버에 접근 지정자를 지정해 줄 수 있습니다.

접근 지정자는 3가지로 나뉘는데


public, private, protected 이렇게 3가지로 나뉩니다.


public 멤버는 공개 데이터 맴버로 클래스 내부 및 외부에서도 객체를 통해 접근이 가능합니다.

private 멤버는 비공개 데이터 멤버로 클래스 내부에서만 접근이 가능합니다.

protected 멤버는 보호된 데이터 멤버로 상속된 클래스 한정 접근 가능합니다.

(protected에 대해서는 상속 시간에 더 자세히 알아보겠습니다. ^^)



public 및 private 접근 지정자는 아래와 같이 지정해 줄 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <string>
using namespace std;
 
class member {
private :
    int id;
    string name;
    
public :
    void print_name() {
        cout << name;
    }
 
};
 
int main(void) {
    member m1;
    
    return 0;
}
cs


☞ 클래스의 멤버 함수 정의 방법?

멤버 함수를 정의하는 방법은 두 가지가 있습니다.

첫번째는 내부 클래스 정의이며, 두번째는 외부 클래스 정의입니다.

내부 클래스 정의는 말 그대로 클래스 내부에 멤버 함수를 정의하는 것이고,

외부 클래스 정의는 :: 연산자(scope resolution)를 사용해야 합니다.

아래는 외부 클래스 정의의 예제 코드입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <string>
using namespace std;
 
class member {
private :
    int id;
    string name;
    
public :
    // 내부 클래스 정의
    void print_name() {
        cout << name;
    }
 
    // 외부 클래스 정의
    void print_id();
};
 
// 외부 클래스 정의
void member :: print_id() {
    cout << id;
}
 
int main(void) {
    member m1;
    
    return 0;
}
cs


☞ 생성자, 소멸자?

클래스는 객체가 인스턴스화(객체 생성) 될 때마다 컴파일러에 의해 호출되는 특수 메소드가 있는데,

바로 생성자 라는 함수입니다.

생성자, 소멸자에는 다음과 같은 유형이 있습니다.


1. 디폴트 생성자

2. 매개변수 생성자

3. 복사 생성자

4. 소멸자


처음 들으신 분들은 많이 생소하실수도 있지만 하나씩 설명해 나가겠습니다.



1. 디폴트 생성자

첫번째 디폴트 생성자는 사용자가 직접 생성자를 정의해 주지 않아도 알아서 만들어지는 생성자입니다.(눈에 보이진 않습니다.)

내부적으로 알아서 처리되는 녀석인데

이를 사용자가 직접 정의해 줄 수 있습니다.

아래 예제 코드는 디폴드 생성자 예제입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
}
cs


디폴트 생성자는 위와 같이 사용자가 직접 정의해 줄 수 있습니다.

함수 반환형은 없으며, 함수 이름은 클래스의 이름과 동일합니다.


2. 매개변수 생성자

두번째로 매개변수 생성자입니다.

매개변수 생성자를 통해 객체 생성 시 클래스 멤버 변수의 값을 초기화 할 수 있습니다.

아래 예제 코드는 매개변수 생성자 예제입니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    // 매개변수 생성자
    Point(int x, int y) {
        this->= x;
        this->= y;
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
 
    Point p2 = { 34 };
    p2.print();
}
cs


매개변수 생성자는 생성자 함수 매개변수로 값을 넘겨받아 클래스 멤버 변수를 초기화 할 때 사용합니다.

매개변수 생성자 안의 this 키워드는 클래스 자신의 객체를 가리키는 특수 키워드로써 자기자신을 의미한다고 생각하시면 됩니다.



3. 복사 생성자

복사 생성자는 기존의 객체를 복사하여 새로운 객체를 생성합니다. 컴파일러는 모든 클래스의 기본 복사 생성자를 제공합니다.


1
2
3
4
5
6
7
int main(void) {
    Point p;
    p.print();    
 
    Point p2 = p;
    p2.print();
}
cs


Point p2 = p; 에서처럼 컴파일러에서 제공하는 디폴트 복사 생성자를 호출하는 모습입니다.

나중에 시간이 되면 이 복사 생성자에 대해서도 자세히 알아보도록 하겠습니다!


4. 소멸자

소멸자는 객체의 사용이 모두 끝날 때 컴파일러에서 호출하는 특수 멤버 함수입니다.

생성자와 같이 디폴트 소멸자가 기본적으로 생성됩니다.

보통 클래스 내에서 동적 할당한 메모리를 해제할 때 유용하게 사용됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;
 
class Point {
private :
    int x;
    int y;
    
public :
    // 디폴트 생성자
    Point() {
        x = 10;
        y = 15;
    }
    // 매개변수 생성자
    Point(int x, int y) {
        this->= x;
        this->= y;
    }
 
    // 디폴트 소멸자
    ~Point() {
        cout << "소멸자 호출\n";
    }
    void print() {
        cout << "X : " << x << ", Y : " << y << "\n";
    }
};
 
int main(void) {
    Point p;
    p.print();    
 
    Point p2 = p;
    p2.print();
}
cs



이상 '클래스와 객체'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C++ 함수 오버로딩  (0) 2018.10.11
C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26



안녕하세요 열코입니다.

이번시간에는 C/C++에서 구조체의 사용법과 간단한 예제에 대해 알아보도록 하겠습니다.


☞ 구조체란?

구조체는 C/C++에서 사용자 정의 데이터 형식입니다.

구조체는 다른 유형의 항목들을 단일 유형으로 그룹화하는데 사용합니다.

쉽게말해 int, char, double과 같은 자료형을 사용자가 임의로 만드는 것입니다.


☞ 구조체 만드는 방법?

struct 키워드를 사용하여 구조체를 작성합니다.

아래는 구조체 작성 예제입니다.


1
2
3
4
5
struct student {
    char name[20];
    char address[100];
    int age;
};
cs


☞ 구조체 변수 선언 방법?

구조체를 선언했으니 구조체 변수를 만들어야합니다.

int a; 와 같이 int 자료형의 변수를 만드는 것과 같은 이치입니다.


1. 첫번째 방법


1
2
3
4
struct Point {
    int x;
    int y;
} p1;
cs


2. 두번째 방법


1
2
3
4
5
6
7
8
struct Point {
    int x;
    int y;
};
 
int main(void) {
    struct Point p1;
}
cs


위와 같이 구조체 변수를 기본 자료형 처럼 별도로 선언할 수 있습니다.



* 두번째 방법에서 struct 키워드를 생략하고 싶을때

아래와 같이 typedef 키워드를 사용하여 구조체를 작성하면 구조체 변수 선언시 struct 키워드를 생략할 수 있습니다


1
2
3
4
5
6
7
8
typedef struct Point {
    int x;
    int y;
} Point;
 
int main(void) {
    Point p1;
}
cs

(최신 컴파일러 버전에서는 typedef를 사용하지 않아도 struct 키워드를 생략할 수 있습니다.)


☞ 구조체 멤버를 초기화 하는 방법?

구조체 멤버는 구조체 변수를 선언할 때 초기화해야 합니다.

다음과 같이 구조체를 작성할 때 초기화 하면 오류를 발생합니다.


1
2
3
4
struct Point {
    int x = 0;
    int y = 0;
};
cs


그 이유는 간단합니다.

데이터 유형이 선언될 때 변수가 메모리에 할당되지 않기 때문입니다.

변수가 생성이 되어야만 메모리에 할당됩니다.

(최신 컴파일러 버전에서는 오류를 발생하지 않습니다.)


구조체 멤버는 { } (중괄호)를 사용하여 초기화 할 수 있습니다.

아래의 예제를 확인하세요.


1
2
3
4
5
6
7
8
struct Point {
    int x;
    int y;
};
 
int main(void) {
    struct Point p1 = { 10 };
}
cs


☞ 구조체 멤버에 접근하는 방법?

구조체 멤버는 점(도트; .) 연산자를 사용하여 접근 할 수 있습니다.


1
2
3
4
5
6
7
8
9
struct Point {
    int x;
    int y;
};
 
int main(void) {
    struct Point p1 = { 10 };
    p1.x = 10;
}
cs


☞ 구조체 배열 사용법?

일반 자료형(int, char, double 등)과 같이 구조체(사용자 임의 자료형) 역시 배열을 만들 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
struct Point {
    int x;
    int y;
};
 
int main(void) {
    struct Point p[5];
    
    for (int i = 0; i < 5; i++) {
        p[i].x = i;
        p[i].y = i;
    }
}
cs



☞ 구조체 포인터란?

지난 시간에 배열과 포인터의 비교에 대해 알아보았습니다. (공부하러가기)

배열과 포인터는 닮은점이 많다고했는데요.

일반 자료형(int, char, double 등)과 같이 구조체(사용자 임의 자료형) 역시 포인터를 만들 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
struct Point {
    int x;
    int y;
};
 
int main(void) {
    struct Point p1 = { 11 };
    struct Point* p2 = &p1;
 
    p2->= 2;
    p2->= 3;
}
cs


위와 같이 * 연산자를 사용하여 포인터 변수를 선언하고, 변수의 주소값을 대입하여 정의할 수 있습니다.

구조체 포인터의 대한 접근방법은 -> 연산자를 사용하여 접근 가능합니다.


구조체는 C와 C++에서 모두 사용 가능합니다.

C++이 세상에 나오기 전 C에서의 구조체를 활용하여 C++의 클래스(class)를 만들었다고 하네요.

이 처럼 C의 구조체와 C++의 클래스는 닮은점이 많이있답니다.

다음 시간에는 C++의 클래스에 대해 한번 배워보도록 하겠습니다.



이상 'C/C++ 구조체'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C/C++ 메모리 동적할당  (0) 2018.10.11
C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25


안녕하세요 열코입니다.

이번에 블루투스 프로그램 개발 도중 백업 파일을 업로드합니다.

연결 및 통신 코드 첨부되어있습니다.

참고하시기바랍니다.



activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
 
    <!-- 메인 화면-->
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연동 APP"/>
 
        <Button
            android:id="@+id/button_connect_bluetooth"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="블루투스 연결"/>
 
        <Button
            android:id="@+id/button_how_to"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="사용 방법"/>
 
        <Button
            android:id="@+id/button_inquire"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="문의 하기"/>
 
        <Button
            android:id="@+id/button_exit"
            android:textSize="15dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="앱 종료"/>
 
        
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs



bluetooth_communication.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- 블루투스 통신 화면-->
    <LinearLayout
        android:id="@+id/linearlayout_setcolor"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:id="@+id/textview_connection_status"
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연결 상태 : "/>
 
        <TextView
            android:textColor="#000000"
            android:layout_marginLeft="10dp"
            android:id="@+id/textview_connection_explaination"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="디바이스 연결 설명"/>
 
        <Button
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/button_pairing"
            android:text="페어링 하기"/>
 
        <TextView
            android:id="@+id/textview_alarm_log"
            android:textColor="#000000"
            android:layout_marginLeft="10dp"
            android:layout_marginBottom="10dp"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=" ▣ 알림 기록"/>
 
        <ScrollView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">
            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/listview_alarm_log">
            </ListView>
        </ScrollView>
 
       
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs


connect_bluetooth.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- 블루투스 연결 화면-->
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="20dp"
            android:layout_marginBottom="20dp"
            android:textSize="20dp"
            android:gravity="center_horizontal|center_vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="블루투스 연결"/>
 
        <Button
            android:id="@+id/button_setting_menu"
            android:textSize="15dp"
            android:layout_marginBottom="5dp"
            android:layout_marginLeft="20dp"
            android:layout_marginRight="20dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="디바이스 신규 등록"/>
 
        <TextView
            android:textColor="#000000"
            android:layout_marginTop="10dp"
            android:layout_marginBottom="10dp"
            android:textSize="15dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text=" ▣ 페어링 된 디바이스"/>
 
        <ScrollView
            android:layout_weight="1"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:fillViewport="true">
            <ListView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/listview_pairing_devices">
            </ListView>
        </ScrollView>
 
      
    </LinearLayout>
 
</android.support.constraint.ConstraintLayout>
cs


MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package com.example.simt.simtbluetoothapp;
 
import android.content.DialogInterface;
import android.content.Intent;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
 
public class MainActivity extends AppCompatActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        // 버튼 객체 생성 및 xml id 연결
        Button button_connect_bluetooth = (Button) findViewById(R.id.button_connect_bluetooth);
        Button button_how_to = (Button) findViewById(R.id.button_how_to);
        Button button_inqure = (Button) findViewById(R.id.button_inquire);
        Button button_exit = (Button) findViewById(R.id.button_exit);
 
        // "블루투스 연결" 버튼 클릭 이벤트
        button_connect_bluetooth.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 ConnectBluetoothActivity 실행
                Intent intent = new Intent(MainActivity.this, ConnectBluetoothActivity.class);
                startActivity(intent);
            }
        });
 
        // "사용 방법" 버튼 클릭 이벤트
        button_how_to.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 HowToActivity 실행
                Intent intent = new Intent(MainActivity.this, HowToActivity.class);
                startActivity(intent);
            }
        });
 
        // "문의하기" 버튼 클릭 이벤트
        button_inqure.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 새 창에서 InquireActivity 실행
                Intent intent = new Intent(MainActivity.this, InquireActivity.class);
                startActivity(intent);
            }
        });
 
        // "앱 종료" 버튼 클릭 이벤트
        button_exit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 종료 확인 다이얼로그(대화창) 생성
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this, android.R.style.Theme_DeviceDefault_Light_Dialog);
                builder.setMessage("정말로 앱을 종료하시겠습니까?").setTitle("앱 종료")
                        .setPositiveButton("아니오"new DialogInterface.OnClickListener() {
                            // 아니오 버튼을 눌렀을 때
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // 아무 작동없이 함수를 종료
                                return;
                            }
                        })
                        .setNeutralButton("예"new DialogInterface.OnClickListener() {
                            // 예 버튼을 눌렀을 때
                            @Override
                            public void onClick(DialogInterface dialog, int which) {
                                // 앱을 종료
                                finish();
                            }
                        })
                        .setCancelable(false).show();
            }
        });
    }
}
 
cs


ConnectBluetoothActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
package com.example.simt.simtbluetoothapp;
 
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
 
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
 
public class ConnectBluetoothActivity extends AppCompatActivity {
    // onActivityResult의 RequestCode 식별자
    private static final int REQUEST_NEW_DEVICE = 1;
    private static final int REQUEST_ENABLE_BT = 2;
 
    // 블루투스 사용 객체
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothDevice bluetoothDevice;
    private Set<BluetoothDevice> bluetoothDeviceSet;
    private BluetoothSocket bluetoothSocket;
    public static InputStream inputStream;
 
    // xml 객체
    private ListView listView_pairing_devices; // 페어링 된 디바이스 리스트뷰 객체
 
    // 일반 객체
    private String device_name;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.connect_bluetooth);
 
        // 리스트 뷰 객체와 xml id 연결
        listView_pairing_devices = (ListView)findViewById(R.id.listview_pairing_devices);
 
        // 버튼 객체 생성 및 xml id 연결
        Button button_setting_menu = (Button)findViewById(R.id.button_setting_menu);
        // "디바이스 신규 등록" 버튼 클릭 이벤트
        button_setting_menu.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                // 블루투스 설정 화면 띄워주기
                Intent intent = new Intent(Settings.ACTION_BLUETOOTH_SETTINGS);
                // 종료 후 onActivityResult 호출, requestCode가 넘겨짐
                startActivityForResult(intent, REQUEST_NEW_DEVICE);
            }
        });
 
        // 블루투스 활성화 확인 함수 호출
        checkBluetooth();
    }
 
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode) {
            // 블루투스 설정화면 종료 시
            case REQUEST_NEW_DEVICE :
                checkBluetooth();
                break;
            // 블루투스 활성화 선택 종료 시
            case REQUEST_ENABLE_BT :
                // 활성화 버튼을 눌렀을 때
                if(resultCode == RESULT_OK) {
                    selectDevice();
                }
                // 취소 버튼을 눌렀을 때
                else if(resultCode == RESULT_CANCELED) {
                    Toast.makeText(getApplicationContext(), "블루투스를 활성화 하지 않아 앱을 종료합니다.", Toast.LENGTH_LONG).show();
                    // 앱 종료
                    finish();
                }
                break;
        }
        super.onActivityResult(requestCode, resultCode, data);
    }
 
    // 블루투스 활성화 확인 함수
    public void checkBluetooth() {
        bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        // 단말기가 블루투스를 지원하지 않을 때
        if(bluetoothAdapter == null) {
            Toast.makeText(getApplicationContext(), "단말기가 블루투스를 지원하지 않습니다.", Toast.LENGTH_LONG).show();
            finish(); // 앱 종료
        }
        // 블루투스를 지원할 때
        else {
            // 블루투스가 활성화 상태
            if(bluetoothAdapter.isEnabled()) {
                // 블루투스 선택 함수 호출
                selectDevice();
            }
            // 블루투스가 비 활성화 상태
            else {
                // 블루투스를 활성화
                Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(intent, REQUEST_ENABLE_BT);
            }
        }
    }
 
    // 블루투스 선택 함수
    public void selectDevice() {
        // 페어링 된 디바이스 목록을 불러옴
        bluetoothDeviceSet = bluetoothAdapter.getBondedDevices();
 
        // 리스트를 만듬
        List<String> list = new ArrayList<>();
        for(BluetoothDevice bluetoothDevice : bluetoothDeviceSet) {
            list.add(bluetoothDevice.getName());
        }
 
        // 어레이어뎁터로 리스트뷰에 리스트를 생성
        final ArrayAdapter arrayAdapter = new ArrayAdapter(ConnectBluetoothActivity.this, android.R.layout.simple_list_item_1, list);
        listView_pairing_devices.setAdapter(arrayAdapter);
        listView_pairing_devices.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            // 리스트 뷰의 아이템을 클릭했을 때
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                device_name = arrayAdapter.getItem(position).toString();
 
                // 프로그레스 다이얼로그 생성
                CheckTypesTask task = new CheckTypesTask();
                task.execute();
            }
        });
    }
 
    // 클릭 된 디바이스와 연결하는 함수
    public void connectDevice(String deviceName) {
        // 블루투스 연결 할 디바이스를 찾음
        for(BluetoothDevice device : bluetoothDeviceSet) {
            if(deviceName.equals(device.getName())) {
                bluetoothDevice = device;
                break;
            }
        }
 
        // UUID 생성
        UUID uuid = java.util.UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
 
        try {
            // 블루투스 소켓 생성
            bluetoothSocket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
            bluetoothSocket.connect();
            // 데이터 받기 위해 인풋스트림 생성
            inputStream = bluetoothSocket.getInputStream();
 
            // 블루투스 수신 시작 호출
            Intent intent = new Intent(ConnectBluetoothActivity.this, BluetoothCommunicationActivity.class);
            startActivity(intent);
        }
        catch (Exception e) {
            // 쓰레드에서 UI처리를 위한 핸들러
            Message msg = handler.obtainMessage();
            handler.sendMessage(msg);
        }
    }
 
    // 핸들러 선언
    final Handler handler = new Handler() {
        public void handleMessage(Message msg) {
            Toast.makeText(getApplicationContext(), "블루투스 연결을 다시 시도해주세요.", Toast.LENGTH_SHORT).show();
        }
    };
 
    // 프로그레스 다이얼로그 생성
    private class CheckTypesTask extends AsyncTask<Void, Void, Void> {
        ProgressDialog asyncDialog = new ProgressDialog(
                ConnectBluetoothActivity.this);
 
        @Override
        protected void onPreExecute() {
            asyncDialog.setCancelable(false);
            asyncDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
            asyncDialog.setMessage(device_name + "과 연결중입니다.");
 
            // show dialog
            asyncDialog.show();
            super.onPreExecute();
        }
 
        // 백그라운드에서 실행
        @Override
        protected Void doInBackground(Void... arg0) {
            connectDevice(device_name);
            return null;
        }
 
        // 백그라운드가 모두 끝난 후 실행
        @Override
        protected void onPostExecute(Void result) {
            asyncDialog.dismiss();
            super.onPostExecute(result);
        }
    }
}
 
cs


BluetoothCommunication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
package com.example.simt.simtbluetoothapp;
 
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.os.Vibrator;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
 
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
 
public class BluetoothCommunicationActivity extends AppCompatActivity {
 
    // xml 객체 선언
    private LinearLayout linearLayout_setcolor;
    private TextView textView_connection_status;
    private TextView textView_connection_explaination;
    private ListView listView_alarm_log;
    private Button button_pairing;
    private TextView textView_alarm_log;
 
    // 일반 변수 객체 선언
    private List<String> list;
    private ArrayAdapter arrayAdapter;
    private int log_num = 1;
 
    // 쓰레드 사용 객체 선언
    private int readBufferPosition;
    private byte[] readBuffer;
    private Thread thread;
 
    // WakeLock 사용 객체
    private PowerManager powerManager;
    private PowerManager.WakeLock wakeLock;
 
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.bluetooth_communication);
 
        // xml 객체 id 연결
        linearLayout_setcolor = (LinearLayout)findViewById(R.id.linearlayout_setcolor);
        textView_connection_status = (TextView)findViewById(R.id.textview_connection_status);
        textView_connection_explaination = (TextView)findViewById(R.id.textview_connection_explaination);
        listView_alarm_log = (ListView)findViewById(R.id.listview_alarm_log);
        button_pairing = (Button)findViewById(R.id.button_pairing);
        textView_alarm_log = (TextView)findViewById(R.id.textview_alarm_log);
 
        // 리스트 뷰 어댑터 생성
        list = new ArrayList<>();
        arrayAdapter = new ArrayAdapter(BluetoothCommunicationActivity.this, android.R.layout.simple_list_item_1, list);
        // 항상 최하단 아이템으로 유지
        listView_alarm_log.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
        listView_alarm_log.setAdapter(arrayAdapter);
 
        // 페어링 하기 버튼 클릭 이벤트
        button_pairing.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
                startActivity(new Intent(BluetoothCommunicationActivity.this, ConnectBluetoothActivity.class));
            }
        });
 
        // WakeLock 객체 생성 및 설정
        powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK |
                PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "WAKELOCK");
 
        // 동적 버튼 객체 생성
        final Button newbtn = new Button(BluetoothCommunicationActivity.this);
 
        // UI 변경은 핸들러에서 처리
        @SuppressLint("HandlerLeak"final Handler handler = new Handler() {
            public void handleMessage(Message msg) {
                // 연결 되지 않았을 때
                linearLayout_setcolor.setBackgroundColor(Color.rgb(179,179,179));
                textView_connection_status.setTextColor(Color.RED);
                textView_connection_status.setText("블루투스 연결 상태 : 불량");
                textView_connection_explaination.setText("블루투스 디바이스와 연결 상태가 좋지 않습니다.\n" +
                        "계속해서 연결 상태가 좋지 않을 경우 아래 버튼을 눌러 다시 페어링을 시도하세요.");
 
                // 버튼 보이기
                button_pairing.setVisibility(View.VISIBLE);
                listView_alarm_log.setVisibility(View.INVISIBLE);
                textView_alarm_log.setVisibility(View.INVISIBLE);
            }
        };
 
        // 수신 버퍼 저장 위치
        readBufferPosition = 0;
        readBuffer = new byte[10];
 
        // 문자 수신 쓰레드
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 인터럽트 호출 전까지 반복
                while(!Thread.currentThread().isInterrupted()) {
                    // 수신 데이터 확인 변수
                    int byteAvailabe = 0;
 
                    // 문자열 개수를 받아옴
                    try {
                        byteAvailabe = ConnectBluetoothActivity.inputStream.available();
                    }
                    catch (IOException e) {
                        e.printStackTrace();
                    }
 
                    Log.d("Thread""From Bluetooth Data : " + byteAvailabe);
 
                    // 데이터가 수신된 경우
                    if(byteAvailabe > 0) {
                        // 데이터 크기만큼 바이트 배열 생성
                        byte[] packetByte = new byte[byteAvailabe];
                        // 바이트 배열 크기만큼 읽어옴
                        try {
                            ConnectBluetoothActivity.inputStream.read(packetByte);
                        }
                        catch (IOException e) {
                            e.printStackTrace();
                        }
 
                        for(int i = 0; i < byteAvailabe; i++) {
                            final byte readData = packetByte[i];
                            if(readData != '\n') {
                                // 읽어온 바이트 배열을 인코딩 된 배열로 복사
                                byte[] encodedByte = new byte[readBufferPosition];
                                System.arraycopy(readBuffer, 0, encodedByte, 0, encodedByte.length);
 
                                try {
                                    String data = new String(encodedByte, "US-ASCII");
                                }
                                catch (UnsupportedEncodingException e) {
                                    e.getStackTrace();
                                }
 
                                readBufferPosition = 0;
 
                                final PendingIntent pendingIntent = PendingIntent.getActivity(BluetoothCommunicationActivity.this0,
                                        new Intent(getApplicationContext(), BluetoothCommunicationActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
 
                                handler.post(new Runnable() {
                                    // 알림 객체 선언
                                    NotificationManager notificationManager;
                                    Notification.Builder builder;
 
                                    @Override
                                    public void run() {
                                        // 버튼 숨기기
                                        button_pairing.setVisibility(View.INVISIBLE);
                                        listView_alarm_log.setVisibility(View.VISIBLE);
                                        textView_alarm_log.setVisibility(View.VISIBLE);
 
                                        // 0 입력 받을 때
                                        if(readData == 48) {
                                            linearLayout_setcolor.setBackgroundColor(Color.rgb(185,255,198));
                                            textView_connection_status.setTextColor(Color.BLACK);
                                            textView_connection_status.setText("블루투스 연결 상태 : 정상");
                                            textView_connection_explaination.setText("블루투스 디바이스와 성공적으로 페어링했습니다.");
                                        }
                                        // 1 입력 받을 때
                                        else {
                                            // 현재 시간을 받아옴
                                            long now = System.currentTimeMillis();
                                            Date date = new Date(now);
                                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("MM월 dd일 - HH시 mm분 ss초");
                                            String nowDate = simpleDateFormat.format(date);
 
                                            linearLayout_setcolor.setBackgroundColor(Color.rgb(243,197,197));
                                            textView_connection_explaination.setText("센서가 감지되었습니다.");
 
                                            // 알림 객체 설정
                                            builder = new Notification.Builder(BluetoothCommunicationActivity.this)
                                                    .setSmallIcon(R.drawable.ic_launcher_background) // 아이콘 설정
                                                    .setContentTitle(nowDate) // 제목 설정
                                                    .setContentText("센서가 감지되었습니다."// 내용 설정
                                                    .setAutoCancel(true)
                                                    .setTicker("센서가 감지되었습니다."// 한줄 내용 설명
                                                    .setContentIntent(pendingIntent);
                                            notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
                                            // 젤리빈 버전 이상 알림
                                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                                                notificationManager.notify(0, builder.build());
                                            }
 
                                            // 로그 리스트에 추가
                                            list.add(log_num + ". " + nowDate);
                                            arrayAdapter.notifyDataSetChanged();
                                            log_num++;
 
                                            // 진동 객체 설정
                                            Vibrator vibrator = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
                                            vibrator.vibrate(1000);
 
                                            // 알림 소리 설정
                                            Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
                                            Ringtone ringtone = RingtoneManager.getRingtone(getApplicationContext(), uri);
                                            ringtone.play();
 
                                            // WakeLock 깨우기 및 해제
                                            wakeLock.acquire();
                                            wakeLock.release();
                                        }
                                    }
                                });
                            }
                        }
                    }
                    // 데이터가 수신되지 않은 경우
                    else {
                        // 메세지 핸들러 호출
                        Message msg = handler.obtainMessage();
                        handler.sendMessage(msg);
                    }
 
                    try {
                        // 2초 간격으로 반복
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        // 쓰레드 시작
        thread.start();
    }
}
 
cs


파이썬 파일 입출력




안녕하세요 열코입니다.

저번시간에 C/C++과 자바에서 파일처리에 대해 알아보았습니다.

이번에는 파이썬에서의 파일 입출력에 대해 살펴볼텐데요.

C/C++에 비해 자바가 조금 더 쉽고 편한것 보다 C/C++, 자바보다 파이썬은 훨씬 간단한 것 같네요... (역시 갓이썬...)

자 그럼 바로 파이썬의 파일 입출력에 대해 알아보겠습니다!


먼저 다른 언어들과 마찬가지로 파일 처리의 순서는 다음과 같습니다.


[파일 처리 순서]

파일 열기 - 파일 읽기 또는 쓰기 - 파일 닫기


파일을 먼저 열고, 파일을 읽어서 변수에 저장하거나 변수의 데이터를 파일에 쓰고 난 후 사용이 끝나면 꼭 파일을 닫아줍니다.


1. 파일 열기

파이썬에서 파일 열기는 open() 함수를 사용하는데요.

사용법은 아래와 같습니다.


[예제 코드]

f = open("파일 경로", '접근 방식')


파이썬 역시 C/C++과 같이 파일을 열 때 접근 방식에 대해 지정 해 주어야합니다.

접근 방식은 C/C++과 매우 비슷합니다.

w는 쓰기전용, r은 읽기전용, a는 파일끝에 덭붙여쓰기(w는 기존파일이 모두 삭제됩니다)

알파벳 뒤에 +를 붙이는 경우 읽기와 쓰기를 모두 사용할 수 있습니다.



2. 파일 쓰기

파이썬에서 파일에 쓰기 위해서는 write() 함수를 사용합니다.

사용법은 다음과 같습니다.


[예제 코드]

file = open("test.txt", 'w') # 파일 열기

file.write("열코의\n") # 파일 쓰기 

file.write("프로그래밍\n") # \n은 줄바꿈

file.write("일기")

file.close() # 파일 닫기


[실행 결과]

열코의

프로그래밍

일기


네.. 정말 간단합니다...

딱히 설명 드릴게 없군요... ㅜㅜ

다음은 파일 읽기에 대해 알아보겠습니다.


3. 파일 읽기

파이썬에서 파일 읽기는 read() 함수와 readline() 함수가 있습니다.

차이점은 read() 함수는 그냥 읽는거고 readline() 함수는 줄단위로 읽습니다.

아래 예제 코드를 살펴보시죠.


[예제 코드]

file = open("test.txt", 'r') # 파일 열기

text = file.read() # 파일 읽기

print(text) # 출력

file.close() # 파일 닫기



[실행 결과]

열코의

프로그래밍

일기


너무 간단하죠? read() 함수를 그냥 하나 툭 쓰기만 하면 EOF(End Of File; 파일의 끝)까지 파일 전체를 읽어서 반환합니다.(세상 편리)

그러면 줄 단위로 읽는 readline() 함수는 사용하지 않는건가요?

그렇지 않습니다.

필요에 따라 파일을 줄 단위로 읽어서 처리할 필요가 있습니다.(속도와 크기 면에서 경제적으로 사용 가능)

또한 read() 함수에 매개변수로 정수형 숫자를 넣어주면 그 크기만큼만 읽어 올 수도 있습니다.


4. 파일 닫기

파일 닫기는 항상 강조했던 부분입니다.

사실 파일을 안 닫아도 실행에 문제가 없을 때가 많지만

여러개의 파일을 동시에 열때에는 심각한 오류가 발생하여 파일안의 내용이 모두 사라지는 경우도 있습니다.

(실제로 겪었습니다...ㅜ)

그래서 파일 사용이 모두 끝난 후 꼭 파일을 닫아줍시다.


file.close()


5. 그 외 함수들...

tell() : 바이트 형식으로 파일의 시작부분에서 현재 파일 객체의 위치를 알려주는 정수형 값을 반환합니다.

seek() : 파일 객체의 위치를 변경합니다.

flush() : 내부 버퍼를 비웁니다. close() 함수 사용시 자동으로 비워집니다.



이상 '파이썬 파일 처리'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



C/C++ 배열 사용법




안녕하세요 열코입니다.


이번시간에는 C/C++에서 배열의 사용법에 대해 알아보겠습니다.

컴퓨터 공학에서 배열(array)이란 번호(index)와 그에 대응하는 데이터들로 이루어진 자료구조를 뜻합니다.

일반적으로 배열은 같은 종류(type)의 데이터들이 순차적으로 메모리에 저장됩니다.

대부분의 프로그래밍 언어에서 배열을 지원하며 이번시간에는 C와 C++의 배열 사용법에 대해 알아보도록 하겠습니다.


배열의 사용 이유?

많은 수의 데이터를 저장하기위한 변수를 선언할 때 일반 변수로 관리하기가 어렵기 때문에 하나의 변수(배열)를

선언해서 많은 데이터를 한꺼번에 순차적으로 처리 할 수 있습니다.


☞ 배열의 선언 방법?

C/C++에서 배열은 선언 당시 크기가 지정되어야 합니다.(고정된 크기의 자료구조)

일반적으로 다음과 같이 선언 할 수 있습니다.


int arr[5];


배열은 일반 변수와 같이 자료형(type)을 먼저 선언하고 배열의 이름(기본적으로 arr 또는 ary 등을 사용합니다)을

명시해준 후, 대괄호( ' [ ' , ' ] ' )를 사용해서 배열의 크기를 지정해 줍니다. 

이때 배열의 크기는 고정된 상수(양의 정수형 숫자)여야 하며 일반 변수를 지정해 줄 수 없습니다.

배열 요소의 자료형은 int(정수)형을 포함, 모든 기본 자료형(char, double 등)을 지원합니다.


또한 아래와 같이 크기를 명시 해 주지않고 배열의 요소를 모두 정의할 수 있습니다.


int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };


이 경우에는 arr 변수의 크기는 개발자가 직접 명시하지 않아도 자동으로 10으로 지정됩니다.

또한 배열의 크기를 명시적으로 지정해 주고 배열 요소를 모두 지정해 주지않으면 나머지 요소들은 모두 0으로 초기화 됩니다.

아래의 예제를 확인해보겠습니다.



int arr1[5] = { 1, 2, 3 }; // 배열의 요소들은 { 1, 2, 3, 0, 0 } 으로 초기화 됨

int arr2[5]; // 배열의 요소들은 모두 쓰레기값으로 초기화 됨

int arr3[10] = { 0 }; // 배열의 요소들은 모두 0으로 초기화 됨


위 코드를 보면 알 수 있듯이, 요소들의 값을 하나라도 지정해 주면 나머지 지정 해 주지않은 요소들은 모두 0으로 초기화되며,

만약 요소의 값을 하나라도 지정 해 주지않으면 모두 쓰레기 값으로 초기화됩니다.


☞ 배열의 요소에 접근하는 방법?

배열 각각의 요소에 접근을 하기 위해서는 대괄호( ' [ ' , ' ] ' )를 사용해서 접근 할 수 있습니다.


int arr[3];

arr[0] = 5;

arr[1] = 2;

arr[2] = 0;

arr[3] = 4; // 런타임 에러!!


위와 같이 배열의 크기를 3으로 지정하면 배열의 요소(index)는 0부터 2(배열의 크기 - 1)까지 생성됩니다.

또한 배열의 요소에 접근역시 0부터 2까지 허용되며 배열의 요소 범위를 초과하면 런타임 에러가 발생하게 됩니다.

* 배열의 요소의 시작이 1이아닌 0부터 시작한다는 것을 주의합니다.


☞ 배열의 이름의 의미?

우리가 배열을 만들어 줄 때 이름을 arr 또는 ary 또는 a, b, c...등 으로 의미없이 지어주었지만

컴파일러는 배열의 이름에 남다른 의미를 부여해줍니다.

바로 배열의 이름에는 배열의 시작 주소를 담고있는데요.

이 배열의 시작 주소로 여러가지 활용이 가능합니다.


int arr[3]; 

printf("%d\n", arr); // 배열의 시작 주소를 출력 (100번지)

printf("%d\n", arr + 1); // 배열의 다음 요소의 주소를 출력 (104번지)


배열의 다음 요소의 주소가 104번지 (4차이)가 나는 이유는 배열의 자료형이 int(정수형) 4바이트(32비트 운영체제 기준)이기 때문입니다.

이를 이용해 배열의 자료형을 알 수도있으며, 배열 각각의 요소에 접근 할 수도 있고, 포인터와 활용하여 여러가지 연산이 가능해지게 됩니다.



☞ 배열과 포인터의 차이?

배열과 포인터는 엄연히 말하면 다르지만 사용 측면에서 비슷한점이 많습니다. 

먼저 포인터에 대해 이해한 다음 아래 내용을 확인하시면 좋겠습니다.

포인터에 대해 배우러 가기 < 클릭


배열과 포인터는 구조상 차이가 있지만 사용 측면에서는 큰 차이가 없으며 대부분 같은 동작을 수행합니다.

아래 코드를 확인해보시면 배열과 포인터의 비슷한 점을 확인 하실 수 있습니다.


int arr[3] = { 1, 2, 3 }; // 배열 선언

int *p = arr; // 포인터 선언(배열의 첫번째 요소의 주소값을 가리킴)

// 배열을 포인터처럼 사용

printf("%d\n", *(arr + 2)); 

// 배열의 시작 주소의 2를 더함(8바이트 이동하여 배열의 3번째 요소에 도착)

// 배열의 3번째 요소의 주소값에 *(역참조연산자)를 연산하면 그 주소값의 실제 저장된 값에 접근

// 따라서 배열의 마지막 요소인 3을 출력


// 포인터를 배열처럼 사용

printf("%d\n", p[0]);

// p는 포인터 변수이지만 배열처럼 [ ] 대괄호를 사용해 배열의 요소에 접근하는 것 처럼 활용이 가능

// 배열의 첫번째 요소인 1을 출력


// 포인터의 연산

printf("%d\n", *(p + 1));

// p는 포인터 변수이며 배열의 첫번째 요소를 가리킴

// p에 1을 더한것은 포인터의 타입인 int형을 기준으로 4바이트 더한 연산을 수행

// 따라서 p는 배열의 첫번째 요소의 주소값에서 4를 더했으므로 배열의 두번째 연산의 주소값을 가리킴

// *(역참조연산자)을 연산하면 주소값의 실제 값인 2를 출력


☞ 배열의 크기를 동적으로 만들고 싶을 때?

배열은 정적인 크기의 자료구조입니다. 하지만 프로그래밍을 하다보면 배열의 크기를 마음대로 조절하고 싶을 때가 생깁니다.

그럴 때에는 포인터를 사용하여 동적할당을 활용하거나 C++에서는 STL의 하나인 벡터 클래스를 활용하시면 됩니다.


1. C에서 동적할당

C언어에서는 포인터 변수를 활용해 배열을 동적으로 생성하고 제거할 수 있습니다.

아래의 코드는 malloc() 함수를 사용하여 배열의 크기를 입력 받은 후 사용하고 메모리를 해제하는 예제 코드입니다.


int *p; // 포인터 변수 선언

int arr_size; // 배열의 크기를 입력 받을 변수

scanf("%d", &arr_size); // 배열의 크기를 입력 받음

p = (int *)malloc(sizeof(int) * arr_size); // 입력 받은 숫자만큼 배열을 동적 생성

free(p); // 사용이 끝난 후 메모리 해제


2. C++에서 동적할당

C++언어에서도 마찬가지로 포인터 변수를 활용해 배열을 동적으로 생성하고 제거할 수 있습니다.

C++에서는 malloc() 함수이외에 new 키워드를 지원하므로 new 키워드를 사용하여 배열을 동적으로 생성할 수 있습니다.

아래는 new 키워드를 사용하여 배열을 동적 할당하는 예제 코드입니다.


int *p; // 포인터 변수 선언

int arr_size; // 배열의 크기를 입력받을 변수

cin >> arr_size; // 배열의 크기를 입력받음

p = new int[arr_size]; // 입력받은 크기만큼 배열을 동적 생성

delete[] p; // 사용이 끝난 후 메모리 해제


3. C++ STL 벡터클래스 활용

C++은 STL이라는 표준 라이브러리를 지원하며 이 중 벡터(Vector) 클래스를 활용하여 크기가 가변하는 배열을 사용할 수 있습니다.

벡터 클래스의 사용방법은 여기를 참고하세요.



이상 'C/C++ 배열 사용법'에 대해 알아보았습니다.

질문 또는 오타나 잘못된 정보가 있는 경우 댓글로 달아주세요!

공감♡ 버튼을 눌러주시면 더욱 유용하고 좋은 포스팅으로 찾아 뵙겠습니다.



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

C++ friend 클래스와 함수  (1) 2018.10.10
C++ 클래스 접근제한자  (0) 2018.10.10
C++ 클래스와 객체  (0) 2018.10.09
C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08

to Top