网站开发待遇怎么样,广告设计培训目的,网络推广怎么收费,做网站精英目录
sizeof和strlen的区别
sizeof
strlen
数组和指针笔试题解析
一维数组
字符数组
二维数组
指针运算笔试题解析
题目1#xff1a;
题目2#xff1a;
题目3#xff1a;
题目4#xff1a;
题目5#xff1a;
题目6#xff1a;
题目7#xff1a; sizeof和…目录
sizeof和strlen的区别
sizeof
strlen
数组和指针笔试题解析
一维数组
字符数组
二维数组
指针运算笔试题解析
题目1
题目2
题目3
题目4
题目5
题目6
题目7 sizeof和strlen的区别
sizeof
sizeof计算变量所占内存空间的大小单位是字节如果操作数是类型的话计算的是使用类型创建的变量所占内存空间的大小
sizeof只关注占用内存空间的大小不在乎内存中存放什么数据
sizeof是单目操作符不是函数
#include stdio.h
int main()
{int a 0;printf(%zd\n, sizeof(a));//4printf(%zd\n, sizeof(int));//4printf(%zd\n, sizeof a);//4——侧面证明了sizeof不是函数函数调用要有括号return 0;
}
sizeof后面的不进行计算 int b 8;short s 4;printf(%d\n, sizeof(s b 2));//2printf(%d\n, s);//4
C语言是编译型语言test.c-编译-链接-test.exe-运行
strlen
strlen是C语言库函数头文件是string.h功能是求字符串长度函数原型如下
size_t strlen(const char* str);
统计的是从strlen函数的参数str中这个地址开始向后\0之前字符串中字符的个数(不算\0)
strlen函数会一直向后找\0字符直到找到为止所以可能存在越界查找 size_t len strlen(abc\0ef);printf(%zd\n, len);//3 const char* str abcdef;printf(%zd\n, strlen(str));//6 char arr[] { a,b,c };printf(%zd\n, strlen(arr));//随机值——找到\0
数组和指针笔试题解析
一维数组
#include stdio.h
int main()
{//数组名的理解//数组名是数组首元素的地址但是有两个例外//sizeof(数组名)——数组名表示整个数组计算的是整个数组的大小单位是字节//数组名——数组名表示整个数组取出的是整个数组的地址int a[] { 1,2,3,4 };//数组有4个元素printf(%zd\n, sizeof(a));//164*4printf(%zd\n, sizeof(a 0));//4或8——a表示首元素地址类型是int*, a0还是首元素地址printf(%zd\n, sizeof(*a));//4——a是首元素的地址*a就是首元素大小是4个字节*aa[0]*(a0)printf(%zd\n, sizeof(a 1));//4或8——a表示首元素地址类型是int*a1就是第二个元素的地址printf(%zd\n, sizeof(a[1]));//4——第二个元素printf(%zd\n, sizeof(a));//4或8——整个数组的地址是地址就是4或8printf(%zd\n, sizeof(*a));//16——数组a的大小*和相抵消//a是数组的地址类型是int(*)[4],对数组指针解引用访问的是数组printf(%zd\n, sizeof(a 1));//4或8——a1是跳过整个数组后的那个位置的地址是地址就是4/8是野指针printf(%zd\n, sizeof(a[0]));//4或8printf(%zd\n, sizeof(a[0] 1));//4或8——数组第二个元素的地址return 0;
}
字符数组
代码1
#include stdio.h
int main()
{char arr[] { a,b,c,d,e,f };printf(%d\n, sizeof(arr));//66*1——计算数组大小printf(%d\n, sizeof(arr 0));//4或8——数组首元素的地址是地址就是4或8printf(%d\n, sizeof(*arr));//1——arr是首元素地址*arr就是首元素大小就是a的大小//*arrarr[0]*(arr0)printf(%d\n, sizeof(arr[1]));//1——第二个元素的大小printf(%d\n, sizeof(arr));//4或8——数组的地址printf(%d\n, sizeof(arr 1));//4或8——跳过整个数组得到的地址指向数组后面的空间//arr--char (*)[6]printf(%d\n, sizeof(arr[0] 1));//4或8——第二个元素的地址return 0;
}
代码2
#include stdio.h
#include string.h
int main()
{char arr[] { a,b,c,d,e,f };printf(%d\n, strlen(arr));//数组中没有\0导致越界访问结果是随机的printf(%d\n, strlen(arr 0));//arr0是数组首元素地址数组中没有\0导致越界访问结果是随机的//printf(%d\n, strlen(*arr));这个代码有问题//err——首元素a的地址a的ASCII码值是97相当于把97作为地址传递给了strlenstrlen得到的就是野指针//printf(%d\n, strlen(arr[1]));//err——b的ASCII码值是98同上printf(%d\n, strlen(arr));//数组的地址起始位置是数组的第一个元素的位置结束位置随机xprintf(%d\n, strlen(arr 1));//跳过整个数组得到的地址指向数组后面的空间随机值x-6printf(%d\n, strlen(arr[0] 1));//从第二个元素开始向后统计随机值x-1return 0;
}
代码3
#include stdio.h
int main()
{char arr[] abcdef;printf(%d\n, sizeof(arr));//7printf(%d\n, sizeof(arr 0));//4或8——arr表示数组首元素地址arr0还是数组首元素地址是地址就是4或8printf(%d\n, sizeof(*arr));//1——arr是首元素地址*arr就是首元素大小就是a的大小//*arrarr[0]*(arr0)printf(%d\n, sizeof(arr[1]));//1——第二个元素的大小printf(%d\n, sizeof(arr));//4或8——数组的地址printf(%d\n, sizeof(arr 1));//4或8——跳过整个数组得到的地址指向数组后面的空间//arr--char (*)[6]printf(%d\n, sizeof(arr[0] 1));//4或8——第二个元素的地址return 0;
}
代码4
#include stdio.h
#include string.h
int main()
{char arr[] abcdef;printf(%d\n, strlen(arr));//6printf(%d\n, strlen(arr 0));//6——arr首元素的地址arr0还是首元素的地址向后在\0之前有6个字符//printf(%d\n, strlen(*arr));//err——首元素a的地址a的ASCII码值是97相当于把97作为地址传递给了strlenstrlen得到的就是野指针//printf(%d\n, strlen(arr[1]));//err——b的ASCII码值是98同上printf(%d\n, strlen(arr));//6——数组的地址起始位置是数组的第一个元素的位置printf(%d\n, strlen(arr 1));//跳过整个数组得到的地址指向数组后面的空间随机值printf(%d\n, strlen(arr[0] 1));//5return 0;
}
代码5
#include stdio.h
int main()
{const char* p abcdef;printf(%d\n, sizeof(p));//4或8——p是指针变量指针变量的大小printf(%d\n, sizeof(p 1));//4或8——p1是b的地址是地址就是4或8//printf(%d\n, sizeof(*p));//1——p的类型是const char*,*p就是char类型printf(%d\n, sizeof(p[0]));//1——第一个元素的大小printf(%d\n, sizeof(p));//4或8——数组的地址printf(%d\n, sizeof(p 1));//4或8——跳过p指针变量后的地址是地址就是4或8printf(%d\n, sizeof(p[0] 1));//4或8——第二个元素的地址return 0;
}
代码6
#include stdio.h
#include string.h
int main()
{char* p abcdef;printf(%d\n, strlen(p));//6printf(%d\n, strlen(p 1));//5//printf(%d\n, strlen(*p));//err——首元素a的地址a的ASCII码值是97相当于把97作为地址传递给了strlenstrlen得到的就是野指针//printf(%d\n, strlen(p[0]));//err——b的ASCII码值是98同上printf(%d\n, strlen(p));//p是指针变量p的地址与字符串无关//从p这个指针变量的起始位置开始向后数p变量存放的地址是什么不知道所以答案是随机值printf(%d\n, strlen(p 1));//跳过整个数组得到的地址指向数组后面的空间随机值与上句无关因为有可能存在\0printf(%d\n, strlen(p[0] 1));//5return 0;
}
二维数组
#include stdio.h
int main()
{int a[3][4] { 0 };printf(%d\n, sizeof(a));//48——a是数组名单独放在sizeof内部计算的是整个数组的大小单位是字节483*4*4printf(%d\n, sizeof(a[0][0]));//4——第一行第一个元素的大小printf(%d\n, sizeof(a[0]));//16——a[0]第一行的数组名数组名单独放在sizeof内部了计算的是数组的总大小16个字节printf(%d\n, sizeof(a[0] 1));//4或8——a[0]第一行的数组名但是a[0]并没有单独放在sizeof内部//a[0]就是数组首元素的地址就是a[0][0],a[0]1即第一行第二个元素a[0][1]大小是4或8个字节printf(%d\n, sizeof(*(a[0] 1)));//4——a[0][1]的大小printf(%d\n, sizeof(a 1));//4或8——第二行地址的大小,a1是数组指针是地址大小就是4或8printf(%d\n, sizeof(*(a 1)));//16——第二行的大小164*4printf(%d\n, sizeof(a[0] 1));//4或8——第一行第二个元素的地址a[0]就是数组第一行的地址a[0]1就是第二行的地址printf(%d\n, sizeof(*(a[0] 1)));//16——第二行的大小printf(%d\n, sizeof(*a));//16——数组第一行的大小*a*(a0)a[0]printf(%d\n, sizeof(a[3]));//16——int [4],164*4;a[3]无需真实存在仅仅通过类型的推断就能算出长度//a[3]是第四行的数组名单独放在sizeof内部计算的是第四行的大小16个字节
}
指针运算笔试题解析
题目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));//2,5return 0;
}
题目2
#include stdio.h
//在X86环境下(32环境)
//假设结构体的大小是20个字节
//程序输出的结果是
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
}*p (struct Test*)0x100000;//结构体指针
//指针-整数
int main()
{//0x1就是1printf(%p\n, p 0x1);//00100014——结构体指针1要跳过整个结构体;0x10000020-0x100014printf(%p\n, (unsigned long)p 0x1);//00100001——不再是指针long类型整型值1就是1,0x1000001-0x100001printf(%p\n, (unsigned int*)p 0x1);//00100004——int*占4个字节return 0;
}
题目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]);//0return 0;
}
#include stdio.h
int main()
{int a[3][2] { (0,1),(2,3),(4,5) };//逗号表达式即{1, 3, 5}后面元素用0来填充int* p;p a[0];printf(%d, p[0]);//1return 0;
} 题目4
#include stdio.h
int main()
{int a[5][5];int(*p)[4];//p是一个数组指针,指向的数组是4个整型元素p a;printf(%p,%d\n, p[4][2] - a[4][2], p[4][2] - a[4][2]);//FFFFFFFC,-4//a的类型int (*)[5];p的类型是int (*)[4]一行四个元素//p[4][2]*(*(p4)2)//两个指针之间相差4个元素//指针-指针的绝对值是指针和指针之间的元素个数return 0;
}
题目5
#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*int* ptr2 (int*)(*(aa 1));//*(aa1)aa[1],aa[1]是第二行的数组名数组名表示首元素的地址aa[1]也是aa[1][0]printf(%d,%d, *(ptr1 - 1), *(ptr2 - 1));//10,5return 0;
}
题目6
#include stdio.h
int main()
{char* a[] { work,at,alibaba };//数组的每个元素都是char*,a是指针数组char** pa a;pa;printf(%s\n, *pa);//atreturn 0;
}
题目7
#include stdio.h
int main()
{char* c[] { ENTER,NEW,POINT,FIRST };char** cp[] { c 3,c 2,c 1,c };char*** cpp cp;printf(%s\n, **cpp);//POINT——cpp1,指向c2printf(%s\n, *-- * cpp 3);//ER——复杂优先级最低,cpp11解引用指向c1,c1-1即为c解引用得到ENTER首字母首字母3得到ERprintf(%s\n, *cpp[-2] 3);//ST——*cpp[-2]3即**(cpp-2)3,cpp2-2cpp,指向c3,指向FIRST,3得到STprintf(%s\n, cpp[-1][-1] 1);//EW——cpp[-1][-1]*(*(cpp-1)-1);cpp2-1cpp1,指向c2,c2-1c1指向NEW1得到EWreturn 0;
}