sizeof
sizeof可以理解为一个操作符,其作用简单的说就是返回一个对象或者类型所占的内存字节数。
MSDN上的解释为:
The sizeof keyword gives the amount of storage, in bytes, associated with a variable or a type(including aggregate types). This keyword returns a value of type size_t.
其返回值类型为size_t,在头文件stddef.h中定义。这是一个依赖于编译系统的值,
一般定义 typedef
unsigned int
size_t;
其有两种语法形式:
one:sizeof(type_name); //sizeof(类型);
two:sizeof
object; //sizeof对象;
举例:(在64位平台上)
one:
int是一种类型,代表整形 所以
sizeof(int)——正确 答案是:4
sizeof int ——错误
two:
int i;
sizeof(i)——正确 答案是:4
sizeof i ——正确 答案是:4
(i即可当作int整形,也可以被当作操作对象)
那么当 sizeof后面跟的是一个数时呢?
举例:
one:
sizeof 5 —— 5 会被计算机当作整形,相当于 sizeof(int)——答案是:4
two:
sizeof 3.1415926 ——3.14515926会被当作双精度浮点型,相当于 sizeof(double)——答案是:8
接下来讨论指针中的sizeof:
在32位系统中,一个指针变量的sizeof值通常是4
在64位系统中,一个指针变量的sizeof值通常为8 (以字节为单位)。
也就是说,不管你是int*、char*、float*、doudle* 等等。只要你是sizeof 一个指针,不管指针所指的对象是什么,得到的结果不是4就是8,这取决于你使用的计算机是32位还是64为操作系统。
下面是一道经典的笔试题:
解析:(单位为字节)
sizeof(arr)--——--表示计算数组整体的大小。(字符串末尾还有一个‘\0’所以答案为6+1=7)
sizeof(arr+0)--——--表示计算首元素地址大小。(只要是地址,不是4就是8,取决32位/64位)
sizeof(*arr)--——--表示计算首元素字节大小。(字符‘a’,char类型,所以字节大小是1)
sizeof(arr[1])--——--表示计算第二个元素字节大小(字符‘b’,所以字节大小是1)
sizeof(&arr)--——--表示计算arr数组地址的大小(&数组名 表示取出整个数组的地址)(地址)
sizeof(&arr+1)--——--表示计算跳过整个数组后的地址大小(但也是地址)
sizeof(&arr[0]+1)--——--表示计算第二个元素的地址大小(但也是地址)
strlen
strlen是一个函数,用来测量字符串实际长度(不包括‘\0’)。
strlen是STRing LENgth的缩写,除此之外strlen只能用char*做参数,且必须是以''\0''结尾的
简单功能如下:
char str[10] = "china";
printf("%d\n", strlen(str));
//结果如下:
5
D:\VS\Project4\x64\Debug\Project4.exe (进程 16032)已退出,代码为 0。
按任意键关闭此窗口. . .
下面是几个经典题目:
先说正确的吧:
strlen(arr)--——--计算数组整体长度,arr代表了数组首元素地址(计算结果是6)
strlen(arr+0)--——--和strlen(arr)一样(计算结果是6)
strlen(&arr[0]+1)--——--表示跳过第一个元素开始计算长度(计算结果是5)
至于为什么中间4个会报错呢?我们仔细来分析一下:
strlen (*arr) --——--对arr数组名解引用操作会得到字符‘a’->ASCII码97(地址)后面不会再遇到'\0',而strlen遇到'\0'才会停止,所以这种写法就是错误的。
strlen (arr[1]) --——--同理可得,strlen(arr[1])也是错误的。
strlen (&arr) --——--&arr表示整个数组的地址,为什么也不行呢?
提示:" const char *" 类型 的 实参 与 " char *" 类型 的 形参不兼容, 函数 形参 为 char *的 类型 直接写入字符串报错。 于是我抱着试一试的心态到linux平台上用gcc运行了一下,请看结果:
[bsk@localhost test1]$ gcc test.c
test.c: In function ‘main’:
test.c:6:1: warning: passing argument 1 of ‘strlen’ from incompatible pointer type [enabled by default]
printf("%d\n",strlen(&arr));
^
In file included from test.c:2:0:
/usr/include/string.h:395:15: note: expected ‘const char ’ but argument is of type ‘char ()[7]’
extern size_t strlen (const char *__s)
^
[bsk@localhost test1]$ ls
a.out dir1 file.txt test.c
[bsk@localhost test1]$ ./a.out
6
[bsk@localhost test1] ^C</code></pre></div></div><p>虽然给我提示警告了,但还是运行过去了。那strlen(&arr+1)呢?</p><div class="rno-markdown-code"><div class="rno-markdown-code-toolbar"><div class="rno-markdown-code-toolbar-info"><div class="rno-markdown-code-toolbar-item is-type"><span class="is-m-hidden">代码语言:</span>javascript</div></div><div class="rno-markdown-code-toolbar-opt"><div class="rno-markdown-code-toolbar-copy"><i class="icon-copy"></i><span class="is-m-hidden">复制</span></div></div></div><div class="developer-code-block"><pre class="prism-token token line-numbers language-javascript"><code class="language-javascript" style="margin-left:0">[bsk@localhost test1] vim test.c
[bsk@localhost test1]$ gcc test.c
test.c: In function ‘main’:
test.c:6:1: warning: passing argument 1 of ‘strlen’ from incompatible pointer type [enabled by default]
printf("%d\n",strlen(&arr+1));
^
In file included from test.c:2:0:
/usr/include/string.h:395:15: note: expected ‘const char ’ but argument is of type ‘char ()[7]’
extern size_t strlen (const char *__s)
^
[bsk@localhost test1]$ ls
a.out dir1 file.txt test.c
[bsk@localhost test1]$ ./a.out
0
[bsk@localhost test1]$
也成功运行了,但结果是一个随机值。由此可见vs的严谨性!!!