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. 《剑指offer》面试题17—合并两个排序链表

    题目:输入两个递增排顺序的链表,合并这两个链表并使合并后的链表仍是递增排序的. 重点: 1.代码鲁棒性:要判断输入的两个链表都为NULL:其中一个链表为NULL的情况. 2.用递归实现,注意递归的思路 ...

  2. supervisor简明教程

    一.supervisor是什么 Linux的后台进程运行有好几种方法,例如nohup,screen等,但是,如果是一个服务程序,要可靠地在后台运行,我们就需要把它做成daemon,最好还能监控进程状态 ...

  3. CSS小技巧收藏

    居中对齐 很多时候我们需要把一个元素在其父级容器里水平.垂直居中对齐.以下我列出了常用的几种方法: 1.在知道子元素宽度与高度的情况下进行居中,采用位置定位:absolute + margin .pa ...

  4. Java之多线程同步基础

    java学习的道路上呢总有一些麻烦的东西需要花费一些时间去理解,比如个人认为不好搞的多线程. 线程是并列运行的 因为是并列运行,所以有时候会发生资源抢占,从而导致参数变化; 比如酱紫 package ...

  5. 2019年最新总结,从程序员到CTO,从专业走向卓越,大牛分享文档pdf与PPT整理

    整理大牛分享文档如下,持续更新一线开发架构,技术文档 github链接 网易蜂巢公有容器云架构之路 新浪微博redis优化历程 微博Cache架构设计实践 Go在大数据开发中的经验总结 基于Go构建滴 ...

  6. Shiro 权限管理框架

    一.什么是Shiro Apache Shiro是一个强大易用的java安全框架,提供认证.授权.加密和会话管理等功能 · 认证:用户身份识别,俗称“登录”: · 授权:访问控制 · 密码加密:保护或隐 ...

  7. mysql--浅谈查询1

    这是对自己学习燕十八老师mysql教程的总结,非常感谢燕十八老师. 依赖软件:mysql5.6 系统环境:win 在谈查询之前,先说一个特别重要的概念 一定将列名看成变量,既然是变量就可以运算 一定将 ...

  8. 网络编程WebSocket 和socket、HTTP的区别和联系

    一.WebSocket 是什么? WebSocket是HTML5规范提出的一种协议:目前除了完犊子的IE浏览器,其他浏览器都基本支持.他是一种协议,万变不离其宗,也是基于TCP协议的:和HTTP协议是 ...

  9. PostgreSQL - update语句怎么关联多个表

    问题 对于select语句,我们可以通过join/outer join来关联多个表:但是对于update语句,是不能直接通过join/outer join来关联多表数据的,这里仅针对PostgreSQ ...

  10. shell学习(5)- sort

    Linux sort命令用于将文本文件内容加以排序. sort可针对文本文件的内容,以行为单位来排序. 参数如下: -b 忽略每行前面开始出的空格字符. -c 检查文件是否已经按照顺序排序. -d 排 ...