实现strlen
size_t my_strlen(const char *str)
{
unsigned int count = 0;
assert(str); //检查师傅出现错误,会写进stderr并退出程序执行。如果宏NDEBUG已经定义,宏assert()将被忽略。
while(*str != '\0')
{
str++;
count++;
}
return count;
}
一.数组
1.一维数组
理解什么情况下是访问整个数组,省么情况下是访问数组元素
对于下述a来说:sizeof(a)与&a表示访问整个数组,其余情况表示访问数组元素
2.字符数组
sizeof
注意sizeof(*arr)表示访问arr的首元素,sizeof(&arr)表示访问的是整个数组的地址。
注意&arr+1和&arr[0]+1 前者是跳过一整个数组,后者是跳过该数组下的一个元素
strlen
3.字符串数组
sizeof
strlen
需要注意:strlen参数是const char *,而&arr的类型是一个数组指针,char (*p)[7] = &arr, 两者类型不一样会出现警告
3,4传的参数都是数组首元素a,a对应assci码值是97,那么就是strlen(97),从地址97还是计算长度,97是一个非法地址,会err
二、指针
1.字符串指针(常量字符串)
sizeof
strlen
三、二维数组
二维数组在空间内是连续开辟的,可以想象成多行多列
牢记:
把二维数组想象成一维数组。
除了sizeof(a)和&a,一旦涉及a就是首元素。想象成一维数组,则首元素a就是第一行
p[4][2] = *(*(p + 4) + 2)
四.真题
1
.
结果:2,5
解释:&a表示整个数组,&a+1就表示跳过整个数组加1,将该地址存入到ptr,ptr-1就是5.。*(a+1)因为a不是sizeof(a)也不是&a,就是数组首元素,首元素+1就是2.
2.
结果:0x00100014 0x00100001 0x00100004
解释:
p本身是一个结构体指针,结构体指针地址+1就相当于跳过整个结构体,结构体大小是20,换算成十六进制就是0x00100014
将地址转换成无符号长整形,加0x1(十进制1),所以四 0x00100001
将地址转换成无符号整形指针,+1对于指针类型来说就是加4 0x00100004
3.
结果:0x4 0x2000000
解:
4.
结果:1
5.
二维数组赋值给数组指针,对于数组指针来说每+1,相当于跳过一个数组,
地址-地址得到的是元素的个数,%p打印的是补码
6.
结果:10,5
解:&aa+1相当于跳过整个数组,ptr-1就是10 *(aa+1) = aa[1] 把二维数组想象成一维数组,则aa表示第一行首元素地址,aa+1表示第二行首元素地址
注意:
7.
结果:at
解:1.首先理解char **pa,表示指针*pa指向的数据类型是char *
2.题2指出,地址++有类型决定,假设int *a , 则a++跳过的是4个字节,同理char **pa pa++,跳过的是一个char *
3.上述指针数组布局如图:
8.
结果:POINT ER ST EW
解:1.先看内存布局
2.当++cp就使得char***指向c+2,解引用就是c+2,c+2解引用就是POINT
3.当++cp就使得char***指向c+1,解引用以后内容是c+1,--以后就是c,c解引用内容就是ENTER,+3从E打印
4.原本char***指向c+,当**(cp -2)+3 就是ST
5.cpp[-1][-1] == *(*(cpp -1)-1)