【C语言指针超详解(六)】--sizeof和strlen的对比,数组和指针笔试题解析,指针运算笔试题解析
目录
一.sizeof和strlen
1.1--sizeof
1.2--strlen
1.3--sizeof和strlen的对比
二.数组和指针笔试题解析
2.1--一维数组
2.2--字符数组
2.2.1--代码1:
2.2.2--代码2:
2.2.3--代码3:
2.2.4--代码4 :
2.2.5--代码5:
2.2.6--代码6:
2.3--二维数组
部分注意点总结:
三.指针运算笔试题解析
3.1--题目1:
3.2--题目2:
3.3--题目3:
3.4--题目4:
3.5--题目5:
3.6--题目6:
3.7--题目7:
🔥个人主页:@草莓熊Lotso的个人主页
🎬作者简介:C++研发方向学习者
📖个人专栏:《C语言》
⭐️人生格言:生活是默默的坚持,毅力是永久的享受。
一.sizeof和strlen
1.1--sizeof
-- sizeof 计算变量所占内存空间大小的,单位是字节,如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。
sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据;sizeof中表达式不计算
比如:
#include<stdio.h>
int main()
{int a = 10;printf("%d\n", sizeof(a));//4printf("%d\n", sizeof (a+3.14));//8//sizeof中表达式不计算//3.14是double类型,a是int类型//a要进行算术转换为double类型,所有最后结果还是double类型printf("%d\n", sizeof(int));//4return 0;
}
1.2--strlen
--strlen是C语言库函数,功能是求字符串长度。函数原型如下:
1 size_t strlen ( const char * str );
统计的是从strlen函数的参数str这个地址开始向后,\0之前字符串中字符的个数。
strlen函数会一直向后找\0字符,直到找到为止,所以可能存在越界查找。
#include <stdio.h>
#include<string.h>
int main()
{char arr1[3] = { 'a', 'b', 'c' };char arr2[] = "abc";//字符串后隐藏了一个\0;printf("%d\n", strlen(arr1));//随机值printf("%d\n", strlen(arr2));//3printf("%d\n", sizeof(arr1));//3printf("%d\n", sizeof(arr2));//4return 0;
}
arr1中没有\0所有strlen是找不到\0的,可能会越界访问,产生随机值。sizeof中直接放数组名算的是整个数组的大小
1.3--sizeof和strlen的对比
对比项目 | sizeof | strlen |
---|---|---|
类型 | 操作符 | 库函数(要包含头文件string.h) |
作用 | 计算变量或类型所占内存 空间大小,单位是字节 | 计算字符串中\0 之前字符的个数 |
参数类型 | 可以是各种类型数据类型 ,变量,表达式等 | 必须是const char*l类型 ,且字符要以\0结尾 |
是否关注\0 | 计算内存大小时,将\0所占空间 | 遇到\0停止计算, 不将\0计入字符串长度 |
编译/运行时计算 | 在编译阶段就可确定结果 所以sizeof中表达式不计算 | 在程序运行时才能计算出结果 |
举例 | char arr[] = "abc"; sizeof(arr)结果为4,包括\0的空间 | char arr[] = "abc"; strlen(arr)结果为3,不包括\0 |
二.数组和指针笔试题解析
--在分析题目前再回顾下数组名的意义:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
补充说明一下:sizeof里面如果是地址,不是4就是8,看在多少位机器下。再就是大家可以自己去画图理解下面的题目更直观
2.1--一维数组
--注意看注释
#include<stdio.h>
int main()
{int a[] = { 1,2,3,4 };printf("%zu\n", sizeof(a));//16//a是数组名,且单独存放在sizeof中,所以算的是整个数组的大小printf("%zu\n", sizeof(a + 0));// 4/8(看在多少位机器下)//a是数组名,且不单独存放在sizeof中,所以是数组首元素的地址,加0还是数组首元素的地址//只要是地址,就是4/8printf("%zu\n", sizeof(*a));//4//这里a是数组名,是数组首元素地址(原因不再说了),*a则是数组首元素,int类型,所以是4printf("%zu\n", sizeof(a + 1));// 4/8//这里a是数组首元素地址,a+1是数组第二个元素的地址,所以还是4/8printf("%zu\n", sizeof(a[1]));//4//数组中第二个元素,int类型,所以是4printf("%zu\n", sizeof(&a));// 4/8//&a是取出整个数组的地址,但还是地址,所以还是4/8//&a的特殊性主要体现在加减整数printf("%zu\n", sizeof(*&a));//16// *&a==a,a是数组名,且在sizeof中,所以算的整个数组大小printf("%zu\n", sizeof(&a + 1));// 4/8//&a是数组的地址,&a+1是跳过整个数组后的地址,是地址就是4/8个字节printf("%zu\n", sizeof(&a[0]));//4/8//&a[0]是数组首元素的地址,所以还是4/8printf("%zu\n", sizeof(&a[0] + 1));// 4/8//&a[0]+1就是第二个元素的地址,是地址就还是4/8
}
2.2--字符数组
--注意看注释
2.2.1--代码1:
#include<stdio.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zu\n", sizeof(arr));//6//arr是数组名,且放在sizeof中,所以是算整个数组大小,且是char,所以为6printf("%zu\n", sizeof(arr + 0));// 4/8//数组名arr在这里是数组首元素地址,是地址就是4/8printf("%zu\n", sizeof(*arr));// 1//数组名arr在这里是数组首元素地址,所以*arr就是数组首元素,char类型,为1printf("%zu\n", sizeof(arr[1]));// 1//arr[1]是数组第二个元素,char类型.为1printf("%zu\n", sizeof(&arr));// 4/8//&arr是数组地址,是地址就是4/8printf("%zu\n", sizeof(&arr + 1));// 4/8//&arr是数组地址。&arr+1是跳过一整个数组的地址,是地址就是4/8printf("%zu\n", sizeof(&arr[0] + 1));// 4/8//&arr[0]+1是数组第二个元素的地址,是地址就是4/8
}
2.2.2--代码2:
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = { 'a','b','c','d','e','f' };printf("%zu\n", strlen(arr));//随机值//数组名arr在这里是数组首元素地址,从这开始往后数,直到\0为止,但是找不到\0//所以会越界,产生随机值printf("%zu\n", strlen(arr + 0));//随机值//和上一句代码理由差不多,因为arr+0还是数组首元素地址//printf("%zu\n", strlen(*arr));//err,崩溃//arr在这里是数组首元素地址,*arr是数组首元素,也就是a,a-97//这里给到strlen的不是地址,[strlen(const char* p)]类型不符合,所以会编译错误//printf("%zu\n", strlen(arr[1]));//err,崩溃//arr[1]是数组第二个元素,后续缘由和上面相同printf("%zu\n", strlen(&arr));//随机值//&arr是数组的地址,但还是从首元素开始的,找\0,但是找不到,会越界printf("%zu\n", strlen(&arr + 1));//随机值//&arr是数组的地址,&arr+1是跳过一整个数组后的地址,但还是找不到\0//这里也会是随机值,不过和前面的不同,和第一,第二个的差6printf("%zu\n", strlen(&arr[0] + 1));//随机值//&arr[0]+1是数组第二个元素的地址,从这往后面找,但还是和前面情况相同,所以是随机值,但也是不同的//和第一,第二个的差1
}
2.2.3--代码3:
#include<stdio.h>
int main()
{char arr[] = "abcdef";//字符串里隐藏了个\0,所以其实是7个元素printf("%zu\n", sizeof(arr));//7//数组名arr直接放在sizeof中,算的是整个数组的大小,所以是7printf("%zu\n", sizeof(arr + 0));// 4/8//这里的数组名arr是数组的首元素地址,arr+0还是数组首元素的地址//是地址就是4/8printf("%zu\n", sizeof(*arr));//1//这里的数组名arr是数组的首元素地址,*arr是数组首元素,char类型,所以是1printf("%zu\n", sizeof(arr[1]));//1//arr[1]是数组第二个元素,char类型,所以是1printf("%zu\n", sizeof(&arr));// 4/8//&arr是数组的地址,是地址就是4/8printf("%zu\n", sizeof(&arr + 1));// 4/8//&arr是数组的地址,&arr+1是跳过一整个数组后的地址,是地址就是4/8printf("%zu\n", sizeof(&arr[0] + 1));// 4/8//&arr[0]+1是第二个元素的地址,是地址就是4/8
}
2.2.4--代码4 :
#include<stdio.h>
#include<string.h>
int main()
{char arr[] = "abcdef";//字符串里隐藏了个\0,所以其实是7个元素printf("%zu\n", strlen(arr));//6//这里的数组名arr是数组首元素的地址,从这开始往后找,直到\0;printf("%zu\n", strlen(arr + 0));//6//这里的数组名arr是数组首元素地址,arr+0还是,所以和上面的缘由一样//printf("%zu\n", strlen(*arr));//err,崩溃//*arr是数组首元素,这里给到strlen的不是地址// [strlen(const char* p)]类型不符合,所以会编译错误//printf("%zu\n", strlen(arr[1]));//err,崩溃//arr[1]是数组的第二个元素,理由和上面相同printf("%zu\n", strlen(&arr));//6//&arr是数组的地址,但还是从首元素开始的,直到\0printf("%zu\n", strlen(&arr + 1));//随机值//&arr是数组的地址,& arr + 1是跳过一整个数组后的地址,但就找不到\0了//会越界,产生随机值printf("%zu\n", strlen(&arr[0] + 1));//5//&arr[0]+1是第二个数组的地址,从这里开始,直到\0
}
2.2.5--代码5:
#include<stdio.h>
int main()
{char* p = "abcdef";//这里p存放的是首字符a的地址printf("%zu\n", sizeof(p));// 4/8//p存放的a的地址,是地址就是4/8printf("%zu\n", sizeof(p + 1));// 4/8//p+1(指针+1)还是地址,是b的地址,是地址就是4/8printf("%zu\n", sizeof(*p));// 1//p里存放的是a的地址,*p就是a,char类型,所以是1printf("%zu\n", sizeof(p[0]));// 1//p[0]=*(p+0)=*p=a,char类型,所以是1printf("%zu\n", sizeof(&p));// 4/8//&p是指针变量p的地址,是地址就是4/8printf("%zu\n", sizeof(&p + 1));//4/8//&p+1本质上也还是个地址,是地址就是4/8printf("%zu\n", sizeof(&p[0] + 1));// 4/8//&p[0]+1是第二个元素也就是b的地址,是地址就是4/8
}
2.2.6--代码6:
#include<stdio.h>
#include<string.h>
int main()
{char* p = "abcdef";//这里p存放的是首字符a的地址printf("%zu\n", strlen(p));//6//p里存放的是首字符a的地址,从这里开始找到\0为止printf("%zu\n", strlen(p + 1));//5//p+1是第二个字符b的地址,从这里开始也是找到\0为止//printf("%zu\n", strlen(*p));//err,崩溃// *p=a,这不是一个地址,和sizeof的参数类型不符合//printf("%zu\n", strlen(p[0]));//err,崩溃//p[0]=*(p+0)=*p=a,所以和上面一样printf("%zu\n", strlen(&p));//随机值//&p是指针变量p的地址,在这是找不到\0的,所以会是随机值printf("%zu\n", strlen(&p + 1));//随机值//&p+1是&p向后访问之后的地址,也是找不到\0的,但是随机值和上面不同printf("%zu\n", strlen(&p[0] + 1));//5//&p[0]+1就是从第二个元素也就是b的地址,从这里开始往后直到\0}
2.3--二维数组
--注意看注释
#include<stdio.h>
int main()
{int a[3][4] = { 0 };printf("%zu\n", sizeof(a));// 48//a是二维数组数组名,直接放在了sizeof中,计算的整个二维数组大小,12*4printf("%zu\n", sizeof(a[0][0]));//4//二维数组第一行第一个元素,int类型的printf("%zu\n", sizeof(a[0]));//16//a[0]是二维数组第一行一维数组的数组名,数组名直接放在sizeof中//算的是这一行一维数组的大小,4*4=16printf("%zu\n", sizeof(a[0] + 1));// 4/8//a[0]是二维数组第一行一维数组的数组名,在这里就是一维数组首元素的地址//a[0]+1是第一行一维数组第二个元素的地址,是地址就是4/8printf("%zu\n", sizeof(*(a[0] + 1)));// 4//a[0]+1是第一行一维数组第二个元素的地址,*(a[0] + 1)就是第二个元素,int类型printf("%zu\n", sizeof(a + 1));//4/8//a在这里是二维数组的首元素的地址,也就是第一行一维数组的地址,a+1则是第二行一维数组的地址//是地址就是4/8printf("%zu\n", sizeof(*(a + 1)));// 16//a + 1是第二行一维数组的地址,*(a + 1)则是第二行一维数组中的元素,4个,4*4=16printf("%zu\n", sizeof(&a[0] + 1));// 4/8//&a[0]是第一行一维数组的地址,&a[0]+1是跳过一整个数组之后的地址//其实也就是第二行一维数组的地址,是地址就是4/8printf("%zu\n", sizeof(*(&a[0] + 1)));//16//&a[0] + 1是第二行一维数组的地址,所以*(&a[0] + 1)是第二行所有元素,一共4个,4*4=16printf("%zu\n", sizeof(*a));//16//a是二维数组数组名,在这里就是二维数组的首元素的地址,也就是第一行一维数组的地址//*a则是第一行一维数组的所有元素,4个,4*4=16printf("%zu\n", sizeof(a[3]));//16//--sizeof中的表达式在编译时就已经确定结果了,所有后面不会计算了//sizeof在计算变量,数组大小时,是通过类型来推导的,不会真实去访问内存空间的//所以a[3]没有也不会发生越界访问,它的类型就是int(*)[4],那最后就是16
}
部分注意点总结:
- 判断存放的数据类型,是什么数组或者是字符指针变量存储字符串这种,它们各自有不同的特点
- 再注意数组名是否是那两种特殊情况,不是的话就是数组首元素地址。
- 注意如果sizeof里面是地址就是4/8,strlen要注意是否越界和参数类型是否匹配
- 最好可以画图理解
三.指针运算笔试题解析
3.1--题目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;
}
//程序的结果是什么?
//2 5
题解:
- &a是数组地址,+1跳过一整个数组到图示位置,将这样的地址存放在ptr中,类型不符合,所有将(&a+1)强制类型转换为(int*)类型。
- a是数组名,在这里是数组首元素地址,a+1是数组第二个元素的地址,*(a+1)则是第二个元素,也就是2
- ptr刚开始在图示&a+1处,减1到图中所示位置,*(ptr-1)则是此地址处的元素也就是5
- 所以程序的结果是:2 5
3.2--题目2:
#include<stdio.h>
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;
}
//在X86环境下
//假设结构体的大小是20个字节
//程序输出的结果是啥?
//00100014
//00100001
//00100004
题解:(注意是在X86环境下)
- 先将地址0x100000强制类型转换为(struct Test*)类型存放在p中
- 第一个printf里面p里存放的地址是(struct Test*)类型,假设结构体的大小是20个字节,+1就跳过20个字节,20转换成16进制就是0x000014,加起来后是0x100014
- 第二个printf里面将p强制类型转换为(unsigned long)类型,那+1就是直接+1,1转换为16进制就是0x000001,加起来后就是0x100001
- 第三个printf里面将p强制类型转换为(unsigned int*)类型,+1就是跳过4个字节,4转换为16进制就是0x000004,加起来后就是0x100004
- 所以最后程序的输出结果是:00100014 00100001 00100004 (每个结果间是会换行的)
3.3--题目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;
}
//程序输出的结果是啥?
//1
题解:
- 这里要注意数组里的几个元素用的是()而不是{},所以其实是逗号表达式,则int a[3][2] = {1,3,5};
- p=a[0]则是数组首元素地址,在二维数组中就是第一行一维数组的数组名
- p[0]等价于a[0][0]也就是第一行一维数组的首元素
- 所以程序的输出结果是 1
3.4--题目4:
#include <stdio.h>
int main()
{int a[5][5];int(*p)[4];p = a;printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);return 0;
}//假设环境是x86环境,程序输出的结果是啥?
//FFFFFFFC,-4
题解:(注意是在X86环境下)
- 根据代码,可以得出p中一行4个元素,再如图中划分出来p和a
- 根据图示找到&p[4][2]和&a[4][2]的位置
- 地址减地址(指针减指针)的绝对值是它们之间的元素个数,但这里没有绝对值,且明显&a[4][2]靠后,所以&p[4][2] - &a[4][2]小于0,故是-4
- 根剧printf中的占位符要求,%p需要按16进制打印地址(它认为内存中的补码就是地址),所以先将-4转换成二进制补码形式,再转换为16进制也就是FFFFFFFC,而%d则是按10进制打印,直接就是-4.
- 所以程序输出的结果是:FFFFFFFC -4
3.5--题目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* ptr2 = (int*)(*(aa + 1));printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;
}
//程序输出的结果是啥?
//10 5
题解:
- 分别将&aa + 1和*(aa + 1)强制类型转换为(int*)类型存放在ptr1和ptr2中
- &aa是整个二维数组地址,aa是数组名这里是数组首元素地址也就是第一行一维数组地址
- 都+1了,跳过的距离不一样,移动到图中所示位置,且*(aa+1)=aa[1]最后也就是第二行一维数组首元素地址
- *(ptr1 - 1), *(ptr2 - 1),如图所示位置,解引用分别求出来这个地址处的元素
- 所以程序的输出结果是:10 5
3.6--题目6:
#include <stdio.h>
int main()
{char* a[] = { "work","at","alibaba" };char** pa = a;pa++;printf("%s\n", *pa);return 0;
}
//程序输出的结果是啥?
// at
题解:
- 根据代码,可以得知pa存放的是数组a首元素的地址,pa++则得到了数组a第二个元素的地址,即at所在的地址,如图中所示
- *pa得到了字符串at,直接将它打印出来
- 所以程序的输出结果是:at
3.7--题目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);printf("%s\n", *-- * ++cpp + 3);printf("%s\n", *cpp[-2] + 3);printf("%s\n", cpp[-1][-1] + 1);return 0;
}
//程序输出的结果是啥?
//POINT
//ER
//ST
//EW
题解:
- 根据题目初始化条件画出下图,明确指向关系等
- 第一个printf:先++cpp,让cpp来到了图示cpp+1的位置,也就是拿到了c+2的地址,再解引用(*++cpp),得到了c+2所指向的POINT的地址,再次解引用,拿到了POINT,将它打印出来
- 第二个printf中:因为第一次printf中已经++cpp一次了,所以现在刚开始在图示cpp+1的位置,再次++cpp,来到了cpp+2的位置,也就是拿到了c+1的地址,解引用拿到c+1所指向的NEW的地址 ,然后 --,拿到了ENTER的地址,再解引用一次,拿到ENTER,最后+3,来到ENTER中的第二个E,所以打印出ER
- 第三个printf中:因为前两次的++cpp,现在它在图示cpp+2的位置上,这时的cpp[-2]等价于*(cpp-2),指向的是图示cpp的位置 ,其意义是拿到了c+3的地址后解引用得到了FIRST的地址,再继续解引用一次拿到了FIRST,最后+3来到FIRST中的S,所以打印出ST
- 第四个printf中:将cpp[-1][-1]等价于 *(*(cpp-1)-1) ,还是因为两次++cpp,刚开始在图示cpp+2的位置上,先解析*(*(cpp-1)-1),cpp-1拿到了c+2的地址,解引用得到c+2所指向的POINT的地址 再-1得到NEW的地址,解引用后拿到NEW,解析完*(*(cpp-1)-1)也就是cpp[-1][-1],再+1,来到NEW中的E,所以打印出EW
- 所以程序的输出结果是:POINT ER ST EW (每个结果间是会换行的)
往期回顾:
【C语言指针超详解(一)】--指针变量和地址,指针变量类型的意义,指针运算
【C语言指针超详解(二)】--const修饰指针变量,野指针的辩析,assert断言,指针的使用和传址调用
【C语言指针超详解(三)】--数组名的理解,一维数组传参的本质,冒泡排序,二级指针,指针数组
【C语言指针超详解(四)】--字符指针变量,数组指针变量,二维数组传参的本质,函数指针变量,函数指针数组,转移表
【C语言指针超详解(五)】--回调函数,qsort函数的理解和使用,qsort函数的模拟实现
结语:本篇文章就到此结束了,继前面几篇文章后,在此篇文章中给大家分享了sizeof和strlen的知识点,还有指针和数组以及指针变量笔试题,这篇也是指针的最后一篇了,后续会继续分析其它内容,如果文章对你有帮助的话,欢迎评论,点赞,收藏加关注,感谢大家的支持。
相关文章:
【C语言指针超详解(六)】--sizeof和strlen的对比,数组和指针笔试题解析,指针运算笔试题解析
目录 一.sizeof和strlen 1.1--sizeof 1.2--strlen 1.3--sizeof和strlen的对比 二.数组和指针笔试题解析 2.1--一维数组 2.2--字符数组 2.2.1--代码1: 2.2.2--代码2: 2.2.3--代码3: 2.2.4--代码4 : 2.2.5--代码5&#…...
Java 异常处理之 BufferUnderflowException(BufferUnderflowException 概述、常见发生场景、避免策略)
一、BufferUnderflowException 概述 BufferUnderflowException 是 Java NIO 包中的一个运行时异常,是 RuntimeException 的子类 public class BufferUnderflowException extends RuntimeException {... }# 继承关系java.lang.Object-> java.lang.Throwable->…...
OpenCV人脸识别LBPH算法原理、案例解析
文章目录 前言一、LBPH 算法原理概述1、LBP 特征计算2、均匀模式与旋转不变性3、直方图统计与识别 二、环境准备1、安装依赖2、数据集结构 三、代码实现(完整代码约 150 行)1、导入库与配置2、加载数据与标签生成3、 模型训练与保存4、 实时人脸识别5、主…...
Lightpanda开源浏览器:专为 AI 和自动化而设计的无界面浏览器
一、软件介绍 文末提供程序和源码下载 Lightpanda开源浏览器:专为 AI 和自动化而设计的无界面浏览器; Javascript execution Javascript 执行Support of Web APIs (partial, WIP)支持 Web API(部分、WIP)Compatible with Pla…...
Docker 疑难杂症解决指南:从入门到进阶的全面剖析
Docker 作为容器化技术的代表,凭借其轻量级、可移植性和高效资源利用率,已成为开发、测试和部署应用的标准工具。然而,在实际使用中,用户常常会遇到镜像构建失败、容器启动异常、网络配置问题等疑难杂症。本文将从镜像构建、容器生…...
CodeBuddy Craft,我的编程搭子
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 你好,我是悟空。 背景 最近项目组事情挺多,一个人要干多个人的活,而且写…...
如何实现一个运动会计分系统?(C语言版)
一、需求分析 设计一个运动会计分系统,计分信息包括参加学校,参与项目,性别,名次个数,各个学校获得名次信息。该系统具有以下功能 数据录入: 链表或结构体数组组织数据数据报表: 依照规定的报表格式对数据打印报表数据排序: 按照要求对数据进行统计,含简单统计及综合统计…...
linux内核主要由哪五个模块构成?
Linux内核是一个高度模块化的系统,其核心功能通常被划分为以下五大模块,共同协作实现操作系统的基础功能: 1. 进程管理(Process Management) 核心功能:负责进程的创建、调度、终止,以…...
编程日志5.5
树的结构代码 #include<iostream> using namespace std; //由于树的每个结点可能有一些孩子结点,这些孩子结点的数量不确定,所以可以用一个链表来把所有的孩子结点给串起来 //链表结点定义 //这段代码定义了一个结构体ListNode,用于表示链表中的一个结点。这个结构…...
React学习———React.memo、useMemo和useCallback
React.memo React.memo是React提供的一个高阶组件,用于优化函数组件的性能,它通过记忆组件的渲染结果,避免在父组件重新渲染时,子组件不必要的重新渲染 React.memo会对组件的props进行浅比较,如果props没有变化&#…...
OpenCV实现数字水印的相关函数和示例代码
OpenCV计算机视觉开发实践:基于Qt C - 商品搜索 - 京东 实现数字水印的相关函数 用OpenCV来实现数字水印功能,需要使用一些位操作函数,我们需要先了解一下这些函数。 1. bitwise_and函数 bitwise_and函数是OpenCV中的位运算函数之一&…...
【CUDA】Sgemm单精度矩阵乘法(下)
目录 前言1. 优化技巧5:使用register模拟二级缓存(内积转外积)2. 优化技巧6:使用register模拟二级缓存 float43. 优化技巧7:global memory转置再存放shared memory4. 优化技巧8:使用double buffer加速矩阵…...
cursor 学习
参考:AI编程神器!Cursor无限续杯!白嫖白嫖!!!...
学术论文的科研流程概述 视频会议记录
CCF-Talk SPP131期 浙江大学研究员彭思达的报告。 举例视频生成要多快好省。 提升代码能力:先明白基础的函数,可以复现一个网络。最好是实现一个操作系统。...
【Linux笔记】——Linux线程理解与分页存储的奥秘
🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:Linux 🌹往期回顾🌹:【Linux笔记】——进程信号的捕捉——从中断聊聊OS是怎么“活起来”的 🔖流水不争,争的…...
ACM算法
在ACM模式下使用JavaScript/TypeScript获取输入值 在ACM编程竞赛或在线判题系统(如LeetCode、牛客网等)中,JavaScript/TypeScript需要特定的方式来获取输入值。以下是几种常见的获取输入的方法: 1. 使用Node.js的readline模块 这是最常见的处理ACM模式…...
家用或办公 Windows 电脑玩人工智能开源项目配备核显的必要性(含 NPU 及显卡类型补充)
一、GPU 与显卡的概念澄清 首先需要明确一个容易误解的概念:GPU 不等同于显卡。 显卡和GPU是两个不同的概念。 【概念区分】 在讨论图形计算领域时,需首先澄清一个常见误区:GPU(图形处理单元)与显卡(视…...
FastByteArrayOutputStream和ByteArrayInputStream有什么区别
FastByteArrayOutputStream 和 ByteArrayInputStream 是两种完全不同的 Java I/O 类,它们的主要区别体现在 设计目的 和 使用场景 上。以下是详细对比: 1. 核心区别总结 特性FastByteArrayOutputStream (Spring框架)ByteArrayInputStream (JDK原生)所属…...
远程连接电脑的方法?异地远程桌面连接和三方软件实现
远程连接电脑,是指通过网络技术,在一台设备上操控另一台设备的电脑桌面,实现跨地域的操作和管理。在日常工作、技术支持、远程办公等场景中,远程连接电脑都发挥着重要作用。实现远程连接电脑主要有系统自带工具和第三方软件两种方…...
编程题 03-树2 List Leaves【PAT】
文章目录 题目输入格式输出格式输入样例输出样例 题解解题思路完整代码 编程练习题目集目录 题目 Given a tree, you are supposed to list all the leaves in the order of top down, and left to right. 输入格式 Each input file contains one test case. For each case, …...
数据预处理之数据平滑处理详解
信号数据收到噪声干扰,影响检测的准确性。数据平滑处理的关键步骤,旨在降低噪声同时保留信号特征。 1.1 移动平均(Moving Average) 原理:通过计算窗口内数据的平均值来平滑噪声,适用于快速去除高频噪声。…...
deepseek梳理java高级开发工程师算法面试题
Java高级工程师算法面试题与答案 一、数据结构与算法基础 1. 红黑树与AVL树比较 题目:详细说明红黑树和AVL树的区别及各自的适用场景,并用Java实现红黑树的插入操作。 答案: 区别对比: ┌─────────────────…...
【SSL证书系列】SSL证书工作原理解读
SSL(Secure Sockets Layer)及其继任者TLS(Transport Layer Security)是用于保护网络通信安全的加密协议。SSL证书是实现HTTPS协议的核心,其工作原理涉及加密技术、身份验证和信任机制。以下是其工作原理的详细分步解析…...
模板源码建站、定制建站和SaaS 建站有什么区别?企业建站应该怎么选?
最近遇到不少客户问,为什么现在做一个网站为什么从几百到几万的都有呀?市面上五花八门有模板源码建站、SaaS建站和定制建站我该怎么选?有什么区别?今天小编就跟大家一起来唠一唠,接下来我们就一起来看看吧!…...
OpenCV进阶操作:人脸检测、微笑检测
文章目录 前言一、OpenCV如何实现人脸检测1、haar特征2、级联分类器3、级联分类器的使用 二、人脸检测、微笑检测 案例实现1、预处理2、加载分类器3、标注人脸4、运行结果:4、微笑检测 总结 前言 要实现人脸识别首先要判断当前图像中是否出现了人脸,这就…...
论文查询的ai工具 —— SCAICH
(1)SCAICH的项目背景 SCAICH是由Scihub Web3 Community孵化的技术产品。SCAICH是一个非盈利性的平台,模式上采用免费邀请码模式,采用捐赠和广告维持成本。产品将会面向世界上所有国家的学者。 (2)SCAICH产品…...
Python+大模型 day01
Python基础 计算机系统组成 基础语法 如:student_num 4.标识符要做到见名知意,增强代码的可读性 关键字 系统或者Python定义的,有特殊功能的字符组合 在学习过程中,文件名没有遵循标识符命名规则,是为了按序号编写文件方便查找复习 但是,在开发中,所有的Python文件名称必须…...
elasticsearch硬件与资源配置优化
以下是Elasticsearch硬件与资源配置优化的综合方案,结合最新实践与核心优化逻辑: 一、硬件选型优化 存储设备 优先选用SSD作为存储介质,其随机读取性能比机械硬盘高5-10倍,尤其适合文档检索类高并发场景。单节点存储控制在2TB以内,避免超过5TB导致查询性能下降和系统…...
C++ 在 Windows 的开发经验与解决方案
一、开发环境搭建 在 Windows 上进行 C 开发,主流的集成开发环境(IDE)有 Visual Studio 和 CLion。Visual Studio 是微软官方推出的强大开发工具,对 Windows 平台有着原生的支持,集成了编译器、调试器、代码编辑器等一…...
1669上什么课
1.题目描述 暑假来了,晶晶报了四门课来充实自己的暑假生活;周一上游泳,周三上编程,周五上阅读,周六上数学;其余时间没课。请从键盘读入今天是星期几,输出晶晶今天应该上什么课。 请注意&#…...
通过MCP让LLM调用系统接口
场景 MCP的出现大大丰富了LLM的功能,对于存量系统,我们希望能让模型调用已有的接口,以最小的成本让AI能够获取系统内部数据。因此我们开发了一个名为http-api-call的MCP Server,来支持模型到内部API的调用 实现方案 使用用标准…...
Java NIO 深度解析:突破传统IO的性能瓶颈
一、Java NIO 核心价值与演进历程 1.1 传统IO的局限性 Java传统的BIO(Blocking I/O)模型在应对高并发场景时存在显著缺陷: 线程资源浪费:每个连接需要独立线程处理上下文切换开销:线程数增加导致CPU调度成本指数级增长吞吐量瓶颈:受限于线程池大小和操作系统限制响应延…...
AI-02a5a5.神经网络-与学习相关的技巧-权重初始值
权重的初始值 在神经网络的学习中,权重的初始值特别重要。实际上,设定什么样的权重初始值,经常关系到神经网络的学习能否成功。 不要将权重初始值设为 0 权值衰减(weight decay):抑制过拟合、提高泛化能…...
sqlalchemy库详细使用
SQLAlchemy 是 Python 中最强大、最受欢迎的 ORM(对象关系映射)库,它允许你使用 Python 对象来操作数据库,而不需要直接编写 SQL 语句。同时,它也提供了对底层 SQL 的完全控制能力,适用于从简单脚本到大型企…...
最短路和拓扑排序知识点
1、在一个有权无向图中,如果顶点b到顶点a的最短路径长度是10,顶点c与顶点b之间存在一条长度为3的边。(c与a的最短路径长度不超过13;c与a的最短路径不小于7) 2、我们用一个有向图来表示航空公司所有航班的航线。最适合…...
【Alist+RaiDrive挂载网盘到本地磁盘】
1.安装准备 安装RaiDrive RaiDrive - 像 USB 驱动器一样安装云存储 安装alist 安装方式请查看官网: AList文档 2.启动Alist(docker) docker官网 Install | Docker EngineDocker Desktop | Docker Docs 运行容器 docker run -d --restartalways -v /home/alist:/opt/alist/…...
达梦数据库 【-6111: 字符串转换出错】问题处理
达梦数据库 【-6111: 字符串转换出错】问题处理 问题背景问题分析问题总结 问题背景 今天在更新数据库某一个值属性的时候,执行更新语句报错提示 -6111: 字符串转换出错,但是自己检查了sql语句,只是一个简单的sql,并没有需要字符…...
Java的多线程笔记
创建一个线程的方法有多种,比如可以继承Thread类或者实现Runnable接口,结论是实现Runnable接口比前者更加优越。 二者代码对比 Java 不支持多继承,如果你继承了 Thread 类,就不能再继承其他类,实现 Runnable 接口后&am…...
学习51单片机01(安装开发环境)
新学期新相貌.......哈哈哈,我终于把贪吃蛇结束了,现在我们来学stc51单片机! 要求:c语言的程度至少要到函数,指针尽量!如果c语言不好的,可以回去看看我的c语言笔记。 1.开发环境的安装&#x…...
互联网协议的多路复用、Linux系统的I/O模式
目录 1. 互联网协议栈-多路复用 1.1. 应用层的多路复用 2.2. 传输层的多路复用 3.3. 网络层的多路复用 2. Linux系统的I/O模式 2.1. I/O 2.2. Socket 2.3. 从网卡到操作系统 2.4. Socket 编程模型 2.5. I/O多路复用 2.6. 阻塞/非阻塞、同步/异步 2.7. Question 1. …...
vue中,created和mounted两个钩子之间调用时差值受什么影响
在 Vue 中,created 和 mounted 是两个生命周期钩子,它们之间的调用时差主要受以下几个因素影响: 🟢 1. 模板复杂度与渲染耗时(最主要因素) mounted 的触发时间是在组件的 DOM 被挂载之后(也就是…...
软件设计师考试《综合知识》计算机编码考点分析——会更新软设所有知识点的考情分析,求个三连
2019-2023年真题深度解析与备考策略 分值占比分析 75分中编码相关分值分布与核心考点 年份编码相关题量分值占总分比例核心考点20232题2分2.67%补码表示范围、IEEE 754偏移量20223题3分4.00%原码/反码比较、浮点数规格化20211题1分1.33%补码表示-1的能力20202题2分2.67%移码…...
剖析提示词工程中的递归提示
递归提示:解码AI交互的本质,构建复杂推理链 递归提示的核心思想,正如示例所示,是将一个复杂任务分解为一系列更小、更易于管理、逻辑上前后关联的子任务。每个子任务由一个独立的提示来驱动,而前一个提示的输出(经过必要的解析和转换)则成为下一个提示的关键输入。这种…...
【SSL证书系列】https双向认证中客户端认证的原理
HTTPS双向认证(也称为双向SSL/TLS认证)是一种增强安全性的机制,其中客户端和服务器都需要验证彼此的数字证书,以确保双方身份的真实性。以下是其核心原理和步骤的详细解析: 一、双向认证的核心目标 双向身份验证&#…...
map格式可以接收返回 fastjson2格式的数据 而不需要显示的转换
Fastjson2 JSONObject 与 Map 的关系 Fastjson2 的 JSONObject 类定义如下: public class JSONObject extends JSON implements Map<String, Object>, Cloneable {// 实现了 Map 接口的所有方法(put、get、keySet 等) }解释ÿ…...
NHANES稀有指标推荐:PWI
文章题目:Association between plain water intake and the risk of osteoporosis among middle-aged and elderly people in the United States: a cross-sectional study DOI:10.3389/fnut.2025.1527771 中文标题:美国中老年人白开水摄入与…...
CN 第二章 应用层-单选题
非并行TCP连接 HTTP非持续连接 假定在同一Web服务器上的某HTML文件引用了3个非常小的对象(例如图片)。忽略传输时延,往返时延为RTT,不考虑连接释放时间,采用非并行TCP连接的HTTP非持续连接方式将该页面完整接收下来需…...
游戏引擎学习第279天:将实体存储移入世界区块
黑板讲解:为什么使用SOA(结构体数组)而不是AOS(数组结构体)来构建实体系统 我们在构建游戏实体系统时,探讨了使用结构体数组(SOA, Struct of Arrays)而不是结构体组成的数组&#x…...
zabbix7.2最新版本 nginx自定义监控(三) 设置触发器
安装zabbix-get服务 在zabbix-server端口安装zabbix-get服务 [rootlocalhost ~]# dnf install -y zabbix-get Last metadata expiration check: 1:55:49 ago on Wed 14 May 2025 09:24:49 AM CST. Dependencies resolved. Package Architectur…...
解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- OpenAI AGI 五阶段
解密企业级大模型智能体Agentic AI 关键技术:MCP、A2A、Reasoning LLMs- OpenAI AGI 五阶段 然后第三个阶段就是agent,注意这里面的agent和我们说应用程序开发的这个agent是一个不同的概念。AI just can take actions autonomously自动的去执行一些动作。但大家像今天我们看到…...