Can someone please explain this line

北城以北 提交于 2019-12-14 03:36:01

问题


K_count = (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0]) ? ++K_count : 1);

It is a part of this simple code, and i cant understand how precisely does it work?


回答1:


this basically increments through the available options on a standard US telephone keypad for the "3" key, looping back to the first option after the last is reached. it does so by referencing a 3-dimensional array containing the options for each key layed out as row/column/options. it is written in such a way that it can be reused for other keys with minor modifications.

the "...?...:..." construct is basically a shortcut for if/else. so you can rewrite the statement like this:

if (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0])) {
    K_count = ++K_count;
} else {
    K_count = 1;
}

the "++" operator simply adds 1 to the variable, so you can rewrite as:

if (K_count < (byte)(CharacterMask[0][(customKey - '0') - 1][0])) {
    K_count = K_count + 1;
} else {
    K_count = 1;
}

CharacterMask is a 3-dimensional array that describes a typical telephone keypad. the first 2 dimensionsindicate the row and column of the keypad. the third dimension contains the options available on that key. so, for example, the 3 key on a telephone has 4 options (3,d,e, and f). for some reason, the author also includes the option count as the first item in the array (index 0). so CharacterMask[0][2] would give you an array containing the number 4 followed by the characters '3','d','e', and 'f'. as such, CharacterMask[0][2][0] will return the number 4. similarly CharacterMask[0][2][1] would return the char '3'. since this line of code is only really concerned with the number of options, not their values, the final array index is hard-coded to 0. given that, you can rewrite the code like this to clarify:

rowIndex = 0;
columnIndex = (customKey - '0') - 1;
optionCountIndex = 0;
if (K_count < (byte)(CharacterMask[rowIndex][columnIndex][optionCountIndex])) {
    K_count = K_count + 1;
} else {
    K_count = 1;
}

since customKey is a char and not a number, we can use the "-" operator to subtract the '0' char. this implicitly casts both values to a byte and returns the difference between those bytes. since the numbers are ordered 0-9 in most character sets, this effectively gets us the numerical value of the character stored in the customKey variable (e.g. char 3 becomes byte 3). so the code can be rewritten as follows:

rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
if (K_count < (byte)(CharacterMask[rowIndex][columnIndex][optionCountIndex])) {
    K_count = K_count + 1;
} else {
    K_count = 1;
}

since they keys 1,2,3 are found in columns 0,1,2 in a zero-based indexed column count, we need to subtract 1 from the keyNumber to get the column index as shown above

because CharacterMask is a char array, we need to cast the first value to a byte to get the value initially entered back. this rewrite clarifies that:

rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
optionCountAsCharType = (CharacterMask[rowIndex][columnIndex][optionCountIndex]);
if (K_count < (byte)optionCountAsCharType) {
    K_count = K_count + 1;
} else {
    K_count = 1;
}

the comparison with K_count relies on the fact that the option array length is equal to the option count plus 1. since it is zero-based indexed, that means the last index is equal to the option count. so as long as the current K_count (aka option index) is less than the option count, you can still add 1 without exceeding the max index value. but if you are on the last index, you must roll back to 1 (the index of the first option). it could be made more clear with one more refactor:

rowIndex = 0;
keyNumber = (customKey - '0');
columnIndex = keyNumber - 1;
optionCountIndex = 0;
optionCountAsCharType = (CharacterMask[rowIndex][columnIndex][optionCountIndex]);
nextIndexIsInsideArrayBounds = K_count < (byte)optionCountAsCharType
if (nextIndexIsInsideArrayBounds) {
    K_count = K_count + 1;
} else {
    K_count = 1;
}



回答2:


You can expand that single line of code to:

int temp = (byte)(CharacterMask[0][(customKey - '0') - 1][0]);
if ( K_count < temp )
{
   K_count = ++K_count;
   // This is bad. See the comment about sequence points.
   // It should be
   K_count = K_count + 1;
}
else
{
   K_count = 1;
}



回答3:


(customKey - '0') - 1

This takes the value of customKey, subtracts the ASCII value of "0" (0x30), and then subtracts 1 from that.

CharacterMask[0][x][0]

This takes the 0th element of CharacterMask, takes the xth element of the result, and then takes the 0th element of that result.

(byte)x

This truncates x to its 8 least significant bits.

K_count < x

This is true (i.e. non-zero) if K_count is less than x.

x ? y : z;

This results in y if x is true, otherwise it results in z.

As to what it actually does, that depends on what CharacterMask and customKey are.



来源:https://stackoverflow.com/questions/30082934/can-someone-please-explain-this-line

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!