sizeof和strlen区别,static和const的使用

做一些笔试题目时,经常会遇到sizeof和strlen区别,static和const的使用等,一直搞不清,最近看看书,稍微懂了一点。

一、总结sizeof和strlen区别

//求字符串长度用strlen(),求内存空间大小用sizeof

关于sizeof

1.sizeof(...)是运算符,结果类型是size_t,在头文件中typedef为unsigned int类型
   sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。
2.其值在编译时即计算好了,由于在编译时计算,因此sizeof不能用来返回动态分配的内存空间的大小。
3.参数可以是数组、指针、类型、对象、函数等
4.它的功能是:获得保证能容纳实现所建立的最大对象的字节大小。
实际上,用sizeof来返回类型以及静态分配的对象、结构或数组所占的空间,返回值跟对象、结构、数组所存储的内容没有关系。

类型——该类型所占的空间大小;

int 4;short 2;long 4;float 4;double 8;char 1;long double 12;
char a[10];sizeof(a)//结果为10
int a[10];sizeof(a)//结果为40


数组——编译时分配的数组空间大小;

char str[20]="0123456789";
int a=strlen(str); //a=10;
int b=sizeof(str); //而b=20;分配的数组str[20]所占的内存空间的大小,不受里面存储的内容改变。  
//sizeof返回定义的数组时,编译器为其分配的数组空间大小,不关心里面存了多少数据。
//strlen只关心存储的数据内容,不关心空间的大小和类型。


指针——存储该指针所用的空间大小(存储该指针的地址的长度,是长整型,应该为4);

char *parr = new char[10];
int len_one = strlen(parr);//取决于parr里面存了什么,从parr[0]开始直到第一个NULL结束,字符串长度
int len_two = sizeof(parr);//sizeof认为parr是个字符指针,因此返回的是该指针所占的空间,4
int len_three = sizeof(*parr);//*parr所代表的是parr所指的地址空间存放的字符,所以长度为1
//指针和数组结果是不一样的


对象——对象的实际占用空间大小;(结构体)

//因为对齐问题使结构体的sizeof变得比较复杂
总体上遵循两个原则:
(1)整体空间是占用空间最大的成员(的类型)所占字节数的整倍数
(2)数据对齐原则----内存按结构成员的先后顺序排列,当排到该成员变量时,其前面已摆放的空间大小必须是该成员类型大小的整倍数,如果不够则补齐

函数——函数的返回类型所占的空间大小。函数的返回类型不能是void。

short f();
printf("%d\n", sizeof(f())); //输出的结果是sizeof(short),即2。


关于strlen()

1.strlen(...)是函数
2.要在运行时才能计算。
3.参数必须是字符型指针(char*),且必须是以'\0'结尾的
当数组名作为参数传入时,实际上数组就退化成指针了。只能接受char型指针

int ac[10];
cout<<strlen(ac)<<endl; //ac相当于一个指针,但是strlen只能接受char*类型,所以编译时出错!!!
4.它的功能是:返回字符串的长度。
从代表该字符串的第一个地址开始遍历,直到遇到结束符NULL。
返回的长度大小不包括NULL。
没有给它赋初值,这个结果是不定的,它会从字符串首地址一直找下去,直到遇到'\0'停止

char a[10];cout<<strlen(a)<<endl;//结果不定
char a[10]={'\0'};cout<<strlen(a)<<endl;//结果为0
char a[10]="Jun";cout<<strlen(a)<<endl;//结果为3


二、static用法总结

1.用static声明局部变量
与auto相比,static局部变量有三点不同
(1)存储空间分配不同
auto类型分配在栈上,属于动态存储类别,占动态存储空间,函数调用结束后自动释放;
static分配在静态存储区,在程序整个运行期间都不释放。

(2)static局部变量只赋初值一次,以后每次调用时不赋新值只是保留上次函数调用结束时的值;

对auto变量赋值,每调用一次函数重新给一次初值。

(3)对静态局部变量,默认值为0或空字符;对自动变量,默认值是不确定的

#include <stdio.h>
void main()
{
	int f(int);
	int a=2,i;
	for(i=0;i<3;i++)
		printf("%d",f(a));
}
int f(int a)
{
	auto int b=0;//auto可省略
	static int c=3;
	b=b+1;c=c+1;
	return (a+b+c);
}
//i=0:a+b+c=2+1+4
//i=1:a+b+c=2+1+5
//i=2:a+b+c=2+1+6

2.用static声明全局变量
该全局变量只能用于本文件,可独立的在不同的文件中使用相同的全局变量而互不相干,可降低各文件之间的耦合性
static/auto两种形式的全局变量(外部变量)都是静态存储方式,都是编译时分配存储空间,但作用域不同(加static使得该全局变量只限于本文件使用)
使用静态外部变量,有利于隔离错误,有利于模块化程序设计。

如何声明所有cpp可共享的全局变量,在头文件里声明为extern:

extern int g_value;     // 注意,不要初始化值!

int g_value = 0;        //然后在其中任何一个包含该头文件的cpp中初始化(一次)就好:
                      // 初始化一样不要extern修饰,因为extern也是声明性关键字;
                    // 然后所有包含该头文件的cpp文件都可以用g_value这个名字访问相同的一个变量;


3.类的静态数据成员

class Type
{
	private:
		int a;
		static int h;
	public:
		void print();
		Type(int x=0);
		static int i;
};
void Type::print()
{
	cout<<"a="<<++a;
	cout<<"  h="<<++h<<endl;
}
Type::Type(int x)
{
	a=x;
}
int Type::h=0;//静态数据成员赋初值在类体外进行,前面不再加static
void main()
{	//静态数据成员在编译时创建并初始化,故在该类的任何对象被创建前已经存在
    //所以公有的静态数据成员可在对象定义前被访问——类名::公有静态成员变量名
	Type::i=9;
	Type t1,t2,t3;
	t1.print();//a=1  h=1
	t2.print();//a=1  h=2
	t3.print();//a=1  h=3
    //a变量为每个对象各自拥有,h为三个对象共有
}
(1)静态数据成员的初始化必须在类外进行,默认值为0;(前面不加static)
(2)可在同一个类的不同对象之间提供数据共享。
(3)对于公有的静态数据成员可在对象定义前被访问;在对象定义后,还可对象名.变量名(t1.i)
私有的静态数据成员不能被类的外部函数访问,也不能用对象进行访问
(private 只允许被该类的成员函数即友元访问)

4.静态成员函数
(1)静态成员函数只能访问静态数据成员
(2)可通过对象或类名进行调用
类名::静态成员函数名(实参表)---所以在建立任何对象之前可以用静态成员函数处理静态数据成员
对象名.静态成员函数名(实参表)
(3)初始化必须在类外进行
(4)静态成员函数没有this指针,而非静态成员函数有一个纸箱当前对象的this指针

#include <iostream.h>
class Type
{
	private:
		int a;
		static int s;
	public:
		static void print();
		Type();
};
void Type::print()
{
	cout<<"s="<<s<<endl;//静态成员函数只能访问静态数据成员
}
Type::Type()
{
	a=0;
	s++;
	cout<<"a="<<++a<<endl;
}
int Type::s //静态数据成员默认初值为0
void main()
{
	Type::print();//在未定义对象前,可用类名来调用静态成员函数
	Type t1,t2;
	t1.print();//也可用对象来调用静态成员函数
	t2.print();
}
//结果:s=0
//      a=1
//      a=1
//      s=2
//      s=2

还有const待整理。。。。






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值