本来是要说int main(int argc,char*argv[])的,可是后来却不知不觉的深挖了很多问题。所以这是一篇没有中心的随笔,我就把自己挖开问题的一步步思路记录了下来。
首先一个小程序测试走起来:
#include <stdio.h>
#include <stdlib.h>
int main(int argc,char*argv[])
{
int num = (--argc && (*++argv)[0]=='-')? atoi(argv[0]+1):6;
printf("%d\n",num);
system("pause");
}
这个代码很简单,生成一个test.exe文件,我的这个文件是在D:\test\bin\Debug路径下保存的
接下来运行结果如图所示:
运行结果为:31
说明程序测试 success
接下来解释参数:argc 和 argv
argc代表的是有几个参数
argv是一个指向字符的指针数组,该数组中第一个指针指向字符串 “test.exe”
第二个指针指向字符串 “-31”
(*++argv)[0] : argv代表第一个元素的地址,第一个元素是指向“test.exe”的指针,那么argv所能代表的就是指针的地址,也就是指向指针的指针, ++argv是指向第二个元素的指针,因为argv指向的是指针,所以++argv在内存中跳过的是4个字节。有测试程序为证。*++argv得到的是第二个元素,第二个元素是指向“-31”的指针,而指针后面直接接[0]的之前没见过,书上是站在数组的角度说过:数组名代表数组的第一个元素的首地址,a[i] == *(a+i) ; 但是没站在指针的角度去说,那么我真是死板,其实反之亦然。
(*++argv)所得的结果就是指向第二个字符串的指针,那么指针后面[],也就是argv[1][0] = *(argv[1] + 0),对过去看,argv[0]就是“抽象的数组名”
另外:经过(*++argv)后.argv就跑到第二个指针的地址,那么argv[0]就相当于*(argv+0)得到第二个指针,那么第二个指针指向“-31”的首地址,在加个1,就指向字符‘3’的地址,所以 atoi(argv[0]+1)得到的是31
总结:破除障眼法直接看底层。凡是用[]的都将之转换成*
例如:
char* p1 = "ksljf";
char* p2 = "65416";
char* array[] = {p1,p2};
array[0] + 1: 常规思维:array[0]是 指针 p1 ,p1所指向的是字符,所以array[0]+1 是指向字符's'
破障眼法思维:array[0]是 *(array+0) array第一个元素的地址,也就是指向第一个元素的指针,而第一个元素是指针
所以array是指向指针的指针,array+0,因为是0所以指针不跳动,*(array+0)就得到了第一个元素——也就是指向“ksljf”的指针,那么再次加1就得到了指向字符‘s’的指针。
所以上述代码也可以改成:
int num = (--argc && (*++argv)[0]=='-')? atoi(*argv+1):6;