Showing posts with label C++. Show all posts
Showing posts with label C++. Show all posts

Tuesday, 28 December 2021

Text formatting on a mainframe

Today I recalled that as a student in the 70s I discovered that the line printer attached to the Univac 1108 mainframe at my university's computer centre could print lower case characters. So I modified the Ratfor workalike of the Unix roff program that I had entered into the computer to treat all alphabetic characters as lower case, and implemented escape codes to raise (and lower later) the case for capitalised words and acronyms. This was to be able to use punch cards as input, as the terminals were not always available. I don't remember if I implemented auto-detection of beginning of sentences, probably not. I even typeset my undergraduate thesis this way.

At that time I was using Ratfor as a structured Fortran, having been introduced to it and the book that described it, Software Tools, at a work experience stint, and had not yet encountered Unix in person. It was only when I did my masters that I learnt Unix and C.

I have wondered if the computer operators were surprised by the appearence of lower case printout since everybody else seemed to accept that UPPER CASE was the only case available.

Wednesday, 7 November 2018

sizeof operator in C and C++ should be better known

Having seen some code examples on the Internet where sizeof should be used, I thought I'd offer a short reminder of a couple of useful cases:

1. A EPROM burner program to run on Arduino where the data was embedded as a byte array in the sketch which is then compiled and downloaded to run:

What was written:

const int progSize = 1024;
const byte hexProg[progSize] = { ... };
...
for (i = 0; i < progSize; i++) {
...
}

What should have been written:

const byte hexProg[] = { ... };
...
for (i = 0; i < sizeof(hexProg); i++) {
...
}

This has the advantage of automatically adapting to the number of bytes that actually need to be programmed instead of always 1024.

2. An Arduino program to test a LCD display:

What was written:

char row1[] = "I'm Arduino";
...
for (int positionCounter1 = 0; positionCounter1 < 26; positionCou
nter1++) {


This prints junk after the greeting because it strays past the end of the string, which is also a security hazard.

What should have been written:

for (int positionCounter1 = 0; positionCounter1 < sizeof(row1) - 1; positionCounter1++) {

The - 1 is to not print the NUL byte at the end of the string. A reminder, if the string is say UTF-8, sizeof gives the number of bytes in the string, not the number of characters. But usually the number of bytes is what you want.

Also do not make this mistake:

char *row1 = "I'm Arduino";

In this case sizeof(row1) will be sizeof(char *) on the machine, not the length of the phrase I'm Arduino.

A couple of other idioms.

Getting the number of elements in an array:

int divisors[] = { 2273, 2145, 2025, 1911, ... };
const int ndivisors = sizeof(divisors)/sizeof(int);

Or even better:

const int ndivisors = sizeof(divisors)/sizeof(divisors[0]);

which means you can change the type of the divisors array to be other than an int without changing the second line.

Allocating the right amount of memory from heap:

double *readings;
...
readings = malloc(NREADINGS * sizeof(double));

And a reminder, sizeof is a compile-time operator, so there is no runtime cost to using it. If the expression provided to sizeof cannot be evaluated at compile-time, the compiler will tell you.