简体   繁体   中英

How to implement a printing function?

Most of the time, when I need a specific functionality not implemented in the standard library, I try to implement it myself. I also create static libraries to use and reuse code.

So I was thinking of writing a test program independent from standard library. This program is missing a printing function. Printing, usually,is a major part of a computer program.

How can a printing function as simple as putchar() or cout be implemented in C or C++?

My Code:

#define TRUE        1
#define FALSE       0

typedef int INT_32;
typedef unsigned int size_t;

struct block {
    INT_32 v;
    size_t x;
};

void f1(struct block *s);
int  f2(void *addr);

int main(void)
{
    struct block blk;
    f1(&blk);
    //print blk members

    int res = f2(&blk);
    // print res

    return 0;
}

void f1(struct block *s)
{
    s->v = -1;
    s->x = 1
}

int f2(void *addr)
{
    if (addr) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}

Well, the most basic one I can come up, for POSIX systems, is:

void putchar(int ch)
{
  const unsigned char character = (unsigned char) ch;
  write(STDOUT_FILENO, &character, 1);
}

This just asks the write() system call to do the write, to stdout . On non-POSIX systems you're going to have to use something else.

Errors are ignored, since putchar() 's prototype doesn't include a return value.

Note that this assumes you don't have "proper" buffered high-level I/O functions, since it basically implements a function that belongs to that group but very simply and without buffering. See the manual page for more about this.

The int -format character is knocked down to an unsigned character to comply with the specification for putchar() . I removed bitwise-AND I had there since it hardcodes 8-bit bytes which is ugly and pointless. This should be fine and keep the proper bits.

You're going to have to use system calls, there's no "native" printing in C after all.

I/O is necessarily platform dependent - because the I/O may be performed on any kind of device from a window manager device context to a UART; which is why it is abstracted by the standard library.

However that is not the only level of abstraction; in an OS such as Linux or Windows for example stdout maps to a file descriptor which refers to a device driver (with some layers probably omitted) - several layers of software are involved. If the output is to the screen it gets even more complex since then the window manager and GPU are likely to be involved too.

You can of course skip the stdio layer and access the underlying OS API, BIOS or device driver for example, but in a system that runs a full modern OS direct output to some output device is not something you would do lightly (because amongst other things other applications may be using that resource for example).

In a bare-metal embedded system with no OS or with a kernel that does not itself support I/O on the other hand; you can do what you like; but in that case the answer is truly platform specific and would depend on the device you choose to output to; it may be a display or it may be a serial port for example, but it is entirely hardware specific.

You could define a macro to print characters:

#define my_putchar(x) write(0, &(x), 1)
/*                    write             - write to a file descriptor
                            0           - standard output file descriptor
                               &(x)     - pointer to the specified character
                                     1  - number of characters to be printed 
*/

For reference:

unsigned int write(int fd, const void *buf, unsigned int count);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM