有什么设计logo网站,聊天app搭建,杭州网站设计步骤,电子商务的工作岗位有哪些?C语言--指针深入理解--题目篇 1. sizeof 与 strlen 比较1.1 sizeof1.2 strlen1.3 数组名的意义 2. 数组和指针笔试题解析#xff08;均以x86环境为例#xff09;2.1 ⼀维数组2.2 字符数组2.3 二维数组 3. 指针运算笔试题解析 1. sizeof 与 strlen 比较
1.1 sizeof
sizeof 计… C语言--指针深入理解--题目篇 1. sizeof 与 strlen 比较1.1 sizeof1.2 strlen1.3 数组名的意义 2. 数组和指针笔试题解析均以x86环境为例2.1 ⼀维数组2.2 字符数组2.3 二维数组 3. 指针运算笔试题解析 1. sizeof 与 strlen 比较
1.1 sizeof
sizeof 计算变量所占内存内存空间⼤⼩的单位是字节如果操作数是类型的话计算的是使⽤类型创建的变量所占内存空间的⼤⼩。
sizeof 只关注占⽤内存空间的⼤⼩不在乎内存中存放什么数据。
#inculde stdio.h
int main()
{int a 10;printf(%d\n, sizeof(a));//结果为 4printf(%d\n, sizeof a);//结果为 4printf(%d\n, sizeof(int));//结果为 4return 0;
}上述代码结果均为 4.
1.2 strlen
strlen 是C语⾔库函数功能是求字符串⻓度。函数原型如下 size_t strlen ( const char * str ); strlen 统计的是从 strlen 函数的参数 str 中这个地址开始向后 \0 之前字符串中字符的个数。 strlen 函数会⼀直向后找 \0 字符直到找到为⽌所以可能存在越界查找。
#include stdio.h
int main()
{char arr1[3] {a, b, c};//结尾没有\0,会造成越界char arr2[] abc;//a b c \0 共4个元素//结尾自带\0不会越界printf(%d\n, strlen(arr1));//结果为随机值因为越界了printf(%d\n, strlen(arr2));//结果为3printf(%d\n, sizeof(arr1));//结果为3printf(%d\n, sizeof(arr2));//结果为4\0也算作一个字符return 0;
}1.3 数组名的意义
sizeof(数组名)这⾥的数组名表⽰整个数组计算的是整个数组的⼤⼩。数组名这⾥的数组名表⽰整个数组取出的是整个数组的地址。除此之外所有的数组名都表⽰⾸元素的地址
2. 数组和指针笔试题解析均以x86环境为例
2.1 ⼀维数组
int main()
{int a[] { 1,2,3,4 };printf(%d\n, sizeof(a));//a 为数组名表示整个数组计算的是整个数组的大小结果为 16 (字节printf(%d\n, sizeof(a 0));//括号中不只是有数组名 a ,此时 a 仅表示数组中首元素的地址//加 0 之后仍表示首元素的地址地址的大小在x86环境下是4个字节结果为4printf(%d\n, sizeof(*a));//*a 表示数组中第一个元素元素类型是 int 类型结果为4printf(%d\n, sizeof(a 1));//括号中不只是有数组名 a ,此时 a 仅表示数组中首元素的地址//加 1 之后表示第二个元素的地址地址的大小在x86环境下是4个字节结果为4printf(%d\n, sizeof(a[1]));//a[1] 表示数组中第二个元素元素类型是 int 类型结果为4printf(%d\n, sizeof(a));//a 是整个数组的地址数组的地址也是地址结果为 4printf(%d\n, sizeof(*a));//arr 是整个数组的地址*(a)则是对整个数组的解引用等价于a结果为16printf(%d\n, sizeof(a 1));//a1 跳过了整个数组指向了数组的后边的地址结果为4printf(%d\n, sizeof(a[0]));//a[0]是数组第一个元素的地址结果为4 printf(%d\n, sizeof(a[0] 1));//a[0]是数组第一个元素的地址a[0]1 指向第二个元素的地址结果为4 return 0;
}2.2 字符数组
代码1
char arr[] {a,b,c,d,e,f};//arr数组中有6个元素
printf(%d\n, sizeof(arr));
//arr表示整个数组此时数组中结尾没有\0,结果为6
printf(%d\n, sizeof(arr0));
//括号中不只是有数组名 arr ,此时 arr 仅表示数组中首元素的地址
//加 0 之后仍表示首元素的地址地址的大小在x86环境下是4个字节结果为4
printf(%d\n, sizeof(*arr));
//*arr 是数组的首元素这里计算的是首元素的大小结果为1
printf(%d\n, sizeof(arr[1]));
//arr[1]是数组的首元素这里计算的是首元素的大小结果为1
printf(%d\n, sizeof(arr));
//arr 是整个数组的地址数组的地址也是地址结果为 4
printf(%d\n, sizeof(arr1));
//arr1 跳过了整个数组指向了数组的后边的地址结果为4
printf(%d\n, sizeof(arr[0]1));
//arr[0]是数组第一个元素的地址arr[0]1 指向第二个元素的地址结果为4 代码2
char arr[] {a,b,c,d,e,f};//arr数组中有6个元素但无\0
printf(%d\n, strlen(arr));
//arr 为数组首地址因为数组中无“\0,结果为随机值
printf(%d\n, strlen(arr0));
//arr0 仍为数组首地址因为数组中无“\0,结果为随机值
printf(%d\n, strlen(*arr));
//将一个具体字符放入strlen函数中相当于将其ASCII值放入函数中
//*arr结果为字符a相当于将97放入strlen中这是一种错误的用法
printf(%d\n, strlen(arr[1]));
//将一个具体字符放入strlen函数中相当于将其ASCII值放入函数中
//*arr结果为字符b相当于将98放入strlen中这是一种错误的用法
printf(%d\n, strlen(arr));
//arr虽然是整个数值的地址但也是指向数组的起始位置数组中无“\0,结果为随机值
printf(%d\n, strlen(arr1));
//arr1指向整个数组地址的下一个地址无法预料结果结果为随机值
printf(%d\n, strlen(arr[0]1));
//arr[0]1指向第二个元素的地址但数组中无“\0,结果为随机值代码3
char arr[] abcdef;//arr数组中有7个元素:a b c d e f \0
printf(%d\n, sizeof(arr));
//此处arr表示整个数组结果为 7
printf(%d\n, sizeof(arr0));
//arr0是数组首元素的地址地址的大小在x86环境下是4个字节
printf(%d\n, sizeof(*arr));
//*arr 是数组的首元素这里计算的是首元素的大小结果为1
printf(%d\n, sizeof(arr[1]));
//arr[1]是数组的首元素这里计算的是首元素的大小结果为1
printf(%d\n, sizeof(arr));
//arr 是整个数组的地址数组的地址也是地址结果为 4
printf(%d\n, sizeof(arr1));
//arr1 跳过了整个数组指向了数组的后边的地址结果为4
printf(%d\n, sizeof(arr[0]1));
//arr[0]是数组第一个元素的地址arr[0]1 指向第二个元素的地址结果为4 代码4
char arr[] abcdef;//arr数组中有7个元素:a b c d e f \0
//strlen 遇到\0 就会停下来
printf(%d\n, strlen(arr));
//arr是数组首元素地址结果为6
printf(%d\n, strlen(arr0));
//arr0 是数组的首元素的地址结果为6
printf(%d\n, strlen(*arr));
//将一个具体字符放入strlen函数中相当于将其ASCII值放入函数中
//传递的是’a-97//error
printf(%d\n, strlen(arr[1]));
//将一个具体字符放入strlen函数中相当于将其ASCII值放入函数中
//传递的是’b-98//error
printf(%d\n, strlen(arr));
//arr虽然是整个数值的地址但也是指向数组的起始位置,结果为6
printf(%d\n, strlen(arr1));
//arr1 跳过了整个数组指向了数组的后边的地址结果为随机值
printf(%d\n, strlen(arr[0]1));
//arr[0]1是第二个元素的地址从第二个元素开始计算结果为5代码5
char *p abcdef;//p存放的是第一个字符a 的地址结尾仍有一个\0
printf(%d\n, sizeof(p));
//p是指向a的指针sizeof计算的是一个地址结果为4
printf(%d\n, sizeof(p1));
//p1是指向b的指针sizeof计算的是一个地址结果为4
printf(%d\n, sizeof(*p));
//*p就是a大小为一个字节
printf(%d\n, sizeof(p[0]));
//p[0]*(p0)*p,就是a大小为一个字节
printf(%d\n, sizeof(p));
//p是指针p的地址仍旧是一个地址大小为4个字节
printf(%d\n, sizeof(p1));
//p1是指向指针p后面空间的地址仍旧是一个地址大小为4个字节
printf(%d\n, sizeof(p[0]1));
//p[0]1是b的地址是地址大小就是4个字节代码6
char *p abcdef; // a b c d e f \0
printf(%d\n, strlen(p));
//p存放的是第一个字符a 的地址
//strlen会根据第一个元素的地址找到其他所有数据直到遇到\0,结果为6
printf(%d\n, strlen(p1));
//p1存放的是第2个字符b 的地址,从第二个元素开始结果为5
printf(%d\n, strlen(*p));
//*p是a,是将a的ASCII值传入strlen中,错误用法err
printf(%d\n, strlen(p[0]));
//p[0]是a,是将a的ASCII值传入strlen中,错误用法err
printf(%d\n, strlen(p));
//p是首元素地址的地址会得到随机值
printf(%d\n, strlen(p1));
//p1是首元素地址的后面一个地址会得到随机值
printf(%d\n, strlen(p[0]1));
//p[0]1指向的是第二个元素的地址从第二个元素开始计算结果为52.3 二维数组
int a[3][4] {0};
printf(%d\n,sizeof(a));
//数组名单独放在sizeof内部计算的是整个数组的大小
//一共12个元素共12*448个字节
printf(%d\n,sizeof(a[0][0]));
//a[0][0]是第一个元素大小为4个字节
printf(%d\n,sizeof(a[0]));
//a[0]是第一行这个一维数组的数组命数组命单独放在sizeof内部了
//计算的是第一行的大小共16字节
printf(%d\n,sizeof(a[0]1));
//a[0]是第一行这个一维数组的数组命这里表示数组首元素
//也就是a[0][0]的地址a[0]1是a[0][1]的地址大小为4个字节
printf(%d\n,sizeof(*(a[0]1)));
//a[0]1是a[0][1]的地址*(a[0]1)是第一行第二个元素大小为4
printf(%d\n,sizeof(a1));
//a是二维数组的数组名但这里没有也没有单独放在sizeof内部
//所以这里a是数组第一行的地址a1是第二行的地址大小为4个字节
printf(%d\n,sizeof(*(a1)));
//*(a1)a[1]--第二行的数组名单独放在sizeof内部计算的是第二行的大小共16个字节
printf(%d\n,sizeof(a[0]1));
//a[0]是第一行的地址a[0]1就是第二行的地址大小为4个字节
printf(%d\n,sizeof(*(a[0]1)));
//访问的是第二行计算的是第二行的大小共16个字节
printf(%d\n,sizeof(*a));
//a是第一行的地址*a就是第一行sizeof(*a)计算的是第一行的大小16个字节
printf(%d\n,sizeof(a[3]));//这里不存在越界
//因为sizeof 内部的表达式不会真实计算的它只会根据类型进行计算
//计算的是第4行的大小--163. 指针运算笔试题解析
题目1
#include stdio.h
int main()
{int a[5] { 1, 2, 3, 4, 5 };int *ptr (int *)(a 1);printf( %d,%d, *(a 1), *(ptr - 1));return 0;
}a是将整个数组的地址a1是数组地址后面的地址所以ptr指向数组后面的一个地址ptr-1指向的就是数组中最后一个元素 a1中a是首元素的地址a1指向第二个元素的地址 上面结果为 2和5 题目2
/在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结构是啥
struct Test
{int Num;char *pcName;short sDate;char cha[2];short sBa[4];
}*p (struct Test*)0x100000;
int main()
{printf(%p\n, p 0x1);printf(%p\n, (unsigned long)p 0x1);printf(%p\n, (unsigned int*)p 0x1);return 0;
}结构体中将0x100000这个十六进制数强制转化为了结构体类型的地址并将其赋给了结构体指针p即此时p存放的是地址0x100000 0x1是十六进制表示的1p0x1即为p表示的地址往后移动一个相同类型大小的地址即往后移动20结构体的大小个字节。 (unsigned long) p是将p强制转换成无符号长整型类型仍属于整型(unsigned long)p 0x1表示该整型加 1 (unsigned int*)p是将p强制转换成了无符号整型指针指针加1往后移动该类型大小的指针即往后移动4个字节 本题结果为 0x1000001ox100014十六进制中二十表示为0x000014 0x1000001ox100001 0x1000001ox100004 题目3
#include stdio.h
int main()
{int a[3][2] { (0, 1), (2, 3), (4, 5) };int *p;p a[0];printf( %d, p[0]);return 0;
}二维数组中存放的是逗号运算实际结果为a[3][2]{1,3,5} a[0]表示的是二维数组第一行数组的地址即p中放的是第一行的数组{1,2} p[0]表示的是p代表数组的首元素,即1. 题目4
#include stdio.h
int main()
{int aa[2][5] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int *ptr1 (int *)(aa 1);int *ptr2 (int *)(*(aa 1));printf( %d,%d, *(ptr1 - 1), *(ptr2 - 1));return 0;
}如下图aa1指向的是数组后面地址的位置aa1指向的是第二行的地址 int *ptr1 (int *)(aa 1);表示将aa1指向的地址强制转换成 int* 类型并赋值给ptr1 int *ptr2 (int *)(*(aa 1));表示将aa1指向的地址强制转换成 int* 类型并赋值给ptr2 *(ptr1 - 1)指向的是数组最后一个元素即10 *(ptr2 - 1)指向的是数组第一行最后一个元素即5 题目5
#include stdio.h
int main()
{char *a[] {work,at,alibaba};char**pa a;pa;printf(%s\n, *pa);return 0;
}如下图pa最开始指向的是数组a的首地址p