strlen()与sizeof()区别、计算及字节对齐、位域

**

strlen()与sizeof()区别、求法及字节对齐问题

**

  • 1.c++中,字符串与字符串类区别
  • 2.c++中,strlen()与sizeof()区别
  • 3.字符串的长度与字节大小的计算
  • 4.字符串类的长度与字节大小计算
  • 5.常见字节对齐的计算

c++中,字符串与字符串类区别

1.头文件不同,字符串引用 #include

c++中,strlen()与sizeof()区别

0.strlen()在一般情况下都以‘\0’结束.
1.strlen()是函数;sizeof()是运算符.
2.strlen()只能作为char*的参数,且必须以‘\0’结束;sizeof()还可以把函数作为参数.
3.数组作为strlen()的参数时退化为指针;数组作为sizeof()参数时.
4.strlen(),在程序运行时,得出结果值;sizeof()在程序编译时,得出结果值.
5.strlen()求得是字符串数组的实际长度;sizeof()求的得是分配数组空间的大小.

Code
//字符串类
#include<string>
#include<iostream>
using namespace std;
void main()
{
    string str = "12345";
    string str1;
    //strcpy(str1,str);
    str1 = str;
    str1 = str1+str;
    //1234512345
    cout<<"str1 = "<<str1<<endl;
    //10
    cout<<"str1 size = "<<str1.size()<<endl;
    //10
    cout<<"str1 length = "<<str1.length()<<endl;
    //字符串类的sizeof()结果由编译器决定
    cout<<"str1 size of="<<sizeof(str1)<<endl;
}
//字符串
#include<iostream>
using namespace std;
void main()
{
    char str[] = "12345";
    char str1[]="123";
    char str2[]="";
    //char str2[] = str1;
    strcpy(str2,str1);

    //123
    cout<<"str2 = "<<str2<<endl;
    //12312345
    cout<<"str1="<<strcat(str1,str)<<endl;
    //8
    cout<<"str1 strlen()="<<strlen(str1)<<endl;
    //不是9,因为在str1定义时,sizeof(str1)为4.
    cout<<sizeof(str1)<<endl;
}
#include<iostream>
using namespace std;
int fun()
{
    int a= 0;
    return a;
}
void main()
{
    char ar[20]={1,2,3,4,5,6,9,9};
    //8
    cout<<"ar strlen="<<strlen(ar)<<endl;
    //20
    cout<<"ar sizeof()="<<sizeof(ar)<<endl;
    //4
    cout<<"ar sizeof()="<<sizeof(fun())<<endl;

}

字符串的长度与字节大小的计算

1.不带‘\0’的字符串计算.

#include<iostream>
using namespace std;
void main()
{
    char str[]="12345";
    //5
    cout<<strlen(str)<<endl;
    //6
    cout<<sizeof(str)<<endl;
}

2.带‘\0’且后面先跟字母时,把’\0’当做一个字符.

#include<iostream>
using namespace std;
void main()
{
    char str[]="12345\0asdf";
    //5
    cout<<strlen(str)<<endl;
    //11
    cout<<sizeof(str)<<endl;
}

3.带’\0‘且后面是数字,将两个数字转译成一个字符.

#include<iostream>
using namespace std;
void main()
{
    char str[]="12345\0123";
    //7
    cout<<strlen(str)<<endl;
    //8
    cout<<sizeof(str)<<endl;
}

4.单个字符

#include<iostream>
using namespace std;
void main()
{
    char str[]={'a','3','\0','1','2','e'};
    //2
    cout<<strlen(str)<<endl;
    //6
    cout<<sizeof(str)<<endl;
}

字节对齐问题

作用

为了提高CPU的存储速度,VC对一些变量的起始地址做了“对齐”处理.

重点

1.每个成员的偏移量都必须是当前成员所占内存大小的整数倍,如果不是,编译器会 自动补充字节.
2.当所有成员大小计算完毕后,编译器判断当前结构体大小是否是结构体中最宽的 成员变量大小的整数倍 , 如果不是会在最后一个成员后做字节填充.
3. 结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储.(struct a里存有struct b,b里有char,int ,double等元素,那b应该从8的整数倍开始存储.).
4.Vc,Vs等编译器默认是#pragma pack(8),所以测试我们的规则会正常;注意gcc默认是#pragma pack(4),并且gcc只支持1,2,4对齐.

结构体类型

#include<iostream>
using namespace std;
//规则1
typedef struct AA
{
    //4
    int id; 
     // 4不是8的整数倍 (4+4)+8
    double weight;
    //16是1的整数倍  16 +1
    float height;
}A;
//规则2,所求结构体大小(17)是否是结构体中最宽成员(8)的整数倍;字节填充成为24.

void main()
{
     //24
    cout<<sizeof(A)<<endl;
}

联合体类型

#include<iostream>
using namespace std;
typedef union BB
{
    // 4
    int id;
    // 20
    char ar[20];
    // 8
    double d;
}B;
//20不是8的整数倍,字节填充24
void main()
{
    cout<<sizeof(B)<<endl;
}

结构体镶嵌联合体

#include<iostream>
using namespace std;
typedef union BB
{

    int id;
    char ar[20];
    double d;
}B;
typedef struct AA
{
    int id;
    double weight;
    float height;
    //(20 +4)+24
    B b; 
}A;

void main()
{

    cout<<sizeof(A)<<endl;
    cout<<sizeof(B)<<endl;
}

结构体镶嵌结构体、联合体

#include<iostream>
using namespace std;
typedef union BB
{
    int id;
    char ar[20];
    double d;
}B;
typedef struct AA
{
    int id;
    double weight;
    float height;
    //24
    B b;
}A;
typedef struct CC
{
    //4
    int id;
    //4是1的整倍数,4 +3
    char weight[3];
    // 7不是8的整倍数,(7+1)+8
    double height;
    //48
    A a; 
}C;

void main()
{
    //48
    cout<<sizeof(A)<<endl;
    //24
    cout<<sizeof(B)<<endl;
    //64
    cout<<sizeof(C)<<endl;
}

struct内镶嵌结构体两种形式

1、当结构体内部镶嵌的结构体有名字时,把它当成类型处理不占空间,不计算在外面结构体大小里面。
2、当结构体内部镶嵌的结构体没有有名字时,计算在结构体大小里面;且按8字节对齐。

#include<iostream>
using namespace std;
struct  Test
{
    int a;//4
    struct 
    {
        char b;//1
        short c;//1+1 +2
        double d;//4+4 +8
    };
    int e;//4

    int a;//4
    struct  aa
    {
        char b;
        short c;
        double d;
    };
    int e;//4
};
void main()
{
    cout<<sizeof(struct Test )<<endl;//32
    cout<<sizeof(struct Test )<<endl;//16
}

//带有数组类型的类型,一种类型一种类型 计算

#include<stdio.h>
#include<iostream>
using namespace std;
class Test
{
private:
    int ar[5];// 20
    char str[6];// 26 26+6 +8*10 116 120
    double d[10];
    long a  
};
int mian()
{
    Test tt;
//120
cout<<sizeof(tt)<<endl;

}

//继承

#include<stdio.h>
#include<iostream>
using namespace std;
class Test
{
    //24
private:
    int ar; //4 
    char str[6]; //4+ 6 +6+8
    double d;   
};
//
class T
{
//16    
private:
    int ar; //4+1+3 +8
    char str; 
    double d;   
};
//16
class Test1:public Test,T
{
private:
    char str[2];//2+2 +4 +8
    int ar; 
    double d;   
};
int main()
{
    Test tt;
    Test1 tt1;
    //24
    cout<<sizeof(tt)<<endl;
    //56
    cout<<sizeof(tt1)<<endl;
    return 0;
}

指定字节对齐类型

一字节对齐 把所有的相加,不用考虑与1对齐

//设置字节对齐格式
#pragma pack(1)
typedef struct CC
{
    int id;
    char weight[3];
    double height;
}C;
//取消指定对齐,恢复缺省对齐
#pragma pack()
void main()
{
    //15
    cout<<sizeof(C)<<endl;
}

位域

通过位来计算大小,减小空间的浪费。

特点:

1、位域不能跨字节存储
2、位域不能跨类型存储
3、位域不能超过其类型对应的位数

#include<iostream>
using namespace std;
struct aa
{
    char a:1;
    char b:1;
    char c:1;
};
void main()
{
    //1个字节
    cout<<sizeof(aa)<<endl;
}
#include<iostream>
using namespace std;
struct aa
{
    char a:5;
    char b:2;
    char c:2;
};
void main()
{
    //2个字节,位域不能跨字节存储
    cout<<sizeof(aa)<<endl;
}
#include<iostream>
using namespace std;
struct aa
{
        int  d:1;
        char a:2;   
};
void main()
{   
    //位域不能跨类型存储
    //字节对齐  8
    cout<<sizeof(aa)<<endl;
}
#include<iostream>
using namespace std;
struct aa
{
    int  d:1;
    char a:9;//位域不能超过其对应的位数

};
void main()
{
    cout<<sizeof(aa)<<endl;
}

柔性数组

1、柔性数组不占内存,可以自动增长
2、柔性数组必须在结构体最后一个
3、柔性数组操作存储与栈区的字符串

#include<iostream>
using namespace std;
struct A
{
    int a ;
    double b;
    char c[0];
};
void main()
{
    char str[]="hello world !";
    struct A st;
    //16
    cout<<st.c<<endl;
    //hello world !
    cout<<sizeof(A)<<endl;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值