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. java保留小数位数

    System.out.println(String.format("%.5f",new Main().minRadius(n,m)));

  2. dos生成目录树

    1. tree命令详解 [Tree命令作用] 以图形显示驱动器或路径的文件夹结构. [Tree命令格式] 在命令行窗口使用tree /?查看帮助. TREE [drive:][path] [/F] [ ...

  3. hdu3257【模拟】

    题意: 从案例找: 思路: 就是16进制,然后到2进制= =.就是个模拟= =.注意格式: #include <bits/stdc++.h> using namespace std; ty ...

  4. Linux - 查看并修改当前的系统时间

    转载自Linux系统查看当前时间的命令 查看和修改Linux的时区 查看当前时区 命令 : date -R 修改设置Linux服务器时区 方法 A 命令 : tzselect 方法 B 仅限于RedH ...

  5. LIS的简单应用:UVA-437

    上一次紫芝详细地介绍了动态规划中的经典问题LIS,今天我们抽出一个类似思想的简单题目进行实践练习. The Tower of Babylon(巴比伦塔) Perhaps you have heard ...

  6. DB2 函数

    1.大小写转换 转大写UPPER 转小写LOWER

  7. [已读]CSS禅意花园

    蛮早的一本书,提到了一些小tip,比如负margin实现居中.FIR图像替换.

  8. Memcached 未授权访问漏洞及加固

    memcached是一套分布式的高速缓存系统.它以Key-Value(键值对)形式将数据存储在内存中,这些数据通常是应用读取频繁的.正因为内存中数据的读取远远大于硬盘,因此可以用来加速应用的访问. 漏 ...

  9. Unity AssetBundle笔记

    1.入门: Resources:表示U3D自动将资源打成一个AssetBundle包,所有放在Resources下的文件夹都会打成一个AssetBundle包,资源非常大,Resources文件夹在真 ...

  10. php __autoload函数 加载类文件

    面向对象的开发时,大家肯定都会遇到这样的问题,就是加载文件,一般都是加文件的头部inclue_once,require一大堆,看着很让人烦.当然你可以自己写程序来加载.php5以后引入了__autol ...