在学习 C 语言的时候,常常看到 int main(int argc, char *argv[]),而大部分国内教科书里并不会介绍括号里的两个参数。这两个参数的含义并不复杂:
int argc:参数个数char *argv[]:参数数组
由于我个人此前忘记其原理解释,一度只知道怎么用,所以特此记录为什么 char *argv[] 表示字符串。
我们知道 C 语言里严格意义上没有字符串,只有字符,那么类似字符串的功能是由字符数组替代的,其中又有几种等价的语法表示和读取字符数组:
char c[] = "hello";char c[] = {'h', 'e', 'l', 'l', 'o', '\0'};char *c = "hello";
这三种方法都可以让我们通过下标访问字符。
因此,我们考虑:char *argv[] = {"hello", "world"};
首先,argv 是一个数组,而数组元素的类型是 char *。换句话说,数组中每个位置存放的都是一个指向字符的指针。
具体来说:
argv[0] // 指向字符串 "hello" 的首字符 'h'
argv[1] // 指向字符串 "world" 的首字符 'w'
Info
argv[0] 并不直接保存整个 "hello",它保存的是字符串首字符所在的地址。由于字符串中的字符连续存储,并且以 '\0' 结尾,因此只要知道首字符的位置,就可以依次找到后面的字符。
例如:
argv[0][0] // 'h'
argv[0][1] // 'e'
argv[0][2] // 'l'
argv[0][3] // 'l'
argv[0][4] // 'o'
argv[0][5] // '\0'
这里的第一层下标用于选取字符串,第二层下标用于选取字符串中的字符。
实际上:argv[0][1] *(argv[0] + 1)
argv[0] 指向 'h',argv[0] + 1 指向下一个字符 'e',再通过 * 取得对应的字符。
因此,char *argv[] 能够表示一组字符串,并不是因为数组直接存储了所有字符串,而是因为它存储了一组字符指针,每个指针分别指向一个字符串的首字符。
| 表达式 | 含义 | 类型 |
|---|---|---|
argv | 字符指针数组 | char *[2] |
argv[0] | 指向 "hello" 首字符的指针 | char * |
argv[1] | 指向 "world" 首字符的指针 | char * |
argv[0][0] | 字符 'h' | char |
&argv[0] | 数组第一个元素的地址 | char ** |