27 March 2019

Notes for Pre-U Physics

I would like to write some notes (minimalist's notes) for certain topics in pre-university physics. I found that some students may be confused by the content of these topics, and sometimes I would also want to make a quick revision should I need them. That's why I write the notes and share them here.

I am a minimalist in writing notes: Just retain the essential definitions and concepts, while omit obvious applications and consequences. Keep in mind if you want to use them. 😊

06 November 2016

Array Initialization in C and C++

A smart student new to C/C++ is confused by array initialization in C and C++. Indeed, standard says something, best practices say something, and compilers may say something else too. So I wrote this.
Note that I wrote in year 2016, this is important because many things can change very fast in the computing world! I will try to update it when I am free.

/* Array initialization in C and C++ */


// Stop GCC from nagging. Yes, you can use gcc/g++ to compile this piece of source code.

#pragma GCC diagnostic ignored "-Wunused-variable"

// This declares an array of 4 integers

// - It has static storage allocation
int ar01[4];

// The first two will be initialized to 1 and 2

// - There is only one copy of this variable, therefore the variable
//   has static storage.
// - The array will be initialized once during load time.
int ar02[4] = {1,2};

int main(void)

{
  // This declares an array of 4 integers
  int ar03[4];

  // The first two will be initialized to 1 and 2

  int ar04[4] = {1,2};

  // The array will be initialized to 2, 3, 4 and 5

  // - How about 6? It's extra and will be ignored by the compiler
  // - C compiler generally issues a warning for this
  //   E.g., gcc: warning: excess elements in array initializer
  // - C++ compiler generates an error instead
  //   E.g., g++: error: too many initializers for int [4]
  int ar05[4] = {2,3,4,5,6};
  // This is a stack-dynamic variable. Therefore it has to be
  // initialized each time it's declared.
  // - A compiler will generally translate the code to:
  //     int ar05[4];
  //     ar05[0] = 2;
  //     ar05[1] = 3;
  //     ar05[2] = 4;
  //     ar05[3] = 5;
  // - In other words, array initialization here is just a syntactic sugar.

  // This declares an array of characters

  // - First 3 elements initialized to 'a', 'b', 'c'
  char ar06[4] = {'a', 'b', 'c'};

  // In C, a string is simply an array of characters where the final

  // character is null ('\0').
  // The array below is thus a C string.
  char ar07[4] = {'a', 'b', 'c', '\0'};

  // We can use a string literal as a 'shortcut' to initialize this array.

  char ar08[4] = "abc";
  // It is important to note that, when you do so, the compiler simply
  // translates the code to:
  //    char ar08[4];
  //    ar08[0] = 'a';
  //    ar08[1] = 'b';
  //    ar08[2] = 'c';
  //    ar08[3] = '\0';

  // How about this?

  char ar09[4] = "abcdef";
  // The size of array initializer is greater than the size of array.
  // So the compiler will ignore excess elements.
  // - In other words, the compiler will simply treat the code above as:
  //     char ar09[4] = {'a', 'b', 'c', 'd'};
  // - Note that 'e', and 'f' will simply be *ignored* by the compiler!
  //     (If you have doubt, use gcc -S and examine the assembly output.)
  // - A string "abcdef" will NEVER be generated by the compiler!
  // - C compiler generally issues a warning for this
  //   E.g., gcc: warning: initializer-string for array of chars is too long
  // - C++ compiler generates an error instead
  //   E.g., g++: error: initializer-string for array of chars is too long

  // How about this?

  char ar10[4] = "abcd";
  // Same as the array above.
  // - So the compiler will ignore the excess terminating null character.
  // - Interestingly, C compiler may not issue warning
  //   for this excess null character!
  //   - E.g., gcc 5.4.1 and clang 3.8.0 do not issue warning here
  //   - However, this array should NOT be used as a normal C string,
  //     since there is NO guarantee that it is null-terminated!
  // - C++ compiler generates an error instead!
  //   E.g., g++: error: initializer-string for array of chars is too long
  // - So this is a 'boundary' case between C and C++:
  //   - No problem with C (may not even have a warning!)
  //   - Error with C++

  // If the size of the array is the same as that of the array initializer,

  // we can choose not to specify the size and let the compiler to fill it
  // in for us.
  int ar11[] = {3, 4, 5};
  // In this case, the size of the array is 3.

  // Same for array of characters

  char ar12[] = {'a', 'e', 'i', 'o', 'u'};
  // In this case, the size of the array is 5

  // How about a C string?

  char ar13[] = "aeiou";
  // In this case, the code is equivalent to:
  //     char ar13[] = {'a', 'e', 'i', 'o', 'u', '\0'};
  // So the size of array is 6.

  // Now, consider the following code:

  char *str01 = "aeiou";
  // We are NOT declaring an array, so there is no array initializer here!
  // Instead, the statement above is equivalent to:
  //     char *str01;
  //     str01 = "aeiou";
  // Here:
  // - When the program is loaded, (at least) 6 bytes will be allocated
  //   to store the null-terminated string "aeiou".
  //   - The string "aeiou" will be allocated to a region that is
  //     supposed to be read-only, enforced either by the hardware
  //     or by the operating system. In other words, the technically
  //     correct data type should be "const char *".
  //   - However, such intensive use of the 'const' keyword is not
  //     practiced by many C programmers.  Nonetheless, care must
  //     be taken as not to modify such strings, or it can lead
  //     to undefined behavior.
  // - When the statement above is reached:
  //   (1) A few bytes will be allocated for the character pointer 'str01'
  //   (2) The pointer will then be assigned the starting address of the
  //       string "aeiou" allocated above.
  //
  // Differences between 'ar13' and 'str01':
  // (1) While 'str01' can be assigned a new value (an address), 'ar13'
  //     can be reassigned and always refers to the starting address of
  //     the array.
  // (2) Storage is allocated for 'str01', but no storage is allocated
  //     for the name 'ar13'.
  //
  // - C compiler generally accepts the statement.
  //   - Since 'const' is not practiced in many C programs, the warning
  //     is disabled by default (in gcc and clang)
  // - C++ compiler generates warning for it since 'const' is encouraged
  //   to be used whenever possible:
  //     gcc -std=c++98: warning: deprecated conversion from string constant to ‘char*’
  //     gcc -std=c++11: warning: ISO C++ forbids converting a string constant to ‘char*’
  //   - So the statement is best to be replaced with:
  //         const char *str01 = "aeiou";

  return 0;

}

27 May 2015

Setup WinEdt to Use Cygwin/TeX Live

1. Scenario

I have installed Cygwin, and included TeX Live so that I can compile LaTeX files in Cygwin.
Then I install WinEdt 9, and to save hard disk space, I would like to configure WinEdt such that it can (re-)use Cygwin/Tex Live.

2. Configuration

2.1. Edit System Environment Vaiables to include Path to Cygwin Executables

Skip this step if you have included the path to Cygwin executables.
  1. In Windows 8.1, press [Windows Key] + [Q], type "variables", and select "Edit the system environment variables" from the list. (For other Windows versions, try to find "System Properties", then select "Environment Variables...".)
  2. Under System variables, select "Path" variable, click "Edit...". Append ";C:\cygwin\bin" to the value.
  3. Click 'Ok' three times to complete.

2.2. Configure WinEdt 9

  1. Select Options > Configurations > TeX Live. This tells WinEdt 9 to make use of TeX Live.
  2. Go to Options > Execution Modes.
  3. Select TeX System tab.
  4. Modify the following fields
    • TeX Root: C:\cygwin
    • TeX Bin: C:\cygwin\bin
    • TeX Help: C:\cygwin\usr\share\texmf-dist\doc
  5. Select TeX Options tab.
  6. Modify the following fields
    • Default PDFTeXify Engine: pdftex.exe -fmt=latex -output-format=pdf

3. Bonus

Can use Sumatra PDF, which synchronizes well with WinEdt and TeX Live.

18 January 2013

BASH: Single-Quotes inside a Single-Quoted String

In bash, to escape some characters for the command-line arguments properly, you can use single quotes. E.g.,
$ file 'Some # Weird File Name.odt'
But how about the single quote characters? There are several methods. I found the following ways most convenient.

(1) Replace ' with '\''

Break out of the quoted string, and escape the single quote alone.
 $ file 'My wife'\''s file.txt'
(2) Replace ' with '"'"'

Same idea, but different way of escaping the single quote.
$ file 'My wife'"'"'s file.txt'
So, in Python, you can use:
s = string.replace("'", "'\"'\"'")
or in PHP,
s = str_replace("'", "'\"'\"'", string);

17 January 2013

MPlayer & MEncoder: Manipulating Audio Channels

MPlayer provides powerful controls to manipulate different audio channels.

During playback,

  • ( and ) keys: Adjust audio balance in favor of left/right channel.
  • # key: Cycle through the available audio tracks.
You can add, remove, route, or copy audio channels with the -af channels=nch[:nr:from1:to1:from2:to2:from3:to3:...] option. For example, if there are 2 channels, and you want to copy channel 0 to channel 1 (and thus abandon the original channel 1), you can use -af channels=2:2:0:0:0:1.

You can even mix the channels with specified proportions with the -af pan=... option. Unfortunately, the suboptions are naturally much more complicated. Basically you can specify a 2D matrix to indicate the amount of each source channel that will be mixed to the destination channel.

References: