728x90

p389 - 1
p389-3
p390-5

 

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 18  (0) 2019.05.29
C언어 공부 17  (0) 2019.05.29
프로그래밍 연습 6  (0) 2019.05.12
C언어 공부 16  (0) 2019.05.11
C언어 공부 15  (0) 2019.05.11
728x90

p344 - 1
p344-3
p344 - 5
p345-7
p345-9

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 17  (0) 2019.05.29
프로그래밍 연습 7  (0) 2019.05.12
C언어 공부 16  (0) 2019.05.11
C언어 공부 15  (0) 2019.05.11
C언어 공부 14  (0) 2019.05.11
728x90

C가 데이터를 값으로 전달하는 이유는, 데이터의 무결성을 유지하기 위해서 이다.

 

함수의 의도가 배열 내용을 변경하지 않는 것이라면, 프로토 타입과 함수 정의에서 형식 매개변수를 선언할 때 키워드 const를 사용하는 것이다.

 

const는 상수배열, 상수 포인터, 상수를 가리키는 포인터 등을 만들 수 있다.

 

일반적으로, 상수를 가리키는 포인터는, 데이터를 변경하는데 포인터를 사용하지 않는 함수에 함수 매개변수로 사용된다.

 

함수 매개변수에서 const를 사용하면 데이터를 보호할 뿐만아니라 그 함수가 const로 선언된 배열을 가지고 작업하는 것을 허용한다.

 

const는 몇가지 다른용도로도 사용할 수 있다. 예를들면, 다른곳을 가리킬 수 없도록 포인터를 선언하고 초기화 할 수 있다. 이 테크닉은 키워드 const를 놓는 위치에 비결이 있다.

 

double rates[5] = {88.99, 100.12, 59.45, 183.11, 340.5};

double *const pc = rates;              //pc는 배열의 시작을 가리킨다.

pc = &rates[2];                           //허용안된다.

*pc = 92.99                               //허용된다. rates[0]을 수정한다.

이와같은 포인터는 여전히 값을 변경하는데 사용할 수 있지만, 처음에 대입된 위치만 가리킬 수 있다.

 

가리키는 곳도 변경할 수없고 가리키는 값도 변경할 수 없는 포인터를 작성하기 위해 const를 두번 사용할 수 있다.

const double * const pc = rates;

 

int zippo[4][2]; 가 있다고 가정한다.

포인터나 주소에 1을 더하는 것은, 그것이 가리키는 객체의 크기만큼 값을 증가시킨다. 이점에서 볼때, zippo와 zippo[0]은 다르다. 왜냐하면 zippo는 int형 2개 크기의 객체를 참조하고, zippo[0]는 int형 1개 크기의 객체를 참조하기 때문이다. zippo+1은 zippo[0]+1과는 크기가 다르다.

 

*연산자를 사용하여 또는 각괄호와 인덱스를 사용하여 포인터나 주소의 내용을 참조하는 것은, 그것이 가리키는 객체의 값을 제공한다.

 

zippo[2][1]과 포인터 표기 *(*(zippo+2)+1)이 동등하다.

zippo             <-배열의 첫번째 원소(int형 2개짜리 배열)의 주소

zippo+2          <-배열의 세번째 원소(int형 2개짜리 배열)의 주소

*(zippo+2)         <-배열의 세번째 원소인, int형 2개짜리 배열의 첫번째 원소(하나의 int)의 주소

*(zippo+2)+1      <-배열의 세번째 원소인, int형 2개짜리 배열의 두번째 원소(하나의 int)의 주소

*(*(zippo +2)+1)    <-세번째 행, 두번째 열에 저장되어 있는 하나의 int형 값(zippo[2][1])

 

배열 이름과 포인터 둘중 어느것을 가지고 있으면, 개별적인 원소들을 배열 표기를 사용하여 나타낼 수 있고, 포인터 표기를 사용하여 나타낼 수 있다.

 

c++에서 비 const 포인터에 const포인터를 할당하도록 허용하지 않지만 C에서는 이 할당이 가능하다.

 

컴파일러는 배열 표기를 포인터 표기로 변환한다.

 

일반적으로, N차원 배열에 대응하는 포인터를 선언하려면, 가장 왼쪽의 각괄호를 제외한 모든 각괄호에 값을 제공해야 한다. 왜냐하면, 첫번째 각괄호가 포인터를 나타내고, 나머지 각괄호들은 가리켜지는 객체의 데이터형이기 때문이다.

 

가변길이 배열 (variable Length Array : VLA) 역시 한번 생성되면 같은 크기를 유지한다. "가변" 이라는 말을 처음 배열을 만들 때 배열의 차원을 지정할 때 변수를 사용할 수 있다는 뜻이다.

 

가변길이 배열은 동적 메모리 할당을 허용한다. 이것은, 사용자가 프로그램이 실행되는 도중에 배열의 크기를 지정할 수 있다는 것이다.

 

리터럴은 기호가 아닌 상수를 말한다.

 

C는 배열을 유도 데이터형(drived type)으로 취급한다. 그 이유는, 다른 데이터형에 기초하여 만들어지기 때문이다.

 

배열을 처리하는 함수에서 배열 이름을 실전달 인자로 사용할 때, 전체 배열을 함수에 전달하는 것이 아니다. 단지 배열의 주소만을 전달하는 것이다.

 

배열은 데이터형이 모두 동일한 원소들의 집합이다. 배열의 우너소들은 메모리에 연속적으로 저장되고, 정수 인덱스를 사용하여 접근할 수 있다. 포인터에 정수를 더하거나 증가시키면, 그 포인터의 값이 그것이 가리키는 객체(object)의 바이트 수만큼 증가된다.

728x90

'Programming > C' 카테고리의 다른 글

프로그래밍 연습 7  (0) 2019.05.12
프로그래밍 연습 6  (0) 2019.05.12
C언어 공부 15  (0) 2019.05.11
C언어 공부 14  (0) 2019.05.11
C언어 공부 13  (0) 2019.05.11
728x90

포인터를 가지고 수행할 수 있는 연산

 

대입하기 : 포인터에 주소를 대입할 수 있다. 예를 들면 대입값은 주소 연산자(&) 뒤에 오는 변수, 즉 배열이름이나 다른                제 2의 포인터가 될 수 있다. 단 그 주소는 포인터형과 일치해야 한다. 무분별한 데이터형 캐스트를 사용하지                않고서는, double형 값의 주소를 int형을 가리키는 포인터에 대입할 수 없다.

 

값 구하기 : *연산자는 그것이 참조하는 주소에 저장되어있는 값을 구한다.

 

포인터 주소 얻기 : 모든 변수들과 마찬가지로, 포인터 변수도 하나의 주소와 값을 가진다. &연산자는 포인터 자체가 어                          디에 저장되어 있는지 알려준다.

 

포인터에 정수 더하기 : 포인터에 정수를 더하거나, 정수에 포인터를 더하기 위해 +연산자를 사용할 수 있다. 어느 경우                                에나, 정수는 포인터가 가리키는 데이터형의 바이트 수만큼 곱해진다. 그러고 나서 결과가 최초                               의 주소에 더해진다. 그 배열의 마지막 원소 바로 다음의 주소(past - the - end)가 유효하다고                                   보장하는 것을 제외하고, 덧셈의 결과가 최초의 포인터가 가리키는 배열의 범위를 벗어나는지는                               정의되지 않는다.

 

포인터 증가시키기 : 배열의 한 원소를 가리키는 포인터를 증가시키면, 그 포인터가 배열의 다음 원소를 가리키게 된다.                            그러므로, ptr1++는 ptr1의 값을 4만큼 증가시킨다.

 

포인터에서 정수 빼기 : 포인터에서 정수를 빼기위해 - 연산자를 사용할 수 있다. 포인터는 첫번째 피연산자이고 정수값                                은 두번째 피연산자가 되어야 한다. 정수는 포인터가 가리키는 데이터형의 바이트 수만큼                                        곱해진다. 그러고 나서 최초의 주소에서 그 결과가 감해진다.

 

포인터 감소시키기 : 포인터를 감소시킬 수도 있다. ptr2를 감소시키면 배열의 세번째 원소가 아니라 두번째 원소를                                   가리키게 된다. 증가연산자와 감소연산자의 전위모드 후위모드 둘다 사용할 수 있다.

 

포인터 사이의 차 구하기 : 두 포인터 사이의 차를 구할 수 있다. 일반적으로, 같은 배열에 있는 원소들이 서로 얼마나                                        떨어져 있는지 알아내기 위해 같은 배열의 두원소를 가리키는 포인터들에 이 연산을                                              수행한다. 그 결과는 데이터형 크기와 같은 단위로 구해진다.                                                                            int형 포인터 urn이 있을 때 &urn[2] - urn은 2이다. 두 포인터 차이가 2바이트가 아니라                                          2개의 int형 크기만큼 떨어져 있는 객체들을 가리킨다는 것을 의미한다.

 

포인터 비교하기 : 두 포인터가 같은 데이터형을 가리키는 경우에, 두 포인터 값을 비교하기 위해 관계연산자를 사용할                         수 있다.

 

뺄셈은 두가지가 있다는 것에 주목하라, 한가지는 포인터에서 다른 포인터를 빼서 정수를 얻는 것이고, 다른 한가지는 포인터에서 정수를 빼서 포인터를 얻는 것이다.

 

C는, 어떤 배열이 주어졌을 때, 배열의 원소를 가리키는 포인터와 마지막 원소 바로 다음의 위치를 가리키는 포인터가 유효한 포인터라고 보장한다. 그러나 마지막 원소 바로 다음 위치를 가리키는 포인터가 유효하다고 보장은 하지만, 그 포인터가 가리키는 내용을 참조할 수 있다고 보장하지는 않는다.

 

포인터를 생성하면 포인터 자체를 저장하기 위한 메모리만 할당된다. 데이터를 저장하기 위한 메모리는 할당되지 않는다. 그러므로 포인터를 사용하기 전에, 반드시 이미할당된 메모리 위치를 그 포인터에 대입해야한다.

 

728x90

'Programming > C' 카테고리의 다른 글

프로그래밍 연습 6  (0) 2019.05.12
C언어 공부 16  (0) 2019.05.11
C언어 공부 14  (0) 2019.05.11
C언어 공부 13  (0) 2019.05.11
프로그래밍 연습 5  (0) 2019.05.09
728x90

배열 : 동일한 하나의 데이터형을 가진 연속된 원소들

 

프로그램이 배열에서 값을 꺼내 오기는 하지만, 배열에 새로운 값을 써 넣지 않을 경우에는 배열을 선언 할 때, const를 사용하는 것이 좋다.

 

배열 원소는 보통의 변수와 같다. 사용자가 이들을 초기화 하지 않는다면 그들은 아무 값이나 가질 수 있다.

 

서로 다른 저장클래스는 서로 다른 특성을 가지고 있다.

 

배열을 사용할 때 초기값 리스트에 들어 있는 항목들의 개수는 배열의 크기와 일치 해야한다.

 

배열을 일부분만 초기화 하면 나머지 원소들이 0으로 설정된다.

 

배열 전체의 크기를 배열 원소 하나의 크로 나누면, 그 배열에 몇개의 원소가 있는지 알 수 있다.

 

지정초기화자를 사용하면 초기화할 원소들을 사용자가 선택할 수 있다.

ex) int arr[6] = {[5] = 212};

사용자가 이 방식으로 최소한 하나의 원소를 초기화 하면, 초기화 하지 않은 나머지 원소들은 0으로 설정된다.

 

하나의 지정초기화자 뒤에, [4] = 31,30,31 와 같이, 여러 개의 값이 붙으면, 여분으로 붙는 값들은 이어지는 다음 원소들을 초기화 하는데 사용된다. 특정 원소가 어떤값으로 한번 이상 초기화 되면, 마지막에 행해진 초기화가 유효하다.

 

배열을 사용할 때, 유효한 범위 내에 있는 배열 인덱스를 사용하고 있는지 반드시 확인해야 한다. 즉, 배열 인덱스의 값이 그 배열에 대해 유효한지 확인 해야한다.

 

배열 인덱스는 0부터 시작한다.

그러므로 배열크기가 사용되는 배열의 선언부와 기타 다른장소에 기호상수를 사용하는 것이다. 이렇게 함으로써 프로그램 전체에 걸쳐서 동일한 배열 크기를 사용할 수 있게 해준다.

 

일반적으로, 3차원 배열은 삼중 중첩루프로 처리하고, 4차원 배열은 사중 중첩 루프로 처리한다. 더높은 차원의 배열도 마찬가지 방식으로 처리한다.

 

컴퓨터의 하드웨어 명령들은 주소를 많이 사용하기 때문에, 포인터를 사용하면 컴퓨터의 표현방식에 가까운 방식으로 표현할 수 있다. 포인터는 배열을 처리하는 매우 효율적인 방법을 제공한다.

 

 

포인터의 값은 그것이 가리키는 객체의 주소이다. 내부적으로 주소를 나타내는 방식은 하드웨어 따라 다르다. 많은 컴퓨터들이 바이트 단위로 주소를 매긴다.

 

포인터에 *연산자를 적용하면, 그 포인터가 가리키는 객체에 저장되어 있는 값을 얻는다.

포인터에 1을 더하면, 그 포인터가 가리키는 객체의 바이트 수 크기 만큼 포인터 값이 증가한다.

 

보통함수에 배열을 알리는 방법은 배열의 시작위치를 나타내기 위해 하나의 포인터 매개변수를 사용하고, 몇개의 원소를 처리할 것인지를 나타내기 위해 하나의 정수 매개변수를 사용한다.

함수에 배열을 알리는 또다른 방법은 두개의 포인터를 전달하는 것이다. 첫번째 포인터는 배열의 시작위치를 나타낸다.

두번째 포인터는 배열이 끝나는 위치를 나타낸다.

 

C는, 배열을 위한 공간을 할당할 때 배열의 끝 바로 다음의 첫번째 위치를 가리키는 포인터가 유효하다는 것을 보장한다.

 

total = *start++;

에서 *와 ++의 우선순위는 같지만 오른쪽에서 왼쪽으로 결합한다. 이것은, ++가 *start에 적용되는것이아니라 start에 적용된다는 것을 의미한다. -> *(start++)

 

배열을 처리하는 함수는 포인터를 전달인자로 사용한다.

 

 

 

 

 

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 16  (0) 2019.05.11
C언어 공부 15  (0) 2019.05.11
C언어 공부 13  (0) 2019.05.11
프로그래밍 연습 5  (0) 2019.05.09
C언어 공부 12  (0) 2019.05.08
728x90

재귀함수는 return 문에 의해 하나씩 청산된다.

프로그램 흐름이 마지막 재귀 수준의 끝에 도달했을 때, 바로 이전의 재귀 수준으로 제어가 넘어간다. 프로그램은 각각의 재귀 수준을 한단계씩 되짚어 올라가야 한다.

 

재귀 함수에서 재귀호출보다 앞에 있는 문장들은 그 함수들이 호출되는 순서로 실행된다.

재귀함수에서 재귀호출보다 뒤에있는 문장들은 그함수들이 호출되는 순서와 반대의 순서로 실행된다.

->위 특징은 순서를 뒤집을 필요가 있는 프로그래밍 문제를 푸는데 유용하다.

 

재귀의 각 수준이 자신만의 변수를 가질지라도, 코드 자체는 중복되지 않는다.

 

재귀함수는 재귀호출의 시퀀스를 중단시킬 수 있는 무언가를 가지고 있어야 한다.

 

함수를 작성할 때 루프와 재귀를 모두 사용할 수 있다면, 일반적으로 루프가 더 좋은 선택이다.

첫째, 각 재귀호출이 자체의 변수 집합을 가지기 때문에, 재귀가 메모리를 더많이 사용한다. 각 재귀호출은 스텍에 새로운 변수집합을 놓는다. 스택의 공간제한이 재귀호출의 수를 제한할 수 있다. 

둘째, 각 함수호출에 시간이 걸리기 때문에, 재귀는 속도가 늦다.

 

함수 프로토타입과 기호상수 정의를 하나의 헤더파일에 모아놓는것은 좋은 프로그래밍 습관이다.

 

주소연산자 : &

변수이름 앞에 사용했을 때, 그 변수의 주소를 제공한다. &nurse는 변수 nurse의 주소이다.

 

간접연산자 : *

포인터 이름이나 주소 앞에 사용했을 때, 그것이 가리키는 주소에 저장되어있는 값을 가리킨다.

 

함수가 다른 함수에 있는 데이터에 꼭 접근할 필요가 있다면, 포인터를 함수의 전달인자로 사용할 수 있다.

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 15  (0) 2019.05.11
C언어 공부 14  (0) 2019.05.11
프로그래밍 연습 5  (0) 2019.05.09
C언어 공부 12  (0) 2019.05.08
C언어 공부 11  (0) 2019.05.08
728x90

280p-1
p280-3
p281-6
p282-11
p283-13
p283-14

 

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 14  (0) 2019.05.11
C언어 공부 13  (0) 2019.05.11
C언어 공부 12  (0) 2019.05.08
C언어 공부 11  (0) 2019.05.08
C언어 공부 10  (0) 2019.05.08
728x90

함수는 하나의 특정 작업을 수행하도록 독립적으로 설계된 프로그램 코드의 한 단위이다.

 

함수도 데이터 형을 가지며 함수를 사용하기전에 함수의 데이터형을 미리 선언해야한다.

void형은 함수가 값을 리턴하지 않는다는 것이다.

 

일반적으로 프로토 타입은 함수반환값의 형과 예상되는 전달인자의 형을 모두 명시한다.

 

프로토타입은 전달인자의 개수와 데이터형을 표시하기 위해 콤마로 분리된 데이터형 리스트를 사용한다.

 

프로토타입에 변수이름을 사용한다고 해서 실제로 변수가 생성되는 것은 아니다.

 

실전달인자는 형식 매개변수로 알려지는 변수에 대입되는 특정한 값이다.

 

피호출 함수(called function)는 호출함수(calling function)로 부터 복사된 데이터를 가지고 작업하기 때문에, 피호출 함수가 사본데이터에 어떠한 조작을 가하더라도, 호출 함수에 있는 원래의 데이터는 보호된다.

 

호출함수는 전달인자를 스택(stack)이라는 임시 저장 공간에 놓는다. 피호출 함수는 그 스택으로부터 전달인자를 읽는다.

 

float형은 전달인자로 전달될때 double형으로 올림 변환이 일어난다.

 

데이터형이 프로토타입과 일치하지 않는다면, 컴파일러는 캐스트 연산을 적용하여 실전달인자들의 값을 형식 매개변수와 일치하는 데이터형으로 변환한다.

 

에러는 컴파일을 중단하지만 경고는 컴파일을 허용한다는 것이다.

 

printf()의 부분적인 프로토타입

int printf(const char *,...);

이 프로토타입은, 첫번째 전달인자가 문자열이라는 것과, 지정되지 않은 전달인자가 더 있을 수 도 있다는 것을 말해준다.

 

C라이브러리는, stdarg.h 헤더파일을 통해 매개변수의 개수가 가변적인 함수를 정의하는 표준 방법을 제공한다. C는 함수가 자기자신을 호출하는 것을 허용한다. 이과정을 재귀(recursion)라고 부른다. 재귀를 끝내는 조건검사를 프로그램에 포함시키지 않는다면, 자기자신을 호출하는 함수는 무한정 그렇게 하려는 경향이 있기 때문에 재귀를 끝내는 부분이 까다롭다.

 

728x90

'Programming > C' 카테고리의 다른 글

C언어 공부 13  (0) 2019.05.11
프로그래밍 연습 5  (0) 2019.05.09
C언어 공부 11  (0) 2019.05.08
C언어 공부 10  (0) 2019.05.08
C언어 공부 9  (0) 2019.05.08

+ Recent posts