문득 수직탭은 들어 본적은 있는데 머하는데 쓰고,
어떻게 출력이 되는지는 모른다는 깨달음(?)을 얻었다.
검색을 해봐도 이렇다할 결과가 없긴한데...
대충 추려내자면
예전에 리본/도트 프린터 시절에 제어를 위해 존재했었는데,
프린터에서 수평탭은 8칸, 수직탭은 6줄마다 이동하도록 되어있다고 한다.
하지만, Virtual Terminal 상에서 표현은 자율에 맡기다 보니,
이상한 문자가 출력되거나, 엔터 처럼 처리되는 경우가 많은것으로 보인다.
대충 리눅스 상에서 해보니 \v (vertical tab)은 LF의 느낌이 든다.
LF(Line Feed)는 지금의 위치에서 바로 아래로 내려지게 되고, CR(Carriage Return)은 가장 앞줄로 이동하게 된다.
(타자기를 생각하면 한글자씩 쓰다가 끝까지 치게 되면 왼쪽으로 미는데 그걸 CR이라고 보면되고
종이를 밀어서 한줄 아래로 내리는걸 LF라고 보면된다.)
The following control
codes are optional but should have the
indicated effect on the display.
Name
code
Decimal Value
Function
BELL
BEL
7
Produces an audible or visible signal (which does NOT
move the print head.
Back Space
BS
8
Moves the print head one character position towards the
left margin. [On a printing devices this mechanism was commonly used to
form composite characters by printing two basic characters on top of
each other.]
Horizontal
Tab
HT
9
Moves the printer to the next horizontal tab stop. It
remains unspecified how either party determines or establishes where
such tab stops are located.
Vertical
Tab
VT
11
Moves the printer to the next vertical tab stop. It
remains unspecified how either party determines or establishes where
such tab stops are located.
Form Feed
FF
12
Moves the printer to the top of the next page, keeping
the same horizontal position. [On visual displays this commonly clears
the screen and moves the cursor to the top left corner.]
vertical
tab (′vərd·ə·kəl ′tab)
(computer science) A control character that causes a computer
printer to jump
from its current line to another preset line further
down the page.
Originally
printers used mechanical tab stops to indicate where the tabs
went. This was done horizontally with movable metal prongs in a row and
vertically with a loop of mylar or other tape the length of a
page with holes punched in it to indicate the tab stops. Initially
these were manually set to match the preprinted forms the printer was
going to print. The intention was to have the machine be programmed with
other control characters to set and clear the stops: ISO 6429 includes the codes 136 Horizontal
Tabulation Set, 137 Horizontal Tabulation with Justification and 138
Vertical Tabulation Set.
Instead settable tab stops were rather quickly replaced with fixed
tab
stops, at
every multiple of 8 characters horizontally and every 6 lines
vertically. A printing program could easily add the necessary
spaces or
line feeds to move to any position wanted on a form, this was far more
reliable than the modal and non-standard
methods of setting tab stops. Tab characters simply became a form of
data compression. The vertical size was chosen to be 1 inch. It is
unclear why the 8-character horizontal size was chosen, as 5 characters,
half inch in a typical printer at that time, was much more popular at
that time as a paragraph indentation. It may have been chosen to match
early Fortran
conventions for where the statement text started after the line number
and continuation character. Or it may have been chosen as the smallest
size that would fit numbers typically printed in a table.
문자열 중에 확장 문자열이라는 게 있다. 대표적으로 \n 같은 경우인데 일종의 정해진 규약이다. 이 중에
수직탭이라는 게 있는데 \v
로 표현된다. C 언어 펀더멘탈 책을 보던 중 궁금증이 들어서 출력을 해보니 윈도우 콘솔 상에서는
이상한 특수문자를 하나 출력해주고 만다. 하지만 리눅스 콘솔에서 출력해보니 세로로 한 칸 내려가버린다. 즉 다음과 같은 결과를
보여준다.
#include "stdio.h"
int main(int argc, char *argv[])
{
int x = 1;
printf("%d %d %d\n", ++x, x, x++);
return 0;
}
You're running into two issues:
1. Undefined behavior -- you are attempting to modify the value of an
object more than once between sequence points, and the Standard imposes
no requirement on how to handle that behavior. Basically, any
expression of the forms:
i = i++;
j = k++ * k++;
foo(i,i++,--i);
invoke undefined behavior. Read up on the semantics of the "++" and
"--" operators in an *authoritative* reference (the Standard would
obviously be one, but also K&R2 or H&S5); they don't work the
way most
people think they should.
2. Order of evaluation -- AFAIK, there's no requirement that
expressions in a function parameter list be evaluated in any particular
order. At first blush, it *looks* like the arguments were evaluated
from right to left (if x = 1, then x++ evaluates to 1, with the side
effect that x == 2, and ++x evaluates to 3, with the side effect that x
== 3), but given that you've invoked undefined behavior the actual
reason may be something else entirely.
$ gcc -Wall cc_test.c
cc_test.c: In function ‘main’:
cc_test.c:6: warning: operation on ‘x’ may be undefined
cc_test.c:6: warning: operation on ‘x’ may be undefined
이런 경고가 발생한다.
분명 x는 변수인데, 그에 대한 operation이 정의되지 않았다는게 무슨 말인지 모르겠지만,
아무튼 실행을 하면
$ ./a.out
3 3 1
요런 희한한 결과가 나온다.
아무튼, calling convention과도 연관이 있어 보이는데,
c언어 특성상 right-left 로 push 하므로(가장 위에는 왼쪽 값이 오도록)
가장 먼저들어가는, 오른쪽 x++ 은 1이 들어가고
1을 더해준다음, 다음 명령어를 수행하면서(++x) 한번에 2가 증가하게 되고
그럼으로 인해 x, ++x 순으로 3이 들어가는게 아닐까 생각된다.
expat 글 보다가 무슨 말인지 몰라서 검색은 해봤는데 점점더 미궁으로 빠져드는 느낌이다 ㄱ-
일단은 call stack 관련 선언문이라는것 외에는 이해를 전혀 못하겠다 ㅠ.ㅠ
cdecl
On the Intel 386, the cdecl attribute causes the compiler to assume that the calling function will pop off the stack space used to pass arguments. This is useful to override the effects of the -mrtd switch.
stdcall
On the Intel 386, the stdcall attribute causes the compiler to assume that the called function will pop off the stack space used to pass arguments, unless it takes a variable number of arguments.
fastcall
On the Intel 386, the fastcall attribute causes the compiler to pass the first two arguments in the registers ECX and EDX. Subsequent arguments are passed on the stack. The called function will pop the arguments off the stack. If the number of arguments is variable all arguments are pushed on the stack.
All arguments are widened to 32 bits when they are passed. Return
values are also widened to 32 bits and returned in the EAX register,
except for 8-byte structures, which are returned in the EDX:EAX
register pair. Larger structures are returned in the EAX register as
pointers to hidden return structures. Parameters are pushed onto the
stack from right to left.
The compiler generates prolog and
epilog code to save and restore the ESI, EDI, EBX, and EBP registers,
if they are used in the function.
Note When
a struct, union, or class is returned from a function by value, all
definitions of the type need to be the same, else the program may fail
at runtime.
For information on how to define your own function prolog and epilog code, see Naked Function Calls.
The following calling conventions are supported by the Visual C/C++ compiler.
static char array[]; 로 선언한 변수를
포인터로 다른 파일에 있는 함수로 넘겼을 경우, 읽지 못하고 죽어 버린다는 사실이다.
Static global variables are declared as "static" at the top level of a source file. Such variables are not visible outside the source file ("file scope"), unlike variables declared as "extern".