Timeline
Timeline
2025-07-19
init
This article introduces the basics of the C language, focusing on the byte sizes and value ranges of common integer types, and points out that the differences of the long type across platforms are determined by data models (such as LP64, LLP64). The article also covers the ASCII table, library functions, and input/output operations, detailing the difference in handling %c and whitespace characters in the scanf function, as well as the usage and return value of the getline function. In addition, the format specifiers of the printf function are listed and explained.
Data Type
Common integer ranges
| Data Type | Byte count | Decimal range | Scientific notation (approx.) |
|---|---|---|---|
char | 1 | -128 ~ 127 | -1.28×10² ~ 1.27×10² |
unsigned char | 1 | 0 ~ 255 | 0 ~ 2.55×10² |
short | 2 | -32,768 ~ 32,767 | -3.28×10⁴ ~ 3.27×10⁴ |
unsigned short | 2 | 0 ~ 65,535 | 0 ~ 6.55×10⁴ |
int | 4 | -2,147,483,648 ~ 2,147,483,647 | -2.15×10⁹ ~ 2.15×10⁹ |
unsigned int | 4 | 0 ~ 4,294,967,295 | 0 ~ 4.29×10⁹ |
long(Linux 64-bit) | 8 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | ±9.22×10¹⁸ |
unsigned long | 8 | 0 ~ 18,446,744,073,709,551,615 | 0 ~ 1.84×10¹⁹ |
long long | 8 | -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 | ±9.22×10¹⁸ |
unsigned long long | 8 | 0 ~ 18,446,744,073,709,551,615 | 0 ~ 1.84×10¹⁹ |
- The byte size of long may differ across platforms; for example, it is usually 8 bytes on 64-bit Linux systems.
- The actual size and range are determined by the compiler and the target platform’s data model, such as LP64 (Linux) / LLP64 (Windows).
ASCII table


Library functions
Input/Output
scanf
Difference between %c and whitespace
1 | scanf("%c", &ch); |
It reads one character as-is, including spaces, tabs, and newline \n.
1 | scanf(" %c", &ch); |
Because there is a space in the format string, scanf first skips all whitespace characters (space, \t, \n), then reads a valid character.
1 | while(scanf("%d",&x)!=EOF) |
Summary:
- scanf returns EOF if an input failure occurs (such as end-of-file) before any conversion is performed; if a matching failure occurs after some conversions, it returns the number of items successfully matched (possibly 0).
- Numeric format specifiers such as %d, %f: whitespace is automatically skipped by default.
- %c: does not skip whitespace; you need " %c" to ignore spaces and newlines.
- Principle: In scanf’s format string, a whitespace character (space, \n, \t) means “match any amount of whitespace”.
getline
The return value of getline() is the number of characters read (including the newline, excluding the terminator\0); on failure it returns -1. getline is a POSIX function, not a standard C function.
| Parameters | meaning |
|---|---|
char **lineptr | Points to achar*Pointer (used to store the read string; the function automatically allocates/expands memory internally) |
size_t *n | Pointer to the buffer size (initially 0); the function dynamically allocates/expands memory as needed |
FILE *stream | Input stream, e.g.,stdin, file handles, etc. |
Return value
- Success: returns the number of characters read (including the newline character
\n, but not including the terminator\0) - Failure: returns
-1, and setserrno
Using getline requires including<stdio.h>and<stdlib.h>, but more importantly, on some non-POSIX platforms (such as Windows or older standard C compilers), getline() is not available.
Comprehensive solution (applicable to Linux/GCC environment):
Make sure to include the following header files:
123456789101112 | // Optional: enable GNU extensions// Use strcspn// defines the ssize_t type (signed size_t), commonly used as the return value of functions such as read, write, getline, readlink// is part of the POSIX standard, not part of the C standard library. On GNU/Linux platforms, when using POSIX APIs, this type can be obtained by including <unistd.h> or <sys/types.h> |
Example:
1234567891011121314151617181920212223242526272829303132 | int main() { char *line = NULL; size_t len = 0; ssize_t nread; printf("请输入一行文本(按 Ctrl+D 或 Ctrl+Z + Enter 结束):\n"); errno = 0; // Clear to zero before use nread = getline(&line, &len, stdin); if (nread == -1) { if (feof(stdin)) { printf("输入结束(EOF)\n"); } else { // Print the value of errno and the corresponding information fprintf(stderr, "getline 失败,errno = %d: %s\n", errno, strerror(errno)); } free(line); return 1; } printf("读取了 %zd 字符:%s", nread, line); free(line); return 0;} |
printf
Detailed explanation of the printf function:
Below is the declaration of the printf() function.
1 | int printf(const char *format, ...) |
Parameters
- format – This is a string that contains the text to be written to the standard output stdout. It can contain embedded format tags, which can be replaced by the values specified in the subsequent additional arguments and formatted as required.
- The format tag attributes are
1 | %[flags][width][.precision][length]specifier |
| Format character | Meaning |
|---|---|
| a, A | Output floating-point numbers in hexadecimal form (new in C99). Example printf(“pi=%a\n”, 3.14); output pi=0x1.91eb86p+1。 |
| d | Output signed integers in decimal form (positive numbers do not output the sign) |
| o | Outputs an unsigned integer in octal form (without outputting the prefix 0) |
| x,X | Outputs an unsigned integer in hexadecimal form (without outputting the prefix 0x) |
| u | Outputs an unsigned integer in decimal form |
| f | Outputs single- or double-precision real numbers in decimal notation |
| e,E | Outputs single- or double-precision real numbers in exponential notation |
| g,G | Automatically selects the more compact of %f or %e to output single- or double-precision real numbers |
| c | Outputs a single character |
| s | Outputs a string |
| p | Outputs a pointer address |
| lu | Length modifier for %u, outputs unsigned long |
| llu | Length modifier for %u, outputs unsigned long long |
| flags | Description |
|---|---|
| - | Left-aligns the output within the given field width; right-alignment is the default (see width sub-specifier). |
| + | Forces a plus or minus sign (+ or -) to be shown before the result, i.e., positive numbers are preceded by a + sign. By default, only negative numbers are preceded by a - sign. |
| space | If no sign is written, a space is inserted before the value. |
| # | When used with o, x, or X specifiers, a non-zero value is preceded by 0, 0x, or 0X respectively. When used with e, E, and f, it forces the output to contain a decimal point, even if no digits follow. By default, if no digits follow, the decimal point is not shown. When used with g or G, the result is the same as with e or E, but trailing zeros are not removed. |
| 0 | Places zeros (0) to the left of the number instead of spaces when padding is specified (see width sub-specifier). |
| width | Description |
|---|---|
| (number) | Minimum number of characters to be output. If the output value is shorter than this number, the result is padded with spaces. If the output value is longer than this number, the result is not truncated. |
| * | The width is not specified in the format string, but is given as an additional integer value argument placed before the argument to be formatted. |
| .precision | Description |
|---|---|
| .number | For integer specifiers (d, i, o, u, x, X): precision specifies the minimum number of digits to be written. If the value written is shorter than this number, the result is padded with leading zeros. If the value written is longer than this number, the result is not truncated. When precision is 0 and the value is 0, no characters are written; otherwise, it is output normally. For e, E, and f specifiers: the number of digits to be output after the decimal point. For g and G specifiers: the maximum number of significant digits to be output. For s: the maximum number of characters to be output. By default, all characters are output until the terminating null character is encountered. For c type: no effect. When no precision is specified, the default is 1. If specified without an explicit value, it is assumed to be 0. |
| .* | The precision is not specified in the format string, but is given as an additional integer value argument placed before the argument to be formatted. |
| length | Description |
|---|---|
| h | The argument is interpreted as a short int or unsigned short int (only applies to integer specifiers: i, d, o, u, x, and X). |
| l | The argument is interpreted as a long int or unsigned long int, applicable to integer specifiers (i, d, o, u, x, and X) and specifiers c (denoting a wide character) and s (denoting a wide character string). |
| L | The argument is interpreted as a long double (only applies to floating-point specifiers: e, E, f, g, and G). |
Additional arguments
Depending on the format string, the function may require a series of additional arguments, each containing a value to be inserted, replacing each % tag specified in the format parameter. The number of arguments should be the same as the number of % tags.
Return value
If successful, returns the total number of characters written; otherwise, returns a negative number.
math.h
Error status macro definitions
Before<math.h>Among them, there are some macros used to represent the error status of mathematical functions:
| Macro | Description |
|---|---|
HUGE_VAL | The value returned when the function result overflows (positive infinity). This macro represents a very large double-precision floating-point number, usually used as the return value for certain mathematical functions when the result exceeds the representable range. When a function’s result is too large to be represented as a normal floating-point number (i.e., an overflow occurs), errno is set to ERANGE (range error), and HUGE_VAL or its negative value (for negative infinity) is returned. |
HUGE_VALF | The value returned when the function result overflows (positive infinity, float type) |
HUGE_VALL | The value returned when the function result overflows (positive infinity, long double) |
INFINITY | Positive infinity |
NAN | Not-A-Number (NaN) |
FP_INFINITE | Represents infinity |
FP_NAN | Represents a non-numeric value |
FP_NORMAL | Represents a normal floating-point number |
FP_SUBNORMAL | Represents a subnormal number |
FP_ZERO | Represents zero |
Library functions
The following lists the functions defined in the header file math.h:
| function | Description |
|---|---|
| double acos(double x) | Returns the arccosine of x in radians. |
| double asin(double x) | Returns the arcsine of x in radians. |
| double atan(double x) | Returns the arctangent of x in radians. |
| double atan2(double y, double x) | Returns the arctangent of y/x in radians. The signs of the values of y and x determine the correct quadrant. |
| double cos(double x) | Returns the cosine of the radian angle x. |
| double cosh(double x) | Returns the hyperbolic cosine of x. |
| double sin(double x) | Returns the sine of x, where x is in radians. |
| double sinh(double x) | Returns the hyperbolic sine of x. |
| double tanh(double x) | Returns the hyperbolic tangent of x. |
| double exp(double x) | Returns the value of e raised to the power of x. |
| double frexp(double x, int *exponent) | Breaks the floating-point number x into a mantissa and an exponent. The return value is the mantissa, and the exponent is stored in exponent. The resulting value is x = mantissa * 2 ^ exponent. |
| double ldexp(double x, int exponent) | Returns x multiplied by 2 raised to the power of exponent. |
| double log(double x) | Returns the natural logarithm of x (logarithm to base e). |
| double log10(double x) | Returns the common logarithm of x (logarithm to base 10). |
| double modf(double x, double *integer) | Returns the fractional part (the part after the decimal point), and sets integer to the integer part. |
| double pow(double x, double y) | Returns x raised to the power of y. |
| double sqrt(double x) | Returns the square root of x. |
| double ceil(double x) | Returns the smallest integer value greater than or equal to x. |
| double fabs(double x) | Returns the absolute value of x. |
| double floor(double x) | Returns the largest integer value less than or equal to x. |
| double fmod(double x, double y) | Returns the remainder of x divided by y. |
| function name | Function | Rounding direction |
|---|---|---|
round() | Round half up | To nearest integer |
floor() | Round down (the largest integer not greater than the original number) | Toward -∞ |
ceil() | Round up (the smallest integer not less than the original number) | Toward +∞ |
trunc() | Remove the fractional part (truncate) | Toward 0 |
Common mathematical constants
The following are<math.h>Some common mathematical constants defined in:
| Constant | Value | Description |
|---|---|---|
M_PI | 3.14159265358979323846 | Pi (π) |
M_E | 2.71828182845904523536 | The base of the natural logarithm, e |
M_LOG2E | 1.44269504088896340736 | log2(e) |
M_LOG10E | 0.43429448190325182765 | log10(e) |
M_LN2 | 0.69314718055994530942 | ln(2) |
M_LN10 | 2.30258509299404568402 | ln(10) |
M_PI_2 | 1.57079632679489661923 | π/2 |
M_PI_4 | 0.78539816339744830962 | π/4 |
M_1_PI | 0.31830988618379067154 | 1/π |
M_2_PI | 0.63661977236758134308 | 2/π |
M_2_SQRTPI | 1.12837916709551257390 | 2/√π |
M_SQRT2 | 1.41421356237309504880 | √2 |
M_SQRT1_2 | 0.70710678118654752440 | 1/√2 |
string.h
strdup
12 | char *strdup(const char *s); |
Equivalent to strcpy, but automatically allocates memory
strtok
1 | char *strtok(char *str, const char *delim) |
Parameters
str: The string to be split. On the first call, pass the string to be split; on subsequent calls, pass NULL to continue splitting the same string.
delim: The delimiter string. strtok() splits str based on any character in this string.
Return value
Returns a pointer to the next token. If there are no more tokens, returns NULL.
123456789 | /* Get the first substring */token = strtok(str, s);/* Continue getting the remaining substrings */while( token != NULL ) { printf( "%s\n", token ); token = strtok(NULL, s);} |
Notes.
- Modifies the original string: strtok() modifies the passed string, replacing delimiters with \0 (null character). Therefore, the original string is corrupted.
- Non-reentrant: strtok() uses a static buffer to save state, so it is not thread-safe. If used in a multi-threaded environment, consider using strtok_r() (the reentrant version).
- Consecutive delimiters: If there are consecutive delimiters in the string, strtok() ignores them and returns the next valid token.
Reentrant version: strtok_r()
strtok_r() is the reentrant version of strtok(), which allows you to use it safely in multi-threaded environments. Its prototype is as follows:
char *strtok_r(char *str, const char *delim, char *saveptr);
saveptr: A pointer to char used to save the splitting state.
Example:
12345678910111213141516171819 | int main() { char str[] = "This is a sample string"; char *token; char *saveptr; // Call strtok_r the first time, passing the string to be split token = strtok_r(str, " ", &saveptr); // Continue calling strtok_r until it returns NULL while (token != NULL) { printf("%s\n", token); token = strtok_r(NULL, " ", &saveptr); } return 0;} |
strcspn
strcspn is a string handling function in the C standard library <string.h> that finds the position of the first character in the target string that matches any character in the specified character set.
- Function prototype
123 | size_t strcspn(const char *s, const char *reject); |
- Description
It returns the position (index) of the first character in string s that is also in reject. If s contains none of the characters in reject, it returns strlen(s).
💡 “cspn” stands for complement span, meaning: returns the length of the longest prefix consisting of characters not in reject.
- example
12345678910 | int main() { char str[] = "hello, world!"; size_t pos = strcspn(str, ",!"); printf("第一个 ',' 或 '!' 的位置是:%zu\n", pos); // Output: 5 return 0;} |
strspn
strspn is a function in the C standard library <string.h> that counts how many characters at the beginning of a string all belong to the specified character set.
The function name strspn is an abbreviation of ‘string span’, meaning ‘the span of a string’ or ‘the length of a contiguous prefix of a string that satisfies a condition’.
Compare with strcspn
| function name | Meaning description |
|---|---|
strspn | span of characters in accept |
strcspn | span of characters not in reject |
In other words:
strspn(s, accept): starting from the beginning, count how many characters are in accept.
strcspn(s, reject): starting from the beginning, count how many characters are not in reject.
Function prototype
123 | #include <string.h>size_t strspn(const char *s, const char *accept); |
- Description
strspn(s, accept) returns the number of consecutive characters at the beginning of string s that all appear in accept.
- It does not skip characters, nor does it examine the entire string;
- As soon as it encounters a character not in accept, it stops counting;
- The return value is of type size_t (that is, an unsigned integer), representing the length of the match.
- example
1234567891011 | int main() { const char *s = "abcabc123"; const char *accept = "abc"; size_t len = strspn(s, accept); printf("前缀长度为:%zu\n", len); // Output: 6 return 0;} |
✨ Analysis:
String s = “abcabc123”
Starting with “a”, “b”, “c”, exactly 6 consecutive characters are in “abc”.
The 7th character is ‘1’, which is not in “abc” → counting stops.
So it returns 6.Application scenarios
📌 Check whether the beginning of a string contains only certain characters
123 | if (strspn(s, "0123456789") == strlen(s)) { printf("s 是纯数字\n");} |
📌 Skip all valid characters in the prefix
123 | char *s = " \t\n hello";s += strspn(s, " \t\n"); // Skip all whitespace charactersprintf("剩下:%s\n", s); // Output: "hello" |
Error handling
errno
You can, when a standard library function call fails, readerrnothe value of … to determine the failure’sspecific reason, and then useperror()orstrerror(errno)to get the corresponding error description.
Example: Usageerrno
12345678910111213141516171819202122 | int main() { FILE *fp = fopen("no-such-file.txt", "r"); if (fp == NULL) { // Print error number printf("errno = %d\n", errno); fprintf(stderr, "error code = %d\n", errno); // Print error description perror("fopen 失败"); // Recommended: automatically add prefix // Or manually print error message printf("错误信息: %s\n", strerror(errno)); } return 0;} |
Output:
1234 | errno = 2error code = 2fopen 失败: No such file or directory错误信息: No such file or directory |
