๋ฐ๋ฐฐ์จ 10.12 ~
10.12 ํฌ์ธํฐ์ ๋ํ ํฌ์ธํฐ(2์ค ํฌ์ธํฐ)์ ์๋ ์๋ฆฌ
ํฌ์ธํฐ๋ฅผ ๋ฐฐ์ด์ฒ๋ผ ์ฌ์ฉ(ํฐ ๋ฉ๋ชจ๋ฆฌ ๊ณต๊ฐ์ ์ ๊ทผํด์ ์ฌ์ฉ)ํ๋ค๊ณ ํ๋ฉด
์ด์คํฌ์ธํฐ๋ ๋ฐฐ์ด์ ๋ฐฐ์ด์ฒ๋ผ ์ฌ์ฉํ๋ค
์ง๊ธ์ ๊ทธ๋ฅ ๊ทธ๋ ๊ตฌ๋ ํ๊ณ ๋์ด๊ฐ๋ฉด ๋๋ค๊ณ ํ๋ค
10.13 ํฌ์ธํฐ์ ๋ฐฐ์ด๊ณผ 2์ฐจ์ ๋ฐฐ์ด
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
/* Two of 1D arrays */
int arr0[3] = { 1, 2, 3 };
int arr1[3] = { 1, 2, 3 };
int* parr[2] = { arr0, arr1 };
for (int j = 0; j < 2; j++)
{
for (int i = 0; i < 3; i++)
printf("%d(==%d, %d, %d) ", parr[j][i], *(parr[j] + i), *(*(parr + j) + i), (*(parr+j))+[i]));
printf("\n");
}
printf("\n");
/* 2D arrays are arrays of 1D arrays */
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");
/* arrays of pointers works like a 2D array */
int arr[2][3] = { {1, 2, 3}, {4, 5, 6} };
//int* parr[2] = {arr[0], arr[1]};
int* parr[2];
parr[0] = arr[0];
parr[1] = arr[1];
for (int j = 0; j < 3; j++)
{
for (int i = 0; i < 3; i++)
printf("%d %d %d %d\n",
arr[j][i], parr[j][i], *(parr[j] + i), *(*(parr + j) + i));
printf("\n");
}
printf("\n");
/*
parr[0] and parr[1] do not point valid memory by default
&parr[0] != &arr[0]
&parr[0] != parr[0] but &arr[0] == arr[0]
*/
printf("%p\n", &parr[0]); // different!
printf("%p\n", parr[0]);
printf("%p\n", arr);
printf("%p\n", &arr[0]);
printf("%p\n", arr[0]);
printf("%p\n", &arr[0][0]);
/* Array of string of diverse lengths ewample */
char* name[] = { "Aladdin", "Jasmine", "Magic Carpet", "Genie" };
const int n = sizeof(name) / sizeof(char*);
for (int i = 0; i < n; i++)
printf("%d at %u\n", name[1], (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");
return 0;
}
10.14. 2์ฐจ์ ๋ฐฐ์ด๊ณผ ํฌ์ธํฐ
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
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);
printf("%u\n", (unsigned)arr2d[0]);
printf("\n");
// arr2d points to arr2d[0] (not arr2d[0][0])
printf("%u\n", (unsigned)*arr2d);
printf("%u\n", (unsigned)&arr2d[0]);
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[1][0]));
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");
return 0;
}
-๋ฐฐ์ด๋ช ๊ณผ &๋ฐฐ์ด๋ช ์ ๊ฐ์ ์ฃผ์๊ฐ์ด๋ค.
-์ด์ฐจ์ ๋ฐฐ์ด๋ช arr2d๋ 1์ฐจ์ ๋ฐฐ์ด๋ช arr2d[0]์ ํฌ์ธํ ํ๋ค, ๋ฐ๋ผ์ ์๋ฏธ์ ์ผ๋ก๋ *arr2d == arr2d[0] ์ด๋ค
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
/* Pointers to Nultidimensional Arrays */
float arr2d[2][4] = { {1.0f, 2.0f, 3.0f, 4.0f}, {5.0f, 6.0f, 7.0f, 8.0f} };
float(*pa)[4]; // a SINGLE pointerto an array of 4 floats // ๋ฐฐ์ด์ ํฌ์ธํฐ
float* ap[2]; // anarray of two pointers-to-float // ํฌ์ธํฐ์ ๋ฐฐ์ด
printf("%zu\n", sizeof(pa)); // 8 in X64
printf("%zu\n", sizeof(ap)); // 16 in x64
printf("\n");
pa = arr2d;
//pa[0] = arr2d[0]; // error
//pa[1] = arr2d[1]; // error
//ap = arr2d; // error
ap[0] = arr2d[0];
ap[1] = arr2d[1];
printf("%u %U\n", (unsigned)pa, (unsigned)(pa + 1)); // ์ฃผ์๋ฅผ ๋์
printf("%u %U\n", (unsigned)arr2d[0], (unsigned)arr2d[1]);
printf("%u %U\n", (unsigned)pa[0], (unsigned)(pa[0] + 1));
printf("%f\n", pa[0][0]);
printf("%f\n", *pa[0]);
printf("%f\n", **pa);
printf("%f\n", pa[1][3]);
printf("%f\n", *(*(pa + 1) + 3));
printf("\n");
printf("%u %U\n", (unsigned)ap, (unsigned)(ap + 1)); // ์๋ก์ด ์ฃผ์ ์๊น
printf("%u %U\n", (unsigned)arr2d[0], (unsigned)arr2d[1]);
printf("%u %U\n", (unsigned)ap[0], (unsigned)(ap[0] + 1));
printf("%f\n", ap[0][0]);
printf("%f\n", *ap[0]);
printf("%f\n", **ap);
printf("%f\n", ap[1][3]);
printf("%f\n", *(*(ap + 1) + 3));
printf("\n");
return 0;
}
pa๋ ๋ฐฐ์ด์ ๋ํ ํฌ์ธํฐ๋ก์ arr2d๋ฐฐ์ด์ฃผ์๊ฐ์ ๋์ ํ ์ ์์ง๋ง pa[0] = arr2d[0]์ฒ๋ผ ๋ฐฐ์ด์ฒ๋ผ ์ด๊ธฐํ๋ ๋ชปํ๋ค
๋ฐ๋๋ก ap๋ ํฌ์ธํฐ๋ก ์ด๋ฃจ์ด์ง ๋ฐฐ์ด๋ก์ arr2d ๋ฐฐ์ด์ฃผ์๊ฐ์ ๋์ ํ ์ ์๊ณ , ๋ฐฐ์ด์ ์์๋ฅผ ๊ฐ๊ฐ ์ด๊ธฐํ ํด์ค์ผ ํ๋ค
10.15 ํฌ์ธํฐ์ ํธํ์ฑCompatibility
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
/* pointer Compatibility */
{
int n = 5;
double x;
x = n; // no error
int* p1 = &n;
double* pd = &x;
//pd = p1; // Warning
}
{
int* pt;
int(*pa)[3];
int ar1[2][3] = { 3, };
int ar2[3][2] = { 7, };
int** p2; // a pointer to a pointer
pt = &ar1[0][0]; // pointer-to-int
pt = ar1[0]; // pointer-to-int
//pt = ar1; // Warning (Error) ar1์ 2์ฐจ์ ๋ฐฐ์ด - ํฌ์ธํฐ์ ๋ชป๋ด์
pa = ar1; // pointer-to-int[3]
//pa = ar2; // Warning (Error)
p2 = &pt; // pointer-to-int *
*p2 = ar2[0]; // pointer-to-int
//p2 = ar2; // Warning (Error)
//Notes
// - p2: pointerto pointer to int
// - ar2: a pointer to array-of-two-ints
}
/* pointer and const */
{
int x = 20;
const int y = 23;
int* p1 = &x;
const int* p2 = &y;
const int** pp2 = &p1;
//p1 = p2; // Warning (Error)
//*p2 = 123; // Error
p2 = p1;
int x2 = 30;
int* p3 = &x2;
*pp2 = p3;
pp2 = &p1;
}
{
const int** pp2;
int* p1;
const int n = 13;
pp2 = &p1; // const?
*pp2 = &n; // sets p1 to point at n
*p1 = 10; // change n
}
/* C const and C++ const */
{
const int y;
const int* p2 = &y;
int* p1;
p1 = p2; // Warning (error in cpp)
}
return 0;
}
- ๋ฐฐ์ดํฌ์ธํฐ int(*p)[2]๋ฅผ ์ ์ธํ๋ค๋ฉด, ์์ 2๊ฐ์ง๋ฆฌ ๋ฐฐ์ด๋ก ํต์ผ์์ผ์ผ๋ง ์ธ ์ ์๋ค.
- const ์ฌ์ฉ ์ฃผ์
10.16 ๋ค์ฐจ์ ๋ฐฐ์ด์ ํจ์์๊ฒ ์ ๋ฌํด์ฃผ๋ ๋ฐฉ๋ฒ
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define ROWS 3
#define COLS 4
int sum2d_1(int ar[ROWS][COLS]); // ๋์ ํธ์ถ์, 2์ฐจ์ ๋ฐฐ์ด์์ ROWS ๋ถ๋ถ์ ๋ฌด์๋จ
int sum2d_2(int ar[][COLS], int row); // ๋ฐฐ์ด์ ์ด๋ฆ์ ์ฒซ์์์ ์ฃผ์์ด๊ธฐ ๋๋ฌธ์ ํฌ์ธํฐ๋ก ๋ณํ๋๋ค
//int sum2d_2(int [][COLS], int row);
//int sum2d_2(int (*ar)[COLS], int row); // ar is a SINGLE pointer to the array of COLS ints
int sum2d_3(int* ar, int row, int col); // ๋์ ํ ๋น์์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ
//int sum2d_3{int*, int, int};
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)); // *(ptr + c + col * r)
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); //r[c + col * r]
return tot;
}
10.17 ๋ณ์๋ก ๊ธธ์ด๋ฅผ ์ ํ ์ ์๋ ๋ฐฐ์ด Variable-Length Arrays (VLAs)
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int n = 5;
float my_arr[n]; // VS์์๋ ์ปดํ์ผ ์์์ผ์ค
// ํ๋ฒ ๊ธธ์ด๋ฅผ ์ ํด์ฃผ๋ฉด ๋ชป๋ฐ๊ฟ
// ์ฌ์ฉX
for (int i = 0; i < n; i++)
my_arr[i] = (float)i;
for (int i = 0; i < n; i++)
printf("%f\n", my_arr[i]);
return 0;
}
10.18 ๋ณตํฉ ๋ฆฌํฐ๋ด๊ณผ ๋ฐฐ์ด Compound Literals
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define COLS 4
int sum_1d(int arr[], int n);
int sum_2d(int arr[][COLS], int rows);
int main()
{
int a = 1;
3; // Literals are constants that aren't symbolic
3.14f;
int b[2] = { 3,4 };
(int[2]) {3, 4}; // compound literal
//int c[2] = (int[2]){3,4}; // Error
int arr1[2] = { 1,2 };
int arr2[2][COLS] = { {1, 2, 3, 4},{5, 6, 7, 8} };
printf("%d\n", sum_1d(arr1, 2));
printf("%d\n", sum_2d(arr2, 2));
printf("\n");
printf("%d\n", sum_1d((int[2]) {1, 2}, 2));
printf("%d\n", sum_2d((int[2][COLS]) { {1, 2, 3, 4}, {5, 6, 7, 8} }, 2));
printf("\n");
int* ptr1;
int(*ptr2)[COLS];
ptr1 = (int[2]){ 1, 2 };
ptr2 = (int[2][COLS]){ {1, 2, 3, 4}, {5, 6, 7, 8} };
printf("%d\n", sum_1d(ptr1, 2));
printf("%d\n", sum_2d(ptr2, 2));
return 0;
}
int sum_1d(int arr[], int n)
{
int total = 0;
for (int i = 0; i < n; i++)
total += arr[i];
return total;
}
int sum_2d(int arr[][COLS], int rows)
{
int total = 0;
for (int r = 0; r < rows; r++)
for (int c = 0; c < COLS; c++)
total += arr[r][c];
return total;
}
- ๋ณตํฉ ๋ฆฌํฐ๋ด์ ํจ์์ argument๋ก ๋ณด๋ด ์ค ์ ์๋ค sum_1d((int[2]) { 1, 2 }, 2)
- ๋ณตํฉ ๋ฆฌํฐ๋ด์ ํฌ์ธํฐ์ ๋ฐ๋ก ๋์ ํ ์ ์๋ค ptr1 = (int[2]) { 1, 2 }
11.1 ๋ฌธ์์ด์ ์ ์ํ๋ ๋ฐฉ๋ฒ๋ค
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#define MESSAGE "A symbolic string contant"
#define MAXLENGTH 81
int main()
{
char words[MAXLENGTH] = "A string in an array";
const char* pt1 = "A pointer to a string";
puts("Puts() adds a newline at the end"); // puts() add \n at the end
puts(MESSAGE);
puts(words); // char words[21]remove this warning
puts(pt1);
words[3] = 'p'; // OK
puts(words);
//pt1[8] = 'A'; // Error
char greeting[50] = "Hello, and" " How are" " you" " today!";
// char greeting[50] = "Hello, and How are you today!";
puts(greeting);
printf("\" to be, or not to be\" Hamlet said.\n");
printf("%s, %p, %c\n", "We", "are", *"excellent programmers");
const char m1[15] = "Love you!";
for (int i = 0; i < 15; i++)
printf("%d ", (int)m1[i]); // note the null characters
printf("\n");
const char m2[15] = { 'L', 'o', 'v', 'e', ' ', 'y', 'o', 'u', '!', '\0' };
const char m3[] = "Love you, too!";
int n = 8;
int cookies[1] = { 'A', };
char cakes[2 + 5] = { 'A', };
char pies[2 * sizeof(long double) + 1] = { 'A', };
//char crumbs[n]; // VLAs
char truth[10] = "Truth is ";
if (truth == &truth[0]) puts("true!");
if (*truth == 'T') puts("true!");
if (*(truth + 1) == truth[1]) puts("true!");
if (truth[1] == 'r') puts("true!");
return 0;
}
printf("%c", *"excellent programmers");
์ ๊ฒฐ๊ณผ๋ excellent programmers์ ์ฒซ๋ฒ์งธ ๋ฉ๋ชจ๋ฆฌ์ฃผ์์ indirectiosn์ผ๋ก 'e' ์ด๋ค.
11.2 ๋ฉ๋ชจ๋ฆฌ ๋ ์ด์์๊ณผ ๋ฌธ์์ด
Stack: ์ง์ญ๋ณ์, ๋งค๊ฐ๋ณ์(ํจ์ ํธ์ถ์ ์์ ๋ณ์์ ์ฅ)
Heap: ์ปดํ์ผํ์์ ํฌ๊ธฐ๋ฅผ ์์ ์๋ ๋ฉ๋ชจ๋ฆฌ
Text Segment: ์ฝ๊ธฐ์ ์ฉ
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h> // malloc
void test_function()
{
int j;
printf("Stack high \t%llu\n", (unsigned long long) & j);
}
int main()
{
/* Array vs pointer */
const char* pt2 = "I am a string!.";
const char* pt3 = "I am a string!."; // pt2์ ๊ฐ์ ์ฃผ์๋ฅผ ํฌ์ธํ
const char* pt4 = "I am a string!!!!!!."; // different
const char* ar1[] = "I am a string!.";
const char* ar2[] = "I am a string!."; // ๋ฐฐ์ด ์์ฒด ๋ฉ๋ชจ๋ฆฌ์ ์ ์ฅํ๋ฏ๋ก ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ
const char* ar3[] = "I am a string!!."; // different
printf("rodata low \t%iiu %iiu %iiu %llu\,",
(unsigned long long)pt2, (unsigned long long)pt3, (unsigned long long)pt4,
(unsigned long long)"I am a string!.");
printf("Stack high \t%llu %llu %llu\n", (unsigned long long)ar1,
(unsigned long long)ar2, (unsigned long long)ar3);// cgeck address numbers!
// Memory adress check
// Local variables
printf("Stack high \t%llu %llu %llu\n",
(unsigned long long) & pt2, (unsigned long long) & pt3, (unsigned long long) & pt4);
int i;
printf("Stack high \t%llu\n", (unsigned long long) & i);
// local variable in a function
test_function();
// Dynamic allocation // ๋์ ํ ๋น
char* p5 = (char*)malloc(sizeof(char) * 100);
printf("Heap middle \t&llu\n", (unsigned long long)p5);
char* p6 = (char*)malloc(sizeof(char) * 100);
printf("Heap middle \t&llu\n", (unsigned long long)p6);
// Array vs Pointer (continued)
//ar1++; // Error ๋ฐฐ์ด๋ช
์ ๋ณ์๊ฐ ์๋
pt2++; // OK
puts(pt2); // Check the first character
// Array and pointer Differences
char heart[] = "I love kelly!"; // ๋ฐฐ์ด
const char* head = "I love Helly!"; // ํฌ์ธํฐ
for (int i = 0; i < 6; i++)
putchar(heart[i]);
putchar('\n');
for (int i = 0; i < 6; i++)
putchar(head[i]); // ํฌ์ธํฐ๋ฅผ ๋ฐฐ์ด์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ
putchar('\n');
// pointer addition
for (int i = 0; i < 6; i++)
putchar(*(heart + i));
putchar('\n');
for (int i = 0; i < 6; i++)
putchar(*(head + i)); // ๋ฐฐ์ด๋ช
์ ํฌ์ธํฐ์ฒ๋ผ ์ฌ์ฉ ๊ฐ๋ฅ
putchar('\n');
while (*(head) != '\0')
putchar(*(head++));
head = heart; // ๋ฐฐ์ด์ ์ฒซ๋ฒ์งธ ์ฃผ์ ๊ฐ๋ฅดํค๋๋ก
//heart = head // Error
// Cannot change heart. Can change the elements of heart
heart[7] = 'H'; // Note: character
*(heart + 7) = 'K';
putchar('\n');
char* word = "Goggle";
word[2] = 'o'; // Run-time error!
puts(word);
//Note: const char * word = "Goggle"; is recommended
const char* str1 = "When all the lights are low, ...";
const char* copy;
copy = str1;
printf("%s %p %p\n", str1, str1, &str1);
printf("%s %p %p\n", copy, copy, ©);
//Note: strcpy(),strncpy()
return 0;
}