|
|
12-1
문제 1
16MB 메모리의 주소의 범위를 구하시오. ⇒ 0 ~ (16×2²⁰ − 1)
변수의 주소를 설명하시오. ⇒
변수가 차지하고 있는 공간의 시작 번지이다.
변수의 주소의 자료형은 무엇인가? ⇒ (주소가가리키는변수의자료형)*
포인터란 무엇인가?⇒ 주소를 저장하기 위한 변수이다.
포인터의 자료형은 무엇인가? ⇒ 포인터에 저장 될 주소의 자료형(자료형*)
변수의 주소를 int형 변수에 저장하면 어떻게 되는가? ⇒ 주소 값은 정수처럼 보이지만 정수형 데이터와는 다른 주소형 자료형이기 때문에 변수의 주소를 int형 변수에 저장하면 자료형이 맞지 않으며, 포인터 연산이나 간접참조 연산(*)을 사용할 수 없다. 또한 시스템에 따라 주소의 크기가 int보다 클 수 있기 때문에 주소 값이 정확하게 저장되지 않을 수도 있다.
문제 2
다음에서 pt가 가리키는 데이터의 자료형은 무엇인가? ⇒ double형
다음에서 pt에 저장될 주소의 자료형은 무엇인가? ⇒ double* 형
다음에서 pt의 자료형은 무엇인가? ⇒ double*형
다음처럼 포인터를 선언할 때 double의 의미를 설명하라. ⇒ 포인터에 저장된 주소가 가리키는 자료형이 double이다.
포인터 변수 pt가 메모리에 할당 될 때 메모리 크기는? ⇒ 32비트 시스템-4 64비트 시스템-8
문제 3
| 수식 | 결과 값 | 결과 값의 자료형 |
| &ch | 100 | char* |
| &in | 101 | int* |
| &db | 105 | double* |
문제 4
변수a, b, c를 선언하고 각 변수의 주소를 주소연산자(&)를 이용하여 화면에 다음처럼 출력하라.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char a = 'A';
int b = 36;
double c = 3.141592;
printf("char형 변수a의주소 : %p\n", &a);
printf("int형 변수b의주소 : %p\n", &b);
printf("double형 변수c의주소: %p", &c);
return 0;
}
실행결과
12-2
문제 1
| 수식 | 결과 값 | 결과 값의 자료형 |
| &ch | 100 | char* |
| &in | 101 | int* |
| &db | 105 | double* |
| *&c | ‘A’ | char |
| *&in | 10 | int |
| *&db | 3.4 | double |
문제 2
포인터를 사용하여 같은 결과가 나오도록 코드를 수정하시오
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int a = -100;
char b = 'A';
double c = 3.14;
int* pa = &a;
char* pb = &b;
double* pc = &c;
printf("int형변수a의값은: % d\n", *pa);
printf("char형변수b의값은: % c\n", *pb);
printf("double형변수c의값은: % lf\n", *pc);
return 0;
}
실행결과
문제 3
①번 라인에서 강제 형 변환이 사용된 이유를 설명하라. => 포인터형 변수에 정수(상수)를 저장하기 위해 사용됐다.
아래 코드를 실행하면 오류가 발생하여 중단된다. 이유를 자세히 설명하라. =>125는 임의의 주소값이지 실제로 할당된 메모리공간이 아니다. 존재하지 않거나 접근이 허용되지 않은 메모리에 접근하게 되어 실행 중 오류가 발생하게 된다.
#include<stdio.h>
int main(void)
{
int* ptr = (int*)125; ①
*ptr = 10;
printf("%d\n", *ptr);
return 0;
}
문제 4
포인터를 이용한 간접참조방식의 코드로 필요한 코드를 추가 또는 수정하시오
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int a = 100, b = 200;
int sum;
int* pa = &a;
int* pb = &b;
int* ps = ∑
*ps = *pa + *pb;
printf("두정수의 합: %d\n", *ps);
return 0;
}
실행결과
문제 5
교재 284페이지 문제1번 또는 2번을 자유롭게변형
//포인터를 활용해 더 큰 값에 20을 빼고 더 작은 값에 20을 더하는 코드
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int num1 = 10, num2 = 20;
int* ptr1 = &num1;
int* ptr2 = &num2;
if (*ptr1 > *ptr2) {
*ptr1 -= 20; *ptr2 += 20;
}
else {
*ptr2 -= 20; *ptr1 += 20;
}
printf("%d %d \n", *ptr1, *ptr2);
return 0;
}
실행결과
12장 정리문제
① 메모리 주소가 무엇인가? ⇒ 메모리는 1바이트 단위로 고유한 주소가 붙어있는데 메모리 공간을 나타내는 위치이다. ② 변수의 메모리 주소를 구하는 방법은? ⇒ 주소연산자&을 사용한다.
③ 포인터의 의미를 설명하라⇒ 주소를 저장하기 위한 변수이다.
④ 포인터 변수가 왜 필요한가?⇒ 메모리에 저장된 값에 접근하기 위해서 필요하다.
⑤ 포인터 변수가 메모리에 할당될 때 메모리 크기는 몇 바이트인가? ⇒ 32 비트시스템에선 4, 64비트 시스템에선8바이트
⑥ 포인터 선언은 자료형* 변수명;처럼 하는데 여기서 자료형의 의미를 설명하라 ⇒ 주소가 가리키는 공간에 저장된 데이터의 자료형을 의미한다.
⑦ 정수 100과 주소 100을 어떻게 구분하는가?⇒ 자료형으로 구분하면 된다.
⑧ 포인터를 이용하여 메모리 공간에 저장된 값을 접근하는 방법을 설명하라. ⇒ 간접연산자*을 사용한다.
13-1
문제 1
배열명의 의미를 설명하라. ⇒ 배열 첫 번째 요소의 주소를 의미한다.
배열 표현과 포인터(주소) 표현의 변환공식을 설명하라. ⇒ *a[i] < = > (a+i) // &a[i] < = > a + i
배열의 첫번째 요소의 주소만알면 모든 원소의 주소를 계산할수있다. 방법을 설명하시오. ⇒ 배열은 메모리에 연속적으로 저장되는 자료구조이므로 각 원소의 주소는 일정한 간격으로 증가한다. 각 원소의 크기는 그 배열의 자료형의 크기와 같기 때문에, 첫 번째 원소의 주소에 원소 크기 × 인덱스 값을 더하면 해당 원소의 주소를 구할 수 있다.
배열의 첫번째 요소의 주소만 알면 모든 원소의 값을 계산할수있다. 방법을 설명하시오. ⇒ 배열의 첫 번째 원소의 주소에 인덱스 값을 더하면 포인터 연산에 의해 자료형의 크기만큼 이동하여 해당 원소의 주소를 구할 수 있고, 그 주소를 연산자 *로 역참조하면 해당 위치에 저장된 값을 얻을 수 있다.
포인터에 대해 가능한 연산의 종류와 의미를 설명하라. ⇒ 간접참조(*) , 정수와의 덧셈(+) , 정수와의 뺄셈(-), 증감연산(++ , --)
p + n의 의미는 p+n*(포인터가 가리키는 자료형의 크기)= n개만큼 원소 뒤에 있는 메모리 주소
p – n의 의미는 p-n*(포인터가 가리키는 자료형의 크기)= n개만큼 원소 앞에 있는 메모리 주소
p ++의 의미는 p=p+(포인터가 가리키는 자료형의 크기)= 다음 원소의 주소
p -- 의 의미는 p=p-(포인터가 가리키는 자료형의 크기) = 이전 원소의 주소
포인터 연산을 기존의 산술연산과 다르게 정의한 이유는 무엇일까? ⇒ 산술 연산은 값을 더하는 것이지만 포인터 연산은 위치 이동이기 때문이다.
문제 2
다음 코드의 배열 표현을 포인터(주소) 표현으로 변경하시오.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
int grade[5];
int sum = 0, i, average;
for (i = 0; i < 5; i++)
{
printf("성적을입력하시오: ");
scanf("%d", &*(grade + i));
}
for (i = 0; i < 5; i++)
sum += *(grade + i);
average = sum / 5.0;
printf("성적평균= %d\n", average);
return 0;
}
실행결과
문제 3
증감연산자a++, ++a의차이를설명하시오. => a++는 변수 a의 값을 먼저 사용한 후 a를 1 증가시키며, 식의 결과는 값으로 나오지만 반면 ++a는 변수 a의 값을 먼저 1 증가시키고 그 증가된 변수자체가 식의 값이라는 차이가 있다.
#include<stdio.h>
int main(void)
{
inta[] = { 10, 20, 30 }, i, sum = 0;
for (i = 0; i < 3; i++)
sum += *a++;
printf("sum:%d\n", sum);
return 0;
}
문제 4
교재 299페이지 문제1에서 배열의 초기값을 키보드로부터 5개의 실수를 입력받아 저장하고 나머지는 문제와 동일하게 푸시오. 키보드로부터 입력받아 저장할때도 문제처럼 포인터변수를 증가 시키는 형태의 연산을 이용하여 작성하시오.-> 증감연산자사용
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
double arr[5];;
double* ptr = arr;
int i;
printf("5개의 실수입력:");
for (i = 0; i < 5; i++)
{
scanf("%lf", &arr[i]);
*ptr += 2; ptr++;
}
for (i = 0; i < 5; i++)
{
printf("%.1lf ", arr[i]);
}
return 0;
}
실행결과
문제 5
교재 300페이지 문제2에서 배열의 초기값을 키보드로부터 5개의 실수를 입력받아 저장하고 나머지는 문제와 동일하게 푸시오. 키보드로부터 입력받아 저장할때도 문제처럼 포인터 변수를 덧셈 연산을 하는 형태의 연산을 이용하여 작성하시오. 예제 11처럼 5가지 방식으로 코드를 모두 작성해볼것
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
double arr[5];;
double* ptr = arr;
int i;
printf("5개의 실수입력:");
for (i = 0; i < 5; i++) scanf("%lf", &arr[i]);
for (i = 0; i < 5; i++) *(ptr + i) += 2;
for (i = 0; i < 5; i++)
printf("%.1f ", arr[i]);
printf("\n");
for (i = 0; i < 5; i++)
printf("%.1f ", *(arr + i));
printf("\n");
for (i = 0; i < 5; i++)
printf("%.1f ", ptr[i]);
printf("\n");
for (i = 0; i < 5; i++)
printf("%.1f ", *(ptr + i));
printf("\n");
ptr = arr;
for (i = 0; i < 5; i++)
printf("%.1f ", *ptr++);
printf("\n");
return 0;
}
실행결과
13-2
문제 1
C언어에서 문자를 메모리에 저장하는 방식에 대하여 설명하라(아스키코드참고)⇒ 1바이트크기 메모리에 아스키코드 값으로 저장된다.
널 문자의 용도를 설명하라. ⇒ 문자열의 끝을 구하기 위해 사용된다.
메모리에 저장된 문자열의 끝을 찾는 방법을 설명하라. ⇒ 널문자를 만날 때 까지 반복문을 사용한다.
문자열의 길이를 구하는 알고리즘을 설명하라. ⇒ 널문자를 만날 동안 반복하며 개수를 증가시킨다.
문제 2
키보드를 통하여 문자열을 입력받고 문자열의 각 문자를 실행결과처럼 출력하시오.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char arr[20];
printf("문자열을 입력하시오: ");
scanf("%s", arr);
for (int i = 0; arr[i] != '\0'; i++)
{
printf("%d번째문자 %c\n", i + 1, arr[i]);
}
return 0;
}
실행결과
문제 3
키보드를 통하여 문자열을 입력받고 대문자는 소문자로 소문자는 대문자로 변환하는 코드를 작성하라.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char arr[20];
printf("문자열을 입력하시오: ");
scanf("%s", arr);
for (int i = 0; arr[i] != '\0'; i++)
{
if (arr[i] >= 'a' && arr[i] <= 'z')
arr[i] -= 32;
else arr[i] += 32;
}
printf("변환결과: %s", arr);
return 0;
}
실행결과
문제 4
2개의 문자열(모두 소문자)을 입력 받고 사전에서 앞에 나오는 문자열을 출력하시오. 라이브러리함수를 사용하지말고 문자열의 첫번째 문자의 아스키코드를 비교하여 구할 것. 사전에서 앞에 나오는 문자가 아스키코드가 작음
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char arr1[20], arr2[20];
int i = 0, j = 0;
printf("문자열을 입력하시오: ");
scanf("%s", arr1);
printf("문자열을 입력하시오: ");
scanf("%s", arr2);
while (arr2[j] != '\0' && arr1[i] != '\0')
i++; j++;
if (arr1[i] < arr2[j])
printf("%s\n", arr1);
else
printf("%s\n", arr2);
return 0;
}
실행결과
문제 5
사전에서 제일 앞에 나오는 문자열을 찾는 코드를 작성하시오.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main(void)
{
char* fruits[] = { "apple", "blueberry", "orange", "melon" };
int i, j, min = 0;
for (i = 1; i < 4; i++)
{
j = 0;
while (fruits[i][j] == fruits[min][j])
{
if (fruits[i][j] == '\0') break;
j++;
}
if (fruits[i][j] < fruits[min][j])
min = i;
}
printf("사전에서 가장 앞에 나오는 문자열: %s", fruits[min]);
return 0;
}
실행결과

첫댓글 다시 푸세요
변수의 주소의 자료형은 무엇인가? ⇒ 포인터형
포인터의 자료형은 무엇인가? ⇒ 가리키는 데이터의 자료형에 따라 결정된다.
변수의 주소를 int형 변수에 저장하면 어떻게 되는가? ⇒ 주소가 잘려 나갈 수 있다.
배열 표현과 포인터(주소) 표현의 변환공식을 설명하라. ⇒ *a[i] < = > (a+i) // &a[i] < = > a + i
배열의 첫번째 요소의 주소만알면 모든 원소의 주소를 계산할수있다. 방법을 설명하시오. ⇒ 원소의 크기는 자료형의 크기라서 첫 번째 요소에서부터 더하면 계산할 수 있다.
배열의 첫번째 요소의 주소만 알면 모든 원소의 값을 계산할수있다. 방법을 설명하시오. ⇒ 해당 주소를 포인터로 간접참조하면 값을 계산 할 수있다.
다음에서 pt에 저장될 주소의 자료형은 무엇인가? ⇒ double형 변수의 주소
아래 코드를 실행하면 오류가 발생하여 중단된다. 이유를 자세히 설명하라. => 125는 실제 주소가 아니기 때문에 접근하면 오류가 발생한다.