这节主要讨论sizeof和strlen的区别,以及一些理解题。
sizeof 求的是对象的大小,深入理解一点就是:这个对象,他一定有一块对应的内存空间。求的就是这一块内存空间。
strlen 只能用来求字符串, 求取的是字符串的长度。
sizeof是一个操作符, 并且是单目操作符。而strlen是一个函数,两者有着本质上的区别。
stlren求取字符串的方式是从一个基地址向后进行统计字符个数,直到遇到\0。而sizeof不会关注是否有\0,它只关注对象,对象对应的空间有多大, 结构就是多少。
这里有一些题:
sizeof(arr) : arr只有在两种情况下不是数组的首地址,一种情况就是sizeof运算符操作时,也就是这种情况,这总情况下arr代表的是整个数组, 是一个对象。另一种情况就是对数组名进行取地址,这个时侯的数组名也会发生改变,不再是首地址。
arr被操作符sizeof操作时,表示整个数组, 所以sizeof此时计算的是arr数组的整个空间大小。所以是3 * 4 == 12;
sizeof(arr + 1) : arr虽然在被sizeof操作符操作时代表整个数组, 但是arr + 1却是一个地址。可以理解为arr本身就是一个数组的首地址,可以进行整数加减运算,进行加一运算后仍是一个地址,这个时候的arr + 1只是一个地址,没有别的特别意义。所以sizeof此时计算的是一个地址的大小。而sizeof(地址)计算出来的结构由环境决定,32位下是4, 64位下是8。
sizeof(arr + 2) 和 sizeof(arr + 0)一样的道理。但是要注意sizeof(arr + 0)虽然加的是0,但是其本质上已经发生了变化。
下面再来看三个:
sizeof(*arr) : *arr也就是arr[0],代表的是arr数组里面的一个元素。对象是一个元素,而这个元素是int类型。故而sizeof求出来是4.
sizeof(arr[0])相同的道理。
sizeof(&arr) : 上面已经说过,arr只有在两种情况下表示的不是首地址(首地址是个常量,常量无法进行取地址),一种sizeof,一种&arr, &arr的值仍旧是arr常量的值, 但是类型不同。arr常量的类型显而易见是int* 类型。而&arr类型是int (*) [3]类型。也就是说,&arr类型其实是一个数组指针。sizeof计算一个指针的值与环境有关, 32位环境下是4.64位环境下是8。
二维数组:
sizeof(str[0][0] ) : str[0][0]确认到了元素个体, char类型一个字节, sizeof计算结果是1。
sizeof(str) : 在sizeof下代表整个数组。计算结果是16。
sizeof(str[0]) :是一次解引用。确认到了行, 拿到的是str第一行的首地址。那么问题来了, str解引用后拿到的第一行的首地址,代表的是第一行的数组整体呢?还是代表一个地址呢?
如果是代表这一行的整体, 那么结果就是一行的大小,也就是4.如果是一个地址, 在64位环境下就应该是8(我现在使用的是64位环境).而终端的结果现实的是4,证明这里即便拿到str第一行的首地址, 其实也被size当成了一个一维数组的整体。sizeof(*(arr + 1)) 的结果与其相同。