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. LeetCode: 496 Next Greater Element I(easy)

    题目: You are given two arrays (without duplicates) nums1 and nums2 where nums1’s elements are subset ...

  2. Dapper的正确使用姿势

    本文demo适用于MySQL Dapper优势和缺点 优点 高性能.易排查.易运维.灵活可控 缺点 和EF相比,手写sql当修改表结构不易发现bug. 习惯了EF后再来使用Dapper,会很难适应那种 ...

  3. 玩转phpstorm之terminal

    启动快捷键  Alt+F12 启动之后,像这样 第一次进入这个配置默认显示的是cmd窗口,现在我们将其换成git 命令行窗口,毕竟git才是boss first 将cmd换成我们是先在电脑上安装完成的 ...

  4. 简单安装与使用composer

    1.下载composer.exe工具,然后进行安装 这一步需要找到你使用的php版本文件 2.windows+r     cmd  输入composer 安装中国镜像,提高使用效率 https://p ...

  5. 3DMAX 1快捷键及常用操作

    开启,关闭快捷键 ,使用快捷键时要按下这个按钮 快捷键查看与修改 自定义-自定义用户界面(cutomize user interface):设置和查看快捷键 位置变换 Z: 复位---物体被移动飞了的 ...

  6. C++两个类相互引用错误留影

    java中类相互引用很方便,c++中有编译顺序的问题 c++声明作用,告诉编译器,我声明的东西你要是找不到,那就跳过去吧,等全编译完你就可以找到了. C1.h #pragma once #includ ...

  7. Mol Cell Proteomics. |彭建祥| 人胃肠道间质瘤亚群蛋白质组图谱

    大家好,本周分享的是发表在Molecular & Cellular Proteomics 上的一篇关于人胃肠道间质瘤亚群蛋白质组图谱的文章,题目是Proteomic maps of human ...

  8. (八)SpringBoot使用mybatis-plus+自动代码生成

    一.SpringBoot使用mybatis-plus+自动代码生成 使用mybatis-plus可以自动帮我们生成通用的 controller,service,dao,mapper 二.加入依赖 &l ...

  9. PHP保留小数的相关方法

    结合一下网上的例子 $num = 10.4567; //第一种:利用round()对浮点数进行四舍五入 但是这个如果没有两位小数也不会"两位精度" echo round($num, ...

  10. python自建模块显示说明与详情

    通常我们自建模块放在/usr/lib/python2.7/site-packages下面,这样可以python就可以进行调用. 但是,自建模块也要有详细的说明情况,例如查help,可以看出来模块的作用 ...