Cyril Troian
Cyril Troian

Reputation: 13

Iterate through alphabet in Swift explanation

I accidentally wrote this simple code to print alphabet in terminal:

var alpha:Int = 97

while (alpha <= 122) {
    write(1, &alpha, 1)
    alpha += 1
}

write(1, "\n", 1)
//I'm using write() function from C, to avoid newline on each symbol

And I've got this output:

abcdefghijklmnopqrstuvwxyz
Program ended with exit code: 0

So, here is the question: Why does it work? In my logic, it should display a row of numbers, because an integer variable is being used. In C, it would be a char variable, so we would mean that we point to a sign at some index in ASCII. Then:

char alpha = 97;

Would be a code point to an 'a' sign, by incrementing alpha variable in a loop we would display each element of ascii through 122nd.

In Swift though, I couldn't assign an integer to Character or String type variable. I used Integer and then declared several variables to assign UnicodeScalar, but accidentally I found out that when I'm calling write, I point to my integer, not the new variable of UnicodeScalar type, although it works! Code is very short and readable, but I don't completely understand how does work and why at all.

Has anyone had such situation?

Upvotes: 1

Views: 544

Answers (1)

Martin R
Martin R

Reputation: 539805

Why does it work?

This works “by chance” because the integer is stored in little-endian byte order. The integer 97 is stored in memory as 8 bytes

0x61 0x00 0x00 0x00 0x00 0x00 0x00 0x00

and in write(1, &alpha, 1), the address of that memory location is passed to the write system call. Since the last parameter (nbyte) is 1, the first byte at that memory address is written to the standard output: That is 0x61 or 97, the ASCII code of the letter a.

In Swift though, I couldn't assign an integer to Character or String type variable.

The Swift equivalent of char is CChar, a type alias for Int8:

var alpha: CChar = 97

Here is a solution which does not rely on the memory layout and works for non-ASCII character as well:

let first: UnicodeScalar = "α"
let last: UnicodeScalar = "ω"

for v in first.value...last.value {
    if let c = UnicodeScalar(v) {
        print(c, terminator: "")
    }
}

print()

// αβγδεζηθικλμνξοπρςστυφχψω

Upvotes: 2

Related Questions