'분류 전체보기'에 해당되는 글 84건
- 2010.07.03 c++ 오버라이딩
- 2010.06.26 itoa 대신 sprintf
- 2010.06.26 라이브러리
- 2010.06.26 volatile
- 2010.06.24 포인터 상수
- 2010.06.22 [컴파일 강좌] 2강 - C++ 분할 컴파일
- 2010.06.21 [컴파일 강좌] 1강 - C 분할 컴파일
- 2010.06.19 __attribute__
- 2010.06.14 동적 할당 0614
- 2010.06.13 문자열
'Compile 강좌' 카테고리의 다른 글
[컴파일 강좌] 2강 - C++ 분할 컴파일 (0) | 2010.06.22 |
---|---|
[컴파일 강좌] 1강 - C 분할 컴파일 (0) | 2010.06.21 |
컴파일러 옵션 (0) | 2010.05.30 |
'C' 카테고리의 다른 글
itoa 대신 sprintf (0) | 2010.06.26 |
---|---|
포인터 상수 (0) | 2010.06.24 |
문자열 (0) | 2010.06.13 |
구조체 (0) | 2010.06.12 |
버블 정렬 c 0609 (0) | 2010.06.09 |
#include <stdio.h>
int main(void) {
int arr[4] = {1, 2, 3, 4};
printf("&arr = %p\n", &arr); // 0012FF54
printf("arr = %p\n", arr); // 0012FF54
printf("&arr[0] = %p\n", &arr[0]); // 0012FF54
return 0;
}
arr과 &arr 이 출력하는 메모리주소는 분명 같습니다만,
그 의미에는 미묘한 차이가 있습니다.
익히 아시고 계신 것처럼 arr은 &arr[0] 과 같은 의미이며, 그 data type은 배열의 data type입니다.
즉 arr + 1의 의미는 arr[0]에서 int형의 size만큼, 4byte 이동한 주소, &arr[1]을 의미할 수 있습니다
하지만 &arr은 그렇지 않습니다. &arr은 arr이라는 이름의 int형 4개짜리 일차원 배열의 시작주소입니다.
이것은 즉 (&arr) + 1 이 &arr[1] 을 의미하지 않음을 말합니다.
이러한 맥락에서 (&arr) + 1은 arr[0]에서 int형의 size*배열의 데이터 갯수(4) 를 곱한만큼 이동한 곳
의 주소입니다. 다음의 코드를 봐주세요.
int a[4] = {0, 1, 2, 3};
int (*pa)[4] = &a; /* 그냥 a를 쓰면 에러가 납니다 &a[0]과 &a는 의미하는 바가 달라서입니다
pa는 int형의 데이터 4개를 가지는 일차원배열을 가리키는 포인터입니다 */
pa++; /* 메모리 주소가 sizeof(int) * 4(배열데이터갯수) 만큼 이동합니다 */
printf("%d\n", (*pa)[-1]); /* pa가 가리키는 일차원 배열을 참조한 후 -1 인덱스,
즉 이는 a[3]을 의미합니다 */
출력되는 값은 물론 3입니다 :)
PS) int (*pa)[4]; /* 위에 나온대로 일차원배열을 가리키는 포인터를 선언합니다 */
int *pa[4]; /* int형의 포인터 4개를 가지는 일차원배열을 선언합니다 */
'C' 카테고리의 다른 글
itoa 대신 sprintf (0) | 2010.06.26 |
---|---|
volatile (0) | 2010.06.26 |
문자열 (0) | 2010.06.13 |
구조체 (0) | 2010.06.12 |
버블 정렬 c 0609 (0) | 2010.06.09 |
'Compile 강좌' 카테고리의 다른 글
라이브러리 (0) | 2010.06.26 |
---|---|
[컴파일 강좌] 1강 - C 분할 컴파일 (0) | 2010.06.21 |
컴파일러 옵션 (0) | 2010.05.30 |
#include <stdio.h> void swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; } void disp(int a, int b) { printf("a = %d, b = %d\n", a, b); } int main() { int a = 10; int b = 30; disp(a, b); swap(&a, &b); disp(a, b); return 0; } |
void swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; } |
void disp(int a, int b) { printf("a = %d, b = %d\n", a, b); } |
#include <stdio.h> #include "swap.c" #include "disp.c" int main() { int a = 10; int b = 30; disp(a, b); swap(&a, &b); disp(a, b); return 0; } |
void swap(int* a, int* b) { int temp; temp = *a; *a = *b; *b = temp; } |
#include <stdio.h> void disp(int a, int b) { printf("a = %d, b = %d\n", a, b); } |
void swap(int*, int*); void disp(int, int); int main() { int a = 10; int b = 30; disp(a, b); swap(&a, &b); disp(a, b); return 0; } |
void swap(int* a, int* b); |
void disp(int a, int b); |
#include "swap.h" #include "disp.h" int main() { int a = 10; int b = 30; disp(a, b); swap(&a, &b); disp(a, b); return 0; } |
'Compile 강좌' 카테고리의 다른 글
라이브러리 (0) | 2010.06.26 |
---|---|
[컴파일 강좌] 2강 - C++ 분할 컴파일 (0) | 2010.06.22 |
컴파일러 옵션 (0) | 2010.05.30 |
- The 'signal' attribute ensures that every processor register that gets modified during the ISR is restored to its original value when the ISR exits. This is required as the compiler cannot make any assumptions as to when the interrupt will execute, and therefore cannot optimize which processor registers require saving and which don't.
- The 'signal' attribute also forces a 'return from interrupt' instruction (RETI) to be used in place of the 'return' instruction (RET) that would otherwise be used. The AVR microcontroller disables interrupts upon entering an ISR and the RETI instruction is required to re-enable them on exiting.
Avr-gcc defines an interrupt vector as a name that the linker will use to overide the weak reset addresses in the AVR interrupt vector table. For example, the USART0 receiver interrupt on an ATmega128 is defined as:
#define USART0_RX_vect _VECTOR(18)
The _VECTOR(18) macro is expanded to:
#define USART0_RX_vect __vector_18
and so the ISR macro used to define the corresponding interrupt handler in code expands to:
void __vector_18(void) __attribute__ ((signal, __INTR_ATTRS));
and this wll compile into the assembler output as the two lines:
.global __vector_18 __vector_18:
The linker picks up the name as matching the corresponding interrupt vector table entry and makes the replacement into the vector table. Thus an interrupt with this number will arrive at the corresponding interrupt handler.
However in C++ the name is mangled early in the compile process and prevents the linking from occurring. Patch #6805 allows an interrupt handler name to be represented by a number, and while the name will be mangled as usual, the number survives for later linking. The patch provides for an optional numeric argument to the signal function. An interrupt function prototype using this system for the same USART0 receiver interrupt looks like:
void IntName(void) __attribute__ ((signal(18), __INTR_ATTRS));
The numeric signal argument is translated by this Patch into the same two assembler lines as above. The given name is still processed according to the language rules. The name is thus independent of the vector number, but the number is attached to the name. Note that for C++, by the time the signal argument is being processed the given name is mangled.
Once implemented the Patch can be used, but to be versatile it will require an additional definition for each interrupt in each processor. The current proposal is to add the new definition along with those existing. For example, the USART interrupt above for the '128 in file iom128.h will now have two lines.
#define USART0_RX_vect _VECTOR(18) #define USART0_RX_vect_num 18
The corresponding new interrupt macro for C++ interrupt declarations is defined in Interrupts.h as:
#define ISRN(name, number) void name(void) __attribute__ ((signal(number), __INTR_ATTRS));