sizeof和strlen

来源:互联网 发布:手机流量软件 编辑:程序博客网 时间:2024/06/14 10:08

练习

第一个例子:

char* ss = “0123456789”;
1、sizeof(ss)的结果是4,ss是指向字符串常量的字符指针
2、sizeof(*ss)的结果是1,*ss是第一个字符

第二个例子:

char ss[] = “01233456789”;
1、sizeof(ss)结果是11,ss是数组,计算到’\0’的位置,因此是10+1
2、sizeof(*ss) 结果是1,*ss是第一个字符

第三个例子

char ss[100] = “0123456789”;
1、sizeof(ss)的结果是100,ss表示在内存中预分配的大小:100*1
2、strlen(ss)的结果是10,它的内部实现是用一个循环计算字符串的长度,直到’\0’为止。

第四个例子

int ss[100] = “0123456789”;
1、sizeof(ss)的结果是400,ss表示在内存中的大小,为100*4
2、strlen(ss)错误,strlen的参数只能是char*,且必须是以’\0’结尾的。

综合:

#include <stdio.h>#include <string.h>void func(char str[50]) {     printf("A %d B %d ",sizeof(str), strlen(str)); } int main(void) {     char stra[] = "HelloWorld";     char *strb = stra;     printf("C %d D %d ",sizeof(stra), sizeof(strb++));     func(++strb);     printf("E %d F %d\n",strlen(stra), strlen(strb++));     return 0; }/*C = 11,计算包括'\0'D = 4, 指针A = 4, 尽管形参是数组,但传递的依然是指针B = 9, 因为++strb, 使得strb = "elloWorld".E = 10, '\0'之前的所有字符F = 9, 同上分析。

转发经典:

1.常规

char str1[] = “Hello”;
sizeof (str1 ) = 6 (自动加了’\0’)
strlen (str1 ) = 5 (字符串的长度)
char str2[5] = {‘H’,’e’,’l’,’l’,’o’};
sizeof (str2 ) = 5 (字符数组的大小)
strlen (str2) = 未知 (该字符串缺少结束符’\0’)


char str3[6] = {‘H’,’e’,’l’,’l’,’o’,’\0’};
sizeof (str3) = 6 (字符数组的大小)
strlen (str3) = 5 (该字符串的长度为5)
sizeof:计算字符数组大小(包括’\0’)
strlen:计算长度,到’\0’为止

char *p1 = “Hello”;
sizeof ( p1 ) = 4 (p1是一个指针,大小为4)

==char *p2[]={“hello”,”world”};
sizeof ( p2 ) = 8 (p2是长度为2的字符串数组)==


int n = 10;
int *q = &n;
sizeof ( n ) = 4 (整型大小为4)
sizeof ( q ) = 4 (q是一个指针,大小为4)

2.动态分配内存

int p = (int )malloc( 100 );
sizeof ( p ) = 4 (p是一个指针,大小为4)

3.函数参数

void Function1( char p[],int num ){
sizeof ( p ) = 4 (数组在作为函数参数时均化为指针)
}

void Function2( int p[],int num ){
sizeof ( p ) = 4 (数组在作为函数参数时均化为指针)
}

数组作为参数传递时均作为指针传递,所以sizeof=4.

4.多重继承

class A{};  class B{};  class C : public A, public B{};  class D : virtual public A{};  class E : virtual public A, virtual public B{};

sizeof(A) = 1,
sizeof(B) = 1(空类大小为1,编译器安插一个char给空类,用来标记它的每一个对象)
sizeof ( C ) = 1 (==继承或多重继承后空类大小还是1==)
sizeof(D) = 4 (==虚继承时编译器为该类安插一个指向父类的指针==,指针大小为4)
sizeof(E) = 8 (指向父类A的指针与父类B的指针,加起来大小为8)

5.数据对齐

类(或结构)的大小必需为类中最大数据类型的整数倍.CPU访问对齐的数据的效率是最高的,因此通常编译浪费一些空间来使得我们的数据是对齐的

class A{public:    int a;};  class B{public:    int a ;    char b;};class C{public:    int a ;    char b;    char c;};

sizeof(A) = 4 (内含一个int ,所以大小为4)
sizeof(B) = 8 (int为4,char为1,和为5,考虑到对齐,总大小为int的整数倍即8)
sizeof(C) = 8 (同上)

6.函数与虚函数

编译器为每个有虚函数的类都建立一个虚函数表(其大小不计算在类中),并为这个类安插一个指向虚函数表的指针,即每个有虚函数的类其大小至少为一个指针的大小4

class A {public:    int a;    void Function();};class B {public:    int a;    virtual void Function();};class C : public B{public:    char b;};class D : public B{public:    virtual void Function2();     /*     Int a;  继承来的     Vptr *p; 虚函数指针*/};class E{public:    static void Function();};

sizeof (A) = 4 (内含一个int,普通函数不占大小)
sizeof (B) = 8 (一个int ,一个虚函数表指针)
sizeof (C) =12 (一个int ,一个虚函数表指针,一个char ,再加上数据对齐)
sizeof (D) = 8 (一个int ,一个虚函数表指针,==多个虚函数是放在一个表里的,所以虚函数表指针只要一个就行==了)
sizeof (E) = 1 (==static 函数不占大小,空类大小为1==)

7.父类的私有数据

虽然在子类中不可用,但是是可见的,因此私有的数据还是要占子类的大小

class A{private:    int a;};class B:public A{};sizof(B) = 4;    (内含一个不可用的父类的int