sizeof 和 strlen 的区别★★★★★
strlen 是头文件 中的函数,sizeof 是 C++ 中的运算符。strlen测量的是字符串的实际长度,以 \0 结束,而 sizeof 测量的是对象或者表达式类型占用的字节大小。
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char arr[10] = "hello";
cout << strlen(arr) << endl; // 5
cout << sizeof(arr) << endl; // 10
return 0;
}
若字符数组 arr 作为函数的形参,sizeof(arr) 中 arr 被当作字符指针来处理,而不是字符数组。这意味着在函数内部使用sizeof 会得到指向字符类型的指针的大小。
#include <iostream>
#include <cstring>
using namespace std;
void size_of(char arr[])
{
cout << sizeof(arr) << endl; // 输出指针的大小,在大多数平台上为8字节
cout << strlen(arr) << endl;
}
int main()
{
char arr[20] = "hello";
size_of(arr);
return 0;
}
8 (或平台相关的指针大小)
5
不同之处
- sizeof 在编译时计算长度,而strlen 在程序运行过程中计算长度 。
- sizeof的参数可以是类型,也可以是变量,且必须是完整类型;strlen 的参数必须是 char * 类型的变量。
- sizeof接受的参数可以是对象也可以是表达式,但是sizeof在编译时不会对接受的表达式进行计算;而 strlen是一个函数,如果接受表达式则会对表达式进行运算。
#include <iostream>
using namespace std;
int main(int argc, char * argv[])
{
int x = 4;
char *s = "12345678";
char *p = s;
sizeof(x++);
printf("%d\n", x); // 输出4,因为sizeof不是一个实际调用,所以x不会自增
strlen(p++);
printf("%s\n", p); // 输出"2345678",因为strlen执行前p已经自增了
return 0;
}
C99 中sizeof 则不计算这个不定长数组的空间。
#include <iostream>
#include <cstring>
using namespace std;
struct flexarray {
int val;
int array[]; /* Flexible array member; must be last element of struct */
};
int main()
{
printf("%ld\n", sizeof(struct flexarray)); // 4, 仅计算val成员的大小
}
sizeof(1==1)在 C 和 C++ 中的结果 ★★★☆☆
由于 C 语言没有
bool
类型,用整型表示布尔型。
#include<stdio.h>
void main(){
printf("%d\n", sizeof(1==1)); // 表达式 (1==1) 的结果类型是 int,占 4 字节
}
4
由于 C++ 语言有
bool
类型,布尔型占 1 个字节。
#include <iostream>
using namespace std;
int main() {
cout << sizeof(1==1) << endl; // 表达式 (1==1) 的结果类型是 bool,占 1 字节
return 0;
}
1
C 和 C++ 中 static 的作用★★★★★
在 C 语言中:
- 全局静态变量:
- 普通全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,普通全局变量在各个源文件中都是有效的。
- 静态全局变量则限制了其作用域,即只在定义该变量的源文件内有效,在同一源程序的其他源文件中不能使用它。静态全局变量存储在静态数据存储区,生命周期贯穿于整个程序运行期间。
- 局部静态变量:局部静态变量只能被初始化一次,作用域仅限于函数内部。实际上,局部静态变量也存储在静态存储区,因此它的生命周期贯穿于整个程序运行期间。
- 静态函数:静态函数仅可在定义该函数的文件内部调用。
// a.cpp
#include <iostream>
using namespace std;
int g_var = 0; // 全局变量
static char *gs_var; // 静态全局变量
int main() {
int var; // 局部变量
static int s_var = 0; // 静态局部变量
return 0;
}
// b.cpp
#include <iostream>
using namespace std;
extern int g_var; // 访问全局变量
// extern static char *gs_var; 无法访问静态全局变量
static int test() {
return 0;
}
在 C++ 中,除了上述用途外:
- 静态成员变量:静态成员变量是在类内声明,在类外定义和初始化。静态成员变量相当于类域中的全局变量,被类的所有对象所共享,包括派生类的对象。
#include <iostream>
using namespace std;
class GfG {
public:
static int i;
GfG() {
};
};
int GfG::i = 1; // 初始化
int main() {
GfG obj1;
GfG obj2;
obj1.i = 2; // 修改
obj2.i = 3; // 修改
cout << obj1.i << " " << obj2.i; // 输出 3 3
return 0;
}
- 静态成员函数:不能调用非静态成员变量或非静态成员函数,因为没有
this
指针。
#include<iostream>
using namespace std;
class GfG {
public:
static void printMsg() {
cout << "Welcome to GfG!";
}
};
int main() {
GfG::printMsg();
return 0;
}
- 静态对象:静态对象的生存周期为整个程序的生命周期。
#include<iostream>
using namespace std;
class GfG1 {
int i;
public:
GfG1() {
i = 0;
cout << "GFG1 Inside Constructor\n";
}
~GfG1() {
cout << "GFG1 Inside Destructor\n";
}
};
class GfG2 {
int i;
public:
GfG2() {
i = 0;
cout << "GfG2 Inside Constructor\n";
}
~GfG2() {
cout << "GfG2 Inside Destructor\n";
}
};
int main() {
int x = 0;
if (x == 0) {
GfG1 obj1;
static GfG2 obj2;
}
cout << "End of main\n";
}
GFG1 Inside Constructor
GfG2 Inside Constructor
GFG1 Inside Destructor
End of main
GfG2 Inside Destructor
main
函数执行完成时,静态对象obj2
的生命周期仍然存在。
const 作用及用法★★★★★
const 变量:相较于宏常量,可进行类型检查,节省内存空间,提高了效率。被定义为 const的变量是不可修改的。
#include <iostream>