💡

따배씨 10.1 ~ 본문

따배씨

따배씨 10.1 ~

아옳이 2021. 1. 25. 19:00

10.1 배열과 메모리

 

-&arr[0] = &(arr[0])인 이유는 []가 &보다 연산자 우선순위가 높기 때문이다

-메모리를 읽을때 자료형의 크기만큼 건너서 메모리를 찾는다

-인덱스가 0부터 시작하는 이유는 인덱스 숫자는 첫번째 주소로부터의 거리를 의미하기 때문이다

따라서 첫번째 인덱스는 첫번째 주소 그 자체(거리가 0)이기 때문에 0이 된다

ex) arr = &arr[0]

 

 

10.2 배열의 기본적인 사용방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define MONTH 12

int main()
{
	/* Basic usage */
	int high[MONTH] = { 2, 5, 11, 18, 23, 27, 29, 30, 26, 20, 12, 4 };

	for (int i = 0; i < MONTH; i++)
		printf("%d ", high[i]);
	printf("\n");

	float avg = 0.0;
	for (int i = 0; i < MONTH; i++)
		avg += high[i];
	printf("AVERAGE = %f\n", avg / (float)MONTH);

	high[0] = 1;
	high[1] = 2;
	//high = { 1, 2, 3, 4, ,5 ,6 ,7 ,8 ,9 ,10, 11, 12};// Not working
	//high[12] = { 1, 2, 3, 4, ,5 ,6 ,7 ,8 ,9 ,10, 11, 12};// Not working
	//	선언을 한 후에는 한꺼번에 초기화 X

	/* Addresses */
	printf("%p %p\n", high, &high[0]);

	for (int i = 0; i < MONTH; ++i)
		printf("%lld\n", (long long)&high[i]);	//	high의 형식지정자가 int 이기 떄문에 주소가 4씩 늘어난다
	printf("\n");

	/* Compiler doesn't checkwhether indices are valid */
	high[12] = 4;	//	Error
	high[-1] = 123; //	Error

	/* const and array */
	const int temp = 0;
	// temp = 4;	X
	const int low[12] = { -7, -5, 1, 7, 13, 18, 22, 22, 16, 9, 2, -5 };
	// low[0] = 123;	X

	/* When array is not initialized */
	int not_init[4];		//	static int not_init[4]; -> 0으로 초기화됨	
	for (int i = 0; i < 4; i++)
		printf("%d\n", not_init);	//	쓰레기값 나옴

	/* Partially initialized */
	int insuff[4] = { 2, 4 };
	for (int i = 0; i < 4; i++)
		printf("%d\n", insuff[i]);	//	나머지 배열을 0으로 초기화

	/* Overlly initialized */
	int over[2] = { 2, 4, 8, 16 };	//	Error

	/* Omitting size */
	const int power_of_twos[] = { 1, 2, 4, 8, 16, 32, 64 };
	printf("%d\n", sizeof(power_of_twos));
	printf("%d\n", sizeof(int));
	printf("%d\n", sizeof(power_of_twos[0]));

	for (int i = 0; i < sizeof power_of_twos / sizeof power_of_twos[0]; ++i)
		printf("%d ", power_of_twos[i]);

	/* Designated initializers */
	int days[MONTH] = { 31, 28,[4] = 31, 30, 31,[1] = 29 };
	for (int i = 0; i < MONTH; i++)
		printf("%d ", days[i]);	//	31 29 0 0 31 30 31 0 0 0 0 0

	/* Specifiying Array sizes */
	int arr1[MONTH];	//	Symbolic integer constant
	double arr2[123];	//	Literal integer constant
	float arr3[3 * 4 + 1];
	float arr4[sizeof(int) + 1];
	//float arr5[-10]	//	No
	//float arr6[0];	//	No
	//float arr7[1.5];	//	No
	float arr8[(int)1.5];	//	Yes

	//int n = 8;
	//float arr9[n];
	/* Variable Length Array is optional from C11
	위의 코드는 VS에서 이제 사용 할수 없다.
	대신 동적할당으로 위의 코드 형태를 구현할 수 있다.*/

	return 0;
}

 

 

10.3 포인터의 산술 연산

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define MONTH 12

int main()
{
	int* ptr = 0;

	//printf("%d", *ptr);//Error in this lecture

	printf("%p %lld\n", ptr, (long long)ptr);	//	00000000 0

	ptr++;	//	자료형의 사이즈만큼

	printf("%p %lld\n", ptr, (long long)ptr);	//	00000000 4

	//ptr = -ptr	//	Not working
	//ptr = +ptr	//	Not working

	/* Subtraction */
	int arr[10];
	int* ptr1 = &arr[3], * ptr2 = &arr[5];

	//ptr2 = ptr1 + ptr2;	//	Not working
	int i = ptr2 - ptr1;	//	주소 인덱스의 차

	printf("%p %p %d\n", ptr1, ptr2, i);
	printf("%lld %lld %d\n", (long long)ptr1, (long long)ptr2, i);

	return 0;
}

 

 

10.4 포인터 배열

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define MONTH 12

int main()
{
	int arr[10];

	int num = sizeof(arr) / sizeof(arr[0]);
	for (int i = 0; i < num; ++i)
		arr[i] = (i + 1) * 100;

	int* ptr = arr;

	printf("%p %p %p\n", ptr, arr, &arr[0]);

	ptr += 2;

	printf("%p %p %p\n", ptr, arr + 2, &arr[2]);

	//Note: arr += 2;	//	invalid

	printf("%d %d %d\n", *(ptr + 1), *(arr + 3), arr[3]);

	//Warning
	printf("%d %d %d\n", *ptr + 1, *arr + 3, arr[3]);

	int* ptr = arr;
	for (int i = 0; i < num; i++)
	{
		printf("%d %d\n", *ptr++, arr[i]);
		printf("%d %d\n", *(ptr + i), arr[i]);
		printf("%d %d\n", *ptr + i, arr[i]);	//	다른 결과
	}

	return 0;
}

 

 

10.5 2차원 배열과 메모리

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


int main()
{
	int arr[2][3] = { {1,2,3},{4,5,6} };

	//int arr[2][3] = {1,2,3,
	//				4, 5, 6};
	//int arr[2][3] = {1,2};//insufficient initializer

	printf("%d\n\n", arr[1][1]);

	for (int j = 0; j < 2; j++)
	{
		for (int i = 0; i < 3; i++)
			printf("%d ", arr[j][i]);

		printf("\n");
	}
	printf("\n");

	//Note: inner loop uses i


	int* ptr = &arr[0][0];
	for (int k = 0; k < 6; ++k)
		printf("%d ", ptr[k]);
	printf("\n\n");

	printf("%zd %zd\n", sizeof(arr), sizeof(arr[0]));	//	24 12
	printf("\n");

	return 0;
}

 

 

10.6 2차원 배열 연습문제

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

#define MONTHS 12
#define YEARS 3

int main()
{
	double year2020[MONTHS] = { 1.6,2.5,7.7,11.1,18.0,23.9,24.1,26.5,21.4,14.3,8.0,-0.4 };
	double year2019[MONTHS] = { -0.9,1.0,7.1,12.1,19.4,22.5,25.9,27.2,22.6,16.4,7.6,1.4 };
	double year2018[MONTHS] = { -4.0,-1.6,8.1,13.0,18.2,23.1,27.8,28.8,21.5,13.1,7.8,-0.6 };

	double year3[YEARS][MONTHS];

	for (int i = 0; i < MONTHS; i++)
	{
		year3[0][i] = year2018[i];
		year3[1][i] = year2019[i];
		year3[2][i] = year2020[i];
	}
	
	printf("[Temperature Date]\n");
	printf("year index :\t");
	for (int i = 1; i <= MONTHS; i++)
		printf("%d\t", i);
	printf("\n");
	
	for (int j = 0; j < YEARS; j++)
	{
		printf("Year %d :\t", j);
		for (int i = 0; i < MONTHS; i++)
			printf("%3.1f\t", year3[j][i]);
		printf("\n");
	}
	printf("\n");

	printf("[Yearly average temperatures of 3 years]\n");
	for (int j = 0; j < YEARS; j++)
	{
		printf("Year %d :\t", j);
		double sum = 0;
		for (int i = 0; i < MONTHS; i++)
		{
			sum += year3[j][i];
		}
		printf("average temperature = %3.1f\n", sum / MONTHS);
	}
	printf("\n");

	printf("[Monthly average temperatures for 3 years]\n");
	printf("year index :\t");
	for (int i = 1; i <= MONTHS; i++)
		printf("%d\t", i);
	printf("\n");
	printf("Avg temps :\t");
	for (int i = 0; i < MONTHS; i++)
	{
		double avg = 0;
		for (int j = 0; j < YEARS; j++)
			avg += year3[j][i];
		avg /= YEARS;
		printf("%.1f\t", avg);
	}
	printf("\n");
	
	return 0;
}

 

 

10.7 배열을 함수에게 전달해주는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

double average(double*, int n);

int main()
{
	double arr1[5] = { 10, 13, 12,7, 8 };
	//double arr2[5] = { 1.8, -0.2, 6.3, 13.9, 20.5 };
	double arr2[3] = { 1.8, -0.2, 6.3 };	//	size is differnt

	printf("Address = %p\n", arr1);
	printf("Size = %zd\n", sizeof(arr1));
	printf("Avg = %f\n", average(arr1, 5));
	printf("\n");
	printf("Address = %p\n", arr2);
	printf("Size = %zd\n", sizeof(arr2));
	printf("Avg = %f\n", average(arr2, 3));

	return 0;
}

double average(double* arr, int n)
{
	double avg = 0.0;
	for (int i = 0; i < n; ++i)
	{
		avg += arr[i];
	}
	avg /= (double)n;

	return avg;
}

/*
double average(double arr[], int n);
double average(double [], int n);
double average(double* arr, int n);
double average(double*, int n);
*/

배열을 함수에 전달해줄 때는 포인터를 사용한다

 

 

10.8 두 개의 포인터로 배열을 함수에게 전달해주는 방법

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

double average(double*, double*);

int main()
{
	double arr1[5] = { 10, 13,12, 7,8 };

	printf("Avg = %f\n", average(arr1, arr1 + 5));	//	마지막 주소 다음주소

	return 0;
}

double average(double* start, double* end)
{
	int count = end - start;
	double avg = 0.0;
	while (start < end)
	{
		avg += *start++;
	}
	avg / +(double)count;

	return avg;
}

 

 

10.9 포인터 연산 총정리

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	/*
	Pointer operations
	-Assignment
	-Value finding (deferencing)
	-Taking a pointer address
	-Adding an integer to a pointer
	-Incrementing a pointer
	-Subtractiong an integer from a pointer
	-Decrementing a pointer
	-Differencing
	-Comparisons
	*/

	int arr[5] = { 100, 200, 300, 400, 500 };
	int* ptr1, * ptr2, * ptr3;

	ptr1 = arr;		//	Assignment

	printf("%p %d %p\n", ptr1, *ptr1, &ptr1);//	dereferencing, Taking a pointer address
	ptr2 = &arr[2];	//	Address-of opertor &

	printf("%p %d %p\n", ptr2, *ptr2, &ptr2);

	ptr3 = ptr1 + 4;//	Adding an integer from a pointer

	printf("%p %d %p\n", ptr3, *ptr3, &ptr3);

	//Differencing
	printf("%td\n", ptr3 - ptr1);	//Note: t is for pointer differnce

	ptr3 = ptr3 - 4;//	Subtracing aninteger from a pointer

	printf("%p %d %p\n", ptr3, *ptr3, &ptr3);

	ptr1++;			//	Incrementing, ptr1 = ptr1 + 1
	ptr1--;			//	Decrementing
	--ptr1;
	++ptr1;

	if (ptr1 == ptr3)
		printf("Same\n");
	else
		printf("Different\n");

	double d = 3.14;
	double* ptr_d = &d;
	if (ptr1 == ptr_d)	//	warning C4133: '==' incompatible types - from 'double' to 'int*'
	//if (ptr1 == (int*)ptr_d)
	//if ((double*)ptr1 == ptr_d)
		printf("Same\n");
	else
		printf("Different\n");

		return 0;
}

 

 

10.10 const와 배열과 포인터

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main()
{
	//	typequalifiers: const, volatile, ...

	const double PI = 3.14159;
	//PI = 2.14159;
	
	const int arr[5] = { 1, 2, 3, 4, 5 };
	//arr[1] = 123;
	
	const double arr2[4] = { 1.0, 2.0, 3.0, 4.0};
	//arr2[0] = 100.0;

	const double* pd = arr2;
	//*pd = 3.0;		//	pd[0] = 3.0; arr2[0] = 3.0;	
	//pd[2] = 1024.0;	//	arr2[2] = 1024.0;

	printf("%f %f", pd[2], arr[2]);

	pd++;//	allowed

	printf("%f %f", pd[2], arr[2]);

	/*
	const double* pd2 = arr2; //pd2 주소값이 가르키는 메모리값을 못바꾼다.\

	double* const pd3 = arr2; //포인터 변수의 주소값을 못바꾼다

	const double* const pd4 = arr2; //포인터변수의 주소값과 가르키는 메모리값 둘다 못바꾼다
	*/

	return 0;
}

 

 

10.11 배열 매개변수와 const

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

void print_array(const int arr[],const int n)
{
	for (int i = 0; i < n; i++)
		printf("%d ", arr[i]);
	printf("\n");
}

void add_value(int arr[], int n, int val)
{
	int i;
	for (i = 0; i < n; i++)
		arr[i] += val;
}

int sum(const int arr[], const int n)
{
	int i;
	int total = 0;

	for (i = 0; i < n; i++)
		//total += arr[i]++;	//	wrong implementation
		total += arr[i];
	return total;
}

int main()
{
	int arr[] = { 1, 2, 3, 4, 5 };
	int n = sizeof(arr) / sizeof(arr[0]);

	print_array(arr, 5);
	add_value(arr, 5, 100);
	print_array(arr, 5);

	int s = sum(arr, n);

	printf("Sum is %d\n", s);

	return 0;
}

 

'따배씨' 카테고리의 다른 글

따배씨 11.3 ~  (0) 2021.01.27
따배씨 10.12 ~  (0) 2021.01.26
따배씨 9.10 ~  (0) 2021.01.21
따배씨 9.1 ~  (0) 2021.01.19
따배씨 7.10 ~  (0) 2021.01.18