🙇‍♀️11


🪐배열

배열

int arr[3] = {1, 2, 3}; 총 12바이트를 선언받았다. (4 * 3)

arr[0] = 1; 인덱스를 통해서 대입

&arr[0]&(arr[0])은 같다.


🪐포인터의 산술 연산

Pointer Arithmetic

int* ptr = 0;

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

ptr += 1;

printf("%p %lld\n", ptr, (long long)ptr); //0000000000000008 8

// int만큼 커진다 void*라면 에러가 난다

최적화 작업을 한다면 void*를 사용한다.

ptr = -ptr; 사용불가.

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

//ptr2 = ptr1 + ptr2; // Not working
int i = ptr2 - ptr1; // 빼기는 된다

printf("%d", i); // 2


🪐포인터와 배열

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]); // 3값 모두 같다

ptr += 2;

printf("%p %p %p\n", ptr, arr + 2, &arr[2]); // 3값 모두 같다 8만큼 더해짐

//arr += 2; // error

printf("%d %d %d\n", *(ptr + 1), *(arr + 3), arr[3]); // 3값 모두 같다 400

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


🪐2차원 배열과 메모리

#include <stdio.h>

// 2차원 배열과 메모리

#define MONTHS 12
#define YEARS 3

int main()
{
	double year2016[MONTHS] = { -3.2, 0.2, 7.0, 14.1, 19.6, 23.6, 26.2, 28.0, 23.1, 16.1, 6.8, 1.2 };
	double year2017[MONTHS] = { -1.8, -0.2, 6.3, 13.9, 19.5, 23.3, 26.9, 25.9, 22.1, 16.4, 5.6, -1.9 };
	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 };


	// 2차원 배열 만들기
	double year[YEARS][MONTHS];
	for (int i = 0; i < YEARS; i++)
	{
		for (int j = 0; j < MONTHS; j++)
		{
			switch (i)
			{
			case 0:
				year[i][j] = year2016[j];
				break;
			case 1:
				year[i][j] = year2017[j];
				break;
			case 2:
				year[i][j] = year2018[j];
				break;
			default:
				break;
			}
		}
	}

	// 2차원배열 데이터 출력
	printf("[Temperature Data]\n");

	printf("Year index :");
	for (int i = 0; i < MONTHS; i++)
	{
		printf("\t%d", i + 1);
	}

	for (int i = 0; i < YEARS; i++)
	{
		for (int j = 0; j < MONTHS; j++)
		{
			if (j == 0)
			{
				printf("\n");
				printf("Year %d     : ", i);
			}
			printf("\t%.1f", year[i][j]);
		}
	}

	// 띄우기
	printf("\n\n");

	// 평균 기온 출력
	printf("[Yearly average temperatures of 3 years]\n");

	for (int i = 0; i < YEARS; i++)
	{
		double ave = 0, sum = 0;
		for (int j = 0; j < MONTHS; j++)
		{
			sum += year[i][j];
		}
			printf("Year %d : average temperaure = %.1f\n", i, sum / MONTHS);
	}

	// 띄우기
	printf("\n");

	// 3년 월별 평균 기온

	printf("[Monthly average temperatures for 3 years]\n");

	printf("Year index :");
	for (int i = 0; i < MONTHS; i++)
	{
		printf("\t%d", i + 1);
	}

	printf("\nAvg temps :");
	for (int i = 0; i < MONTHS; i++)
	{
		double sum = 0;
		for (int j = 0; j < YEARS; j++)
		{
			sum += year[j][i];
		}
		printf("\t%.1f", sum / YEARS);
	}

	// 띄우기
	printf("\n");

	return 0;
}


🪐배열을 함수에게 전달하는 방법

배열의 인자들의 평균을 구하는 함수

double Average(double arr[], int n)
{
	printf("Size = %zd in function average\n", sizeof(arr));

	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);
    


🪐두 개의 포인터로 배열을 함수에게 전달하는 방법

앞의 배열의 인자들의 평균을 구하는 함수이지만 두 개의 포인터를 이용한다

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

	return avg;
}

함수를 사용할 때는 주소값을 넣어줘야 하기때문에 printf("Average = %f\n", Average(arr1, arr1 + 5));처럼 사용한다.


🪐포인터 연산 총 정리

double 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 operator &

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 defference


🪐const와 배열과 포인터 정리

int arr[5] = { 1,2,3,4,5 };
arr[1] = 123;

double arr2[3] = { 1.0, 2.0, 3.0 };
arr2[0] = 100.0;

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

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

pd++; // allowed

여기서 const double* pd = arr2;라고 하면 *pd = 3.0;pd[2] = 1024.0;이 막힌다.

pd++;은 되는데 이거까지 막기위해서는 const double* const pd = arr2;라고 하면 된다.


🪐배열 매개변수와 const

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[], const int n, const int val)
{
	for (int i = 0; i < n; i++)
		arr[i] += val;
}

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

	for (int i = 0; i < n; i++)
		total += arr[i];

	return total;
}

함수의 매개변수로 배열을 줄 때는 배열의 값을 변경하는 상황이 아니라면 const를 붙이는 것이 좋다.


🪐2중 포인터의 작동 원리

int a = 7;

int* ptr = &a;
*ptr = 8; // 간접 접근 (역참조) Indirection (dereferencing)

// int (*(*pptr)) = &ptr;
int** pptr = &ptr;

// double indirection
**pptr = 9; // *(*(pptr)) = 9;


🪐포인터의 배열과 2차원 배열

  • Two of 1D arrays ```c

int arr0[3] = { 1, 2, 3 }; int arr1[3] = { 4, 5, 6 };

int* parr[2] = { arr0, arr1 }; // an array of pointers

for (int j = 0; j < 2; j++) { for (int i = 0; i < 3; i++) printf(“%d(==%d, %d) “, parr[j][i], (parr[j] + i), *((parr + j) + i)); // 똑같은 값을 출력한다 1(==1, 1) 2(==2, 2) … printf(“\n”); } printf(“\n”);


 * 2D arrays are arrays of 1D arrays

```c

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

int* parr0 = arr[0];
int* parr1 = arr[1];

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

for (int i = 0; i < 3; i++)
	printf("%d ", parr1[i]);
printf("\n");
  • Array of string of diverse lengths example ```c

char* name[] = { “Aladdin”, “Jasmine”, “Magic Carpet”, “Genie” };

const int n = sizeof(name) / sizeof(char*);

for (int i = 0; i < n; ++i) printf(“%s at %u\n”, name[i], (unsigned)name[i]); // Use ull in x64 build printf(“\n”);

char aname[][15] = { “Aladdin”, “Jasmine”, “Magic Carpet”, “Genie”, “Jafar”};

const int an = sizeof(aname) / sizeof(char[15]);

for (int i = 0; i < an; ++i) printf(“%s at %u\n”, aname[i], (unsigned)&aname[i]); // Use ull in x64 build printf(“\n”);


<br>

### 🪐2차원 배열과 포인터

```c
int arr[2][3] = { {1, 2, 3}, {4, 5,6} };
// arr == arr[0] == &arr[0] == &a[0][0] != a[0][0]
// a[0][0] == **arr

// &arr[0][1] = &arr[0][0] + 1

// arr + 1 == &arr[1] == &arr[0] + 1 == &a[1][0] != a[1][0]

// a[1][2] == *(*(arr+1)+2)

float arr2d[2][4] = { {1.0f, 2.0f, 3.0f, 4.0f}, {5.0f, 6.0f, 7.0f, 8.0f} };

printf("%u\n", (unsigned)arr2d);	// Use unsigned long long in x64
printf("%u\n", (unsigned)arr2d[0]);
printf("\n");

// arr2d points to arr2d[0] (not arr2d[0][0]), KNK Ch. 12.4

printf("%u\n", (unsigned)*arr2d);
printf("%u\n", (unsigned)&arr2d[0]);	// C language allows this
printf("%u\n", (unsigned)&arr2d[0][0]);
printf("%f %f\n", arr2d[0][0], **arr2d);
printf("\n");

printf("%u\n", (unsigned)(arr2d + 1));
printf("%u\n", (unsigned)(&arr2d[1]));
printf("%u\n", (unsigned)(arr2d[1]));
printf("%u\n", (unsigned)(*(arr2d + 1)));
printf("%u\n", (unsigned)(&arr2d[0] + 1));
printf("%u\n", (unsigned)(&arr2d[1][0]));
printf("\n");

printf("%f\n", *(*(arr2d + 1) + 2));
printf("\n");

for (int j = 0; j < 2; ++j)
{
	printf("[%d] = %u, %u\n", j, (unsigned)(arr2d[j]), (unsigned)*(arr2d + j));

	for (int i = 0; i < 4; ++i)
	{
		printf("[%d][%d] = %f, %f\n", j, i, arr2d[j][i], *(*(arr2d + j) + i));

		*(*(arr2d + j) + i) += 1.0f; // arr2d[j][i] += 1.0f;
	}
}
printf("\n");


🪐다차원 배열을 함수에게 전달해주는 방법

#include <stdio.h>

#define ROWS 3
#define COLS 4

int sum2d_1(int ar[ROWS][COLS]);
int sum2d_2(int ar[][COLS], int row);
int sum2d_3(int *ar, int row, int col);

int main()
{
	int data[ROWS][COLS] = {
	{ 1, 2, 3, 4 },
	{ 5, 6, 7, 8 },
	{ 9, 0, 1, 2 }
};
	printf("%d\n", data[2][3]);

	int* ptr = &data[0][0];
	printf("%d\n", *(ptr + 3 + COLS * 2));

	//printf("Sum of all elements = %d\n", sum2d_1(data));
	//printf("Sum of all elements = %d\n", sum2d_2(data, ROWS));
	//printf("Sum of all elements = %d\n", sum2d_3(&data[0][0], ROWS, COLS));

	

	return 0;
}

int sum2d_1(int ar[ROWS][COLS])
{
	int r, c, tot = 0;
	for (r = 0; r < ROWS; r++)
		for (c = 0; c < COLS; c++)
			tot += ar[r][c];
	return tot;
}

int sum2d_2(int ar[][COLS], int row)
{
	int r, c, tot = 0;
	for (r = 0; r < row; r++)
		for (c = 0; c < COLS; c++)
			tot += ar[r][c];
	return tot;
}

int sum2d_3(int* ar, int row, int col)
{
	int r, c, tot = 0;
	for (r = 0; r < row; r++)
		for (c = 0; c < col; c++)
			tot += *(ar + c + col * r); // ar[c + col * r]
	return tot;
}

태그:

카테고리:

업데이트: