📄 深入理解sizeof.htm
字号:
<p> <span lang=EN-US>Routine Required Header</span>: </p>
<p> <span lang=EN-US>strlen <string.h> </span></p>
<p> <span lang=EN-US>size_t strlen( const char *string ); </span></p>
<p> <span lang=EN-US>Parameter </span></p>
<p> <span lang=EN-US>string</span>:<span lang=EN-US>Null-terminated string
</span></p>
<p> <span lang=EN-US>Libraries </span></p>
<p> <span lang=EN-US>All versions of the C run-time libraries. </span></p>
<p> <span lang=EN-US>Return Value </span></p>
<p> <span lang=EN-US>Each of these functions returns the number of
characters </span></p>
<p><span lang=EN-US>in string, excluding the terminal NULL. No return value
is reserved </span></p>
<p><span lang=EN-US>to indicate an error. </span></p>
<p> <span lang=EN-US>Remarks </span></p>
<p> <span lang=EN-US>Each of these functions returns the number of
characters </span></p>
<p><span lang=EN-US>in string, not including the terminating null
character. wcslen </span></p>
<p><span lang=EN-US>is a wide-character version of strlen; the argument of
wcslen </span></p>
<p><span lang=EN-US>is a wide-character string. wcslen and strlen behave
identically </span></p>
<p><span lang=EN-US>otherwise. </span></p>
<p> 二、由几个例子说开去。 </p>
<p> 第一个例子:<span lang=EN-US>char* ss = "0123456789"; </span></p>
<p> <span lang=EN-US>sizeof(ss)</span>结果<span lang=EN-US>4 </span>==》<span
lang=EN-US>ss</span>是指向字符串常量的字符指针 </p>
<p> <span lang=EN-US>sizeof(*ss)</span>结果<span lang=EN-US>1 </span>==》<span
lang=EN-US>*ss</span>是第一个字符 </p>
<p> <span lang=EN-US>char ss[] = "0123456789"; </span></p>
<p> <span lang=EN-US>sizeof(ss)</span>结果<span lang=EN-US> 11 </span>==》<span
lang=EN-US>ss</span>是数组,计算到<span lang=EN-US>\0</span>位置,因此是 </p>
<p><span lang=EN-US>10</span>+<span lang=EN-US>1 </span></p>
<p> <span lang=EN-US>sizeof(*ss)</span>结果<span lang=EN-US>1 </span>==》<span
lang=EN-US>*ss</span>是第一个字符 </p>
<p> <span lang=EN-US>char ss[100] = "0123456789"; </span></p>
<p> <span lang=EN-US>sizeof(ss)</span>结果是<span lang=EN-US>100 </span>==》<span
lang=EN-US>ss</span>表示在内存中的大小<span lang=EN-US>100</span>×<span lang=EN-US>1
</span></p>
<p> <span lang=EN-US>strlen(ss)</span>结果是<span lang=EN-US>10 </span>==》<span
lang=EN-US>strlen</span>是个函数内部实现是用一个循环计算到<span lang=EN-US>\0</span>为止之前 </p>
<p> <span lang=EN-US>int ss[100] = "0123456789"; </span></p>
<p> <span lang=EN-US>sizeof(ss)</span>结果<span lang=EN-US>400 </span>==》<span
lang=EN-US>ss</span>表示再内存中的大小<span lang=EN-US>100</span>×<span lang=EN-US>4
</span></p>
<p> <span lang=EN-US>strlen(ss)</span>错误 ==》<span lang=EN-US>strlen</span>的参数只能是<span
lang=EN-US>char*</span>且必须是以<span lang=EN-US>''\0''</span>结尾的 </p>
<p> <span lang=EN-US>char q[]="abc"; </span></p>
<p> <span lang=EN-US>char p[]="a\n"; </span></p>
<p> <span lang=EN-US>sizeof(q),sizeof(p),strlen(q),strlen(p); </span></p>
<p> 结果是<span lang=EN-US>4 3 3 2 </span></p>
<p> 第二个例子:<span lang=EN-US>class X </span></p>
<p> <span lang=EN-US>{ </span></p>
<p> <span lang=EN-US>int i; </span></p>
<p> <span lang=EN-US>int j; </span></p>
<p> <span lang=EN-US>char k; </span></p>
<p> <span lang=EN-US>}; </span></p>
<p> <span lang=EN-US>X x; </span></p>
<p> <span lang=EN-US>cout<<sizeof(X)<<endl;</span>结果<span
lang=EN-US>12 </span>==》内存补齐 </p>
<p> <span lang=EN-US>cout<<sizeof(x)<<endl;</span>结果<span
lang=EN-US>12</span>同上 </p>
<p> 第三个例子:<span lang=EN-US>char szPath[MAX_PATH] </span></p>
<p> 如果在函数内这样定义,那么<span lang=EN-US>sizeof(szPath)</span>将会是<span
lang=EN-US>MAX_PATH</span>, </p>
<p>但是将<span lang=EN-US>szPath</span>作为虚参声明时(<span lang=EN-US>void fun(char
szPath[MAX_PATH]) </span>) </p>
<p><span lang=EN-US>,sizeof(szPath) </span>却会是<span lang=EN-US>4(</span>指针大小<span
lang=EN-US>) </span></p>
<p> 三、<span lang=EN-US>sizeof</span>深入理解。 </p>
<p> <span lang=EN-US>1.sizeof</span>操作符的结果类型是<span lang=EN-US>size_t</span>,它在头文件中<span
lang=EN-US>typedef </span>为 </p>
<p><span lang=EN-US>unsigned</span> <span lang=EN-US>int </span>类型。该类型保证能容纳实现所建立的最大对象的字
</p>
<p>节大小。 </p>
<p> <span lang=EN-US>2.sizeof</span>是算符,<span lang=EN-US>strlen</span>是函数。
</p>
<p> <span lang=EN-US>3.sizeof</span>可以用类型做参数,<span lang=EN-US>strlen</span>只能用<span
lang=EN-US>char* </span>做参数,且必 </p>
<p>须是以<span lang=EN-US>''\0''</span>结尾的。<span lang=EN-US>sizeof</span>还可以用函数做参数,比如:<span
lang=EN-US> short f(); </span></p>
<p><span lang=EN-US>printf("%d\n", sizeof(f())); </span></p>
<p> 输出的结果是<span lang=EN-US>sizeof(short) </span>,即<span lang=EN-US>2 </span>。
</p>
<p> <span lang=EN-US>4.</span>数组做<span lang=EN-US>sizeof</span>的参数不退化,传递给<span
lang=EN-US>strlen</span>就退化为指针了。 </p>
<p> <span lang=EN-US>5.</span>大部分编译程序在编译的时候就把<span lang=EN-US>sizeof</span>计算过了是类型或是
</p>
<p>变量的长度这就是<span lang=EN-US>sizeof(x) </span>可以用来定义数组维数的原因<span lang=EN-US>
char str[20]="0123456789"; </span></p>
<p> <span lang=EN-US>int a=strlen(str); //a=10; </span></p>
<p> <span lang=EN-US>int b=sizeof(str); //</span>而<span lang=EN-US>b=20; </span></p>
<p> <span lang=EN-US>6.strlen</span>的结果要在运行的时候才能计算出来,时用来计算字符 </p>
<p>串的长度,不是类型占内存的大小。 </p>
<p> <span lang=EN-US>7.sizeof</span>后如果是类型必须加括弧,如果是变量名可以不加括弧。 </p>
<p>这是因为<span lang=EN-US>sizeof</span>是个操作符不是个函数。 </p>
<p> <span lang=EN-US>8.</span>当适用了于一个结构类型时或变量,<span lang=EN-US> sizeof </span>返回实际的大小,
</p>
<p>当适用一静态地空间数组,<span lang=EN-US> sizeof </span>归还全部数组的尺寸。<span lang=EN-US>
sizeof </span></p>
<p>操作符不能返回动态地被分派了的数组或外部的数组的尺寸<span lang=EN-US>9.</span>数组作 </p>
<p>为参数传给函数时传的是指针而不是数组,传递的是数组的首地址, </p>
<p>如:<span lang=EN-US> fun(char [8]) </span></p>
<p> <span lang=EN-US>fun(char []) </span></p>
<p> 都等价于<span lang=EN-US> fun(char *)</span>在<span lang=EN-US>C++ </span>里传递数组永远都是传递指向数组
</p>
<p>首元素的指针,编译器不知道数组的大小如果想在函数内知道数组的 </p>
<p>大小,需要这样做:进入函数后用<span lang=EN-US>memcpy</span>拷贝出来,长度由另一个形 </p>
<p>参传进去<span lang=EN-US> fun(unsiged char *p1, int len) </span></p>
<p> <span lang=EN-US>{ </span></p>
<p> <span lang=EN-US>unsigned char* buf = new unsigned char[len+1] </span></p>
<p> <span lang=EN-US>memcpy(buf, p1, len); </span></p>
<p> <span lang=EN-US>} </span></p>
<p> 有关内容见:<span lang=EN-US> C++ PRIMER? 10.</span>计算结构变量的大小就必须讨论 </p>
<p>数据对齐问题。为了<span lang=EN-US>CPU </span>存取的速度最快(这同<span lang=EN-US>CPU </span>取数操作有关,
</p>
<p>详细的介绍可以参考一些计算机原理方面的书),<span lang=EN-US>C++ </span>在处理数据时 </p>
<p>经常把结构变量中的成员的大小按照<span lang=EN-US>4 </span>或<span lang=EN-US>8 </span>的倍数计算,这就叫数据
</p>
<p>对齐(<span lang=EN-US>data alignment</span>)。这样做可能会浪费一些内存,但理论上速 </p>
<p>度快了。当然这样的设置会在读写一些别的应用程序生成的数据文件 </p>
<p>或交换数据时带来不便。<span lang=EN-US>MS VC++ </span>中的对齐设定,有时候<span lang=EN-US>sizeof</span>得到
</p>
<p>的与实际不等。一般在<span lang=EN-US>VC++</span>中加上<span lang=EN-US>#pragma
pack(n) </span>的设定即可<span lang=EN-US>. </span>或 </p>
<p>者如果要按字节存储,而不进行数据对齐,可以在<span lang=EN-US>Options </span>对话框中 </p>
<p>修改<span lang=EN-US>Advanced compiler </span>页中的<span lang=EN-US>Data
alignment</span>为按字节对齐。 </p>
<p> <span lang=EN-US>11.sizeof </span>操作符不能用于函数类型,不完全类型或位字段。不 </p>
<p>完全类型指具有未知存储大小的数据类型,如未知存储大小的数组类 </p>
<p>型、未知内容的结构或联合类型、<span lang=EN-US>void</span>类型等。如<span lang=EN-US>sizeof(max)
</span>若此 </p>
<p>时变量<span lang=EN-US>max </span>定义为<span lang=EN-US>int </span> <span
lang=EN-US>max(),sizeof(char_v)</span> 若此时<span lang=EN-US>char_v</span>定义 </p>
<p>为<span lang=EN-US>char</span> <span lang=EN-US>char_v</span> <span
lang=EN-US>[MAX] </span>且<span lang=EN-US>MAX </span>未知,<span lang=EN-US>sizeof(void)</span>都不是正确形式
</p>
<p> 四、结束语 </p>
<p> <span lang=EN-US>sizeof</span>使用场合。 </p>
<p> <span lang=EN-US>1.sizeof</span>操作符的一个主要用途是与存储分配和<span lang=EN-US>I/O </span>系统那样的
</p>
<p>例程进行通信。例如: <span lang=EN-US>void</span> <span lang=EN-US>*malloc </span>(<span
lang=EN-US>size_t</span> <span lang=EN-US>size</span>)<span lang=EN-US>,
size_t </span></p>
<p> <span lang=EN-US>fread(void</span> <span lang=EN-US>* </span> <span
lang=EN-US>ptr,size_t</span> <span lang=EN-US>size,size_t </span> <span
lang=EN-US>nmemb,FILE</span> <span lang=EN-US>* </span> </p>
<p><span lang=EN-US>stream) </span>。 </p>
<p> <span lang=EN-US>2.</span>用它可以看看一类型的对象在内存中所占的单元字节。<span lang=EN-US>
void </span></p>
<p> <span lang=EN-US>* </span> <span lang=EN-US>memset</span>(<span
lang=EN-US>void</span> <span lang=EN-US>* </span> <span lang=EN-US>s,int </span> <span
lang=EN-US>c,sizeof(s) </span>) </p>
<p> <span lang=EN-US>3.</span>在动态分配一对象时<span lang=EN-US>, </span>可以让系统知道要分配多少内存。
</p>
<p> <span lang=EN-US>4.</span>便于一些类型的扩充<span lang=EN-US>, </span>在<span
lang=EN-US>windows </span>中就有很多结构内型就有一 </p>
<p>个专用的字段是用来放该类型的字节大小。 </p>
<p> <span lang=EN-US>5.</span>由于操作数的字节数在实现时可能出现变化,建议在涉及到操 </p>
<p>作数字节大小时用<span lang=EN-US>sizeof</span>来代替常量计算。 </p>
<p> <span lang=EN-US>6.</span>如果操作数是函数中的数组形参或函数类型的形参,<span lang=EN-US>sizeof</span>给
</p>
<p>出其指针的大小。 </p>
</td>
</tr>
</table>
<p class=MsoNormal><span lang=EN-US><o:p></o:p></span></p>
</td>
</tr>
</table>
<p class=MsoNormal><span lang=EN-US><o:p> </o:p></span></p>
</div>
</body>
</html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -