关于int main(int argc, char* argv[])中为什么必须要有argc
学C/C++的时,最熟悉的接口参数大概就是int main(int argc, char* argv[])
了,一直很好奇sizeof(argv)/sizeof(argv[0])
就知道数组长度了,为啥多出来各argc。最近用该代码求传入函数的数组长度,编译器报warning char** argv了,并且求出来的值始终为1。顺势追了下原因,发现sizeof的值时编译时确定的。外部传参的数组,编译器无法正常推到数组的大小,也就出现了前面的尴尬的情况了。
引用内容
(以下内容来自chartgtp)
在C语言中,编译时确定的函数主要指的是那些不依赖于程序运行时输入或外部状态的函数,以及那些由编译器直接提供或内联展开的内置函数和宏。以下是一些常见的编译时确定的函数或特性:
-
内置函数(Built-in Functions):
- 这些函数是编译器直接提供的,通常用于执行一些底层操作,如内存管理、类型转换等。它们的实现和行为可能因编译器而异,但通常都有很好的性能。
- 示例:
__builtin_expect
(用于优化分支预测,GCC特有)、__builtin_popcount
(计算一个整数中设置为1的位的数量,GCC和Clang支持)等。
-
宏(Macros):
- 宏是在预处理阶段被展开的代码片段,它们不是真正的函数,但可以在编译时根据定义进行文本替换。
- 示例:
#define MAX(a, b) ((a) > (b) ? (a) : (b))
,这是一个计算两个数中较大值的宏。
-
常量表达式(Constant Expressions):
- 常量表达式是在编译时就能确定其值的表达式,它们可以包含运算符、常量、枚举值等。
- 在C99及以后的版本中,
_Static_assert
可以用来在编译时进行断言,这可以看作是一种特殊的“函数”,用于在编译时检查常量表达式是否为真。
-
类型大小和对齐(Type Size and Alignment):
- 虽然这不是传统意义上的函数,但类型的大小和对齐通常是在编译时确定的。C语言提供了
sizeof
和_Alignof
(C11引入)运算符来获取这些信息。
- 虽然这不是传统意义上的函数,但类型的大小和对齐通常是在编译时确定的。C语言提供了
-
编译时计算(Compile-Time Computation):
- C++11引入了
constexpr
关键字,允许在编译时计算表达式的值。虽然这是C++的特性,但C语言可以通过宏和模板元编程(在C++中更常见)来实现类似的功能。不过,C语言本身没有直接支持编译时计算的内置机制。
- C++11引入了
-
静态断言(Static Assertions):
- 如前所述,C99的
_Static_assert
和C++11的static_assert
都是编译时断言的机制,用于在编译时检查某些条件是否为真。虽然_Static_assert
是C99标准的一部分,但并非所有C编译器都支持它。
- 如前所述,C99的
-
模板元编程(Template Metaprogramming,仅限C++):
- 虽然这是C++的特性,但值得一提的是,模板元编程允许在编译时进行复杂的计算和类型推导。然而,C语言没有模板,因此这一特性不适用于C。