[c/en] clarity, errata, and grammar in array section (#4102)

* [c/en] clarity, errata, and grammar in array section

- [x] I solemnly swear that this is all original content of which I am the original author
- [x] Pull request title is prepended with `[language/lang-code]` (example `[python/fr-fr]` or `[java/en]`)
- [x] Pull request touches only one file (or a set of logically related files with similar changes made)
- [x] Content changes are aimed at *intermediate to experienced programmers* (this is a poor format for explaining fundamental programming concepts)
- [x] If you've changed any part of the YAML Frontmatter, make sure it is formatted according to [CONTRIBUTING.md](https://github.com/adambard/learnxinyminutes-docs/blob/master/CONTRIBUTING.markdown)
  - [x] Yes, I have double-checked quotes and field names!

* Overlooked type uniformity

* Improve 80 col alignment and clarify loop control var declaration

* Remove agrammatical comma

* Mention typedef in struct declaration
This commit is contained in:
krotera 2022-01-03 09:44:49 -07:00 committed by GitHub
parent 2abab47335
commit 6a0b4aee87
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -162,19 +162,25 @@ int main (int argc, char** argv)
int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes int my_int_array[20]; // This array occupies 4 * 20 = 80 bytes
// (assuming 4-byte words) // (assuming 4-byte words)
// You can initialize an array to 0 thusly: // You can initialize an array of twenty ints that all equal 0 thusly:
char my_array[20] = {0}; int my_array[20] = {0};
// where the "{0}" part is called an "array initializer". // where the "{0}" part is called an "array initializer".
// NOTE that you get away without explicitly declaring the size of the array, // All elements (if any) past the ones in the initializer are initialized to 0:
// IF you initialize the array on the same line. So, the following declaration int my_array[5] = {1, 2};
// is equivalent: // So my_array now has five elements, all but the first two of which are 0:
char my_array[] = {0}; // [1, 2, 0, 0, 0]
// BUT, then you have to evaluate the size of the array at run-time, like this: // NOTE that you get away without explicitly declaring the size
// of the array IF you initialize the array on the same line:
int my_array[] = {0};
// NOTE that, when not declaring the size, the size of the array is the number
// of elements in the initializer. With "{0}", my_array is now of size one: [0]
// To evaluate the size of the array at run-time, divide its byte size by the
// byte size of its element type:
size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]); size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]);
// WARNING If you adopt this approach, you should evaluate the size *before* // WARNING You should evaluate the size *before* you begin passing the array
// you begin passing the array to function (see later discussion), because // to functions (see later discussion) because arrays get "downgraded" to
// arrays get "downgraded" to raw pointers when they are passed to functions // raw pointers when they are passed to functions (so the statement above
// (so the statement above will produce the wrong result inside the function). // will produce the wrong result inside the function).
// Indexing an array is like other languages -- or, // Indexing an array is like other languages -- or,
// rather, other languages are like C // rather, other languages are like C
@ -572,7 +578,8 @@ the function are copies of the original arguments (except arrays). Anything you
do to the arguments in the function do not change the value of the original do to the arguments in the function do not change the value of the original
argument where the function was called. argument where the function was called.
Use pointers if you need to edit the original argument values. Use pointers if you need to edit the original argument values (arrays are always
passed in as pointers).
Example: in-place string reversal Example: in-place string reversal
*/ */
@ -583,9 +590,11 @@ void str_reverse(char *str_in)
char tmp; char tmp;
size_t ii = 0; size_t ii = 0;
size_t len = strlen(str_in); // `strlen()` is part of the c standard library size_t len = strlen(str_in); // `strlen()` is part of the c standard library
// NOTE: length returned by `strlen` DOESN'T include the // NOTE: length returned by `strlen` DOESN'T
// terminating NULL byte ('\0') // include the terminating NULL byte ('\0')
for (ii = 0; ii < len / 2; ii++) { // in C99 you can directly declare type of `ii` here // in C99 and newer versions, you can directly declare loop control variables
// in the loop's parentheses. e.g., `for (size_t ii = 0; ...`
for (ii = 0; ii < len / 2; ii++) {
tmp = str_in[ii]; tmp = str_in[ii];
str_in[ii] = str_in[len - ii - 1]; // ii-th char from end str_in[ii] = str_in[len - ii - 1]; // ii-th char from end
str_in[len - ii - 1] = tmp; str_in[len - ii - 1] = tmp;
@ -700,7 +709,7 @@ struct rectangle {
void function_1() void function_1()
{ {
struct rectangle my_rec; struct rectangle my_rec = { 1, 2 }; // Fields can be initialized immediately
// Access struct members with . // Access struct members with .
my_rec.width = 10; my_rec.width = 10;
@ -724,6 +733,16 @@ int area(rect r)
return r.width * r.height; return r.width * r.height;
} }
// Typedefs can also be defined right during struct definition
typedef struct {
int width;
int height;
} rect;
// Like before, doing this means one can type
rect r;
// instead of having to type
struct rectangle r;
// if you have large structs, you can pass them "by pointer" to avoid copying // if you have large structs, you can pass them "by pointer" to avoid copying
// the whole struct: // the whole struct:
int areaptr(const rect *r) int areaptr(const rect *r)
@ -876,7 +895,7 @@ enum traffic_light_state {GREEN, YELLOW, RED};
Node createLinkedList(int *vals, int len); Node createLinkedList(int *vals, int len);
/* Beyond the above elements, other definitions should be left to a C source */ /* Beyond the above elements, other definitions should be left to a C source */
/* file. Excessive includes or definitions should, also not be contained in */ /* file. Excessive includes or definitions should also not be contained in */
/* a header file but instead put into separate headers or a C file. */ /* a header file but instead put into separate headers or a C file. */
#endif /* End of the if precompiler directive. */ #endif /* End of the if precompiler directive. */