sizeof和strlen (string.h)

先看几个例子(sizeof和strlen之间的区别): 
(1) 对于一个指针,
  char* ss ="0123456789";  
  sizeof(ss)为4, ss是指向字符串常量的字符指针
  strlen(*ss)为1,*ss是第一个字符 
(2) 对于一个未定义长度的数组名,
  char ss[] = "0123456789"; 
  sizeof(ss)为11, ss是数组,计算到'\0'的位置,因此是(10+1) ,返回完整的内存长度。
  sizeof(*ss)为1,*ss是第一个字符 
(3) 对于已经定义了长度的数组名,
  char ss[100] = "0123456789"; 
  sizeof(ss)为100,ss表示在内存中预分配的大小,100*1。 
  strlen(ss)为10, 它的内部实现是用一个循环计算字符串的长度,直到'\0'为止。

  int ss[100]="0123456789"; 
  sizeof(ss)为400,ss表示在内存中的大小,100*4。 
  strlen(ss)错误,strlen的参数只能是char*,且必须是以'\0'结尾的。 
(4) 对于一个复合类型,比如类,结构,涉及到内存补齐的问题。请参考字节对齐

class X
{
  int i;
  int j;
  char k;
}; X x;
cout<<sizeof(X)<<endl; //结果为12, 内存补齐 char升为4.
cout<<sizeof(x)<<endl; //结果为12

两者的区别:

(1) sizeof操作符的结果类型是size_t,它在头文件 中的typedef为unsinged int类型。该类型保证能容纳实现所建立的最大对象的字节大小。 
(2) sizeof是算符,strlen是函数。 
(3) sizeof可以用类型作参数,strlen只能用char*作参数,且必须是以'\0'结尾的。sizeof还可以用函数作参数。比如:

short f();
printf("%d\n",sizeof(f()));

输出的结果是sizeof(short),即2。

(4) 数组作sizeof的参数不退化,传递给strlen就退化为指针。 
(5) 大部分编译器在编译的时候就把sizeof计算过了,是类型或是变量的长度。这就是sizeof(x)可以用来定义数组维数的原因:

char str[] = "";
int a = strlen(str); //a = 10
int b = sizeof(str); //而b=20

(6) strlen的结果要在运行的时候才能计算出来。用来计算字符串的长度,而不是类型占用内存的大小。

(7) sizeof后如果是类型必须加括号,如果是变量名可以不加括号,这是因为sizeof是个操作符而不是个函数。 
(8) 当使用了一个结构类型或变量时,sizeof返回实际的大小。当使用一静态的空间数组时,sizeof返回全部数组的尺寸。sizeof操作符不能返回被动态分配的数组或外部的数组的尺寸。 
(9) 数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:fun(char[8])、fun(char[])都等价于fun(char*)。在C++里传递数组永远都是传递指向数组首元素的指针,编译器不知道数组的大小。如果在函数内知道数组的大小,需要这样做:进入函数后用memcpy将数组拷贝出来,长度由另一个形参传进去。代码如下:

fun(unsigned char*p1, int len)
{
  unsigned char *buf = new unsigned char[len+];
  memcpy(buf, p1, len);
}

(10)计算结构变量的大小就必须讨论数据对齐问题。为了使CPU存取的速度最快(这同CPU取数操作有关,详细的介绍可以参考计算机组成原理),C++在处理数据时经常把结构变量中的成员的大小按照4或8的倍数计算,这就叫数据对齐(data alignment)。这样做可能会浪费一些内存,但在理论上CPU速度快了。当然,这样的设置会在读写一些别的应用程序生成的数据文件或交换数据时带来不便。MS VC++中的对齐设定,有时候sizeof得到的实际不等。一般在VC++中加上#program pack(n)的设定即可。或者如果要按字节存储,而不进行数据对齐,可以在Options对话框中修改Advanced Compiler选项卡中的"Data Alginment"为按字节对齐。 
(11)sizeof操作符不能用于函数类型、不完全类型或位字段。不完全类型指具有未知存储大小数据的数据类型,如未知存储大小的数组类型,未知内容的结构或联合类型,void类型等。

 
sizeof的使用场合 :
(1)sizeof操作符的一个主要用途是与存储分配和I/0系统那样的例程进行通信。例如:

void *malloc(size_t size);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

(2)用它可以看看某种类型的对象在内存中所占的单元字节。例如:

void *memset(void *s, int c, sizeof(s)); 

(3)在动态分配一个对象时,可以让系统知道要分配多少内存。 
(4)便于一些类型的扩充。在windows中有很多结构类型就有一个专用的字段用来存放该类型的字节大小 
(5)由于操作数的字节数在实现时可能出现变化,建议在涉及到操作数字节大小时用sizeof代替常量计算。 
(6)如果操作数是函数中的数组形参或函数类型的形参,sizeof给出其指针的大小。 
How many bytes will be occupied for the variable (definition: int **a[3][4])? 
A. 64   B.12    C.48   D.128 
答案:C

 
 
附录:
size_t 类型定义在cstddef头文件中,该文件是C标准库的头文件stddef.h的C++版。它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小。
在C++中,设计 size_t 就是为了适应多个平台的 。size_t的引入增强了程序在不同平台上的可移植性。size_t是针对系统定制的一种数据类型,一般是整型,因为C/C++标准只定义一最低的位数,而不是必需的固定位数。而且在内存里,对数的高位对齐存储还是低位对齐存储各系统都不一样。为了提高代码的可移植性,就有必要定义这样的数据类型。一般这种类型都会定义到它具体占几位内存等。当然,有些是编译器或系统已经给定义好的。经测试发现,在32位系统中size_t是4字节的,而在64位系统中,size_t是8字节的,这样利用该类型可以增强程序的可移植性。
 
 

strstr

 char *strstr( const char *s1, const char *s2 )
{
 int len2;
 if ( !(len2 = strlen(s2)) )
 return (char *)s1;
 for ( ; *s1; ++s1 )
 {
   if ( *s1 == *s2 && strncmp( s1, s2, len2 )== )
 return (char *)s1;
 }
 return NULL;
}

C-基础:详解sizeof和strlen,以及strstr的更多相关文章

  1. 详解sizeof与strlen

    一,sizeof是C语言的一种单目运算符,与C语言的其他运算符++,--一样,它并不是函数:sizeof()以字节为单位给出了操作数的大小:sizeof的值是无符号int. strlen是一个函数,只 ...

  2. Dom探索之基础详解

    认识DOM DOM级别 注::DOM 0级标准实际并不存在,只是历史坐标系的一个参照点而已,具体的说,它指IE4.0和Netscape Navigator4.0最初支持的DHTML. 节点类型 注:1 ...

  3. Android中Canvas绘图基础详解(附源码下载) (转)

    Android中Canvas绘图基础详解(附源码下载) 原文链接  http://blog.csdn.net/iispring/article/details/49770651   AndroidCa ...

  4. javaScript基础详解(1)

    javaScript基础详解 首先讲javaScript的摆放位置:<script> 与 </script> 可以放在head和body之间,也可以body中或者head中 J ...

  5. Python学习一:序列基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7858473.html 邮箱:moyi@moyib ...

  6. Python学习二:词典基础详解

    作者:NiceCui 本文谢绝转载,如需转载需征得作者本人同意,谢谢. 本文链接:http://www.cnblogs.com/NiceCui/p/7862377.html 邮箱:moyi@moyib ...

  7. 深入浅出DOM基础——《DOM探索之基础详解篇》学习笔记

    来源于:https://github.com/jawil/blog/issues/9 之前通过深入学习DOM的相关知识,看了慕课网DOM探索之基础详解篇这个视频(在最近看第三遍的时候,准备记录一点东西 ...

  8. 三剑客基础详解(grep、sed、awk)

    目录 三剑客基础详解 三剑客之grep详解 1.通配符 2.基础正则 3.grep 讲解 4.拓展正则 5.POSIX字符类 三剑客之sed讲解 1.sed的执行流程 2.语法格式 三剑客之Awk 1 ...

  9. java继承基础详解

    java继承基础详解 继承是一种由已存在的类型创建一个或多个子类的机制,即在现有类的基础上构建子类. 在java中使用关键字extends表示继承关系. 基本语法结构: 访问控制符 class 子类名 ...

随机推荐

  1. OpenCV第一课

    1.OpenCV下载地址:http://opencv.org/downloads.html 因为本人电脑装的是vs2010,所以下载的是opencv-2.4.11.exe(vc10.vc11.vc12 ...

  2. c#实现优先级队列

    http://www.baidu.com/s?wd=c%23%E4%BC%98%E5%85%88%E7%BA%A7%E9%98%9F%E5%88%97&ie=utf-8&f=8& ...

  3. 如何在普通 UIViewController 中使用 UITableView

    本系列文章 <Swift on iOS 学习笔记> 将以不定长度.不定内容.不定形式的方式对外发布,主要记录一些 “可重用” 的知识,感谢你的阅读. 在继承自 UIViewControll ...

  4. 在指定的ChartArea中显示Series

    WinForm的Chart有Series, ChartArea,输出图表就往Serie里扔数据就可以了,很方便是吧.我原想Area和serie有上下级关系,可是我错了,Area和Serie并没有上下级 ...

  5. 51Nod 1272 最大距离 (栈或贪心)

    #include <cstdio> #include <queue> #include <cstring> #include <iostream> #i ...

  6. ZROI 部分题目题解

    ZROI 部分题目题解 335 首先发现一个性质: 对于最短的边而言,所有点的路径如果经过了这条边,那么路径的权值就是这条边的边权(废话) 那么我们把最短的边拎出来,可以发现,博物馆确定时,每个点按照 ...

  7. UVA297:Quadtrees(四分树)

    题目描述 四象树是每个内结点均有4个子结点的特殊四叉树,它可用于描述平面上黑白图像.平面上的黑白图像是32行×32列的正方形,每个格子称为1个象素,是最小的图像单位.正方形图像可分成四个相等的小正方形 ...

  8. [HDU1595] find the longest of the shortest

    题目链接: 点我 题意: 给定一个\(n\)个点,\(m\)条边的带权无向图,起点为\(1\),终点为\(n\),现在可以删去其中的一条边,求一种删边方案使得剩下图的最短路值最大,输出这个最短路的长度 ...

  9. 解决 mac zsh 所有命令失效

    上面的没啥用, 直接看分割线吧, 上面的是第一次遇到这个问题, 没有解决.. zsh: command not found: 参考: https://www.jiloc.com/43492.html ...

  10. 修复在unix系统里的文件打开不能显示正常的颜色问题

    在mac上面看到mysql的配置文件的颜色永远是白色,为了让配置文件的颜色更加分明些,这个时候只需进入到home目录下新建一个.vimrc文件, vim  .vimrc set nu syntax o ...