【C语言系列】深入理解指针(5)
深入理解指针(5)
- 一、sizeof和strlen的对比
- 1.1sizeof
- 1.2strlen
- 1.3sizeof和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:
- 四、总结
- 1. `sizeof`与`strlen`的区别
- 2. 数组和指针的关系
- 3. 字符数组与字符串
- 4. 指针运算
- 总结
一、sizeof和strlen的对比
1.1sizeof
sizeof是单目操作符(绝不是函数!!!),sizeof计算变量所占内存空间的大小的,单位是字节。
如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。
注:sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据。
比如:
#inculde <stdio.h>int main(){int a = 10;printf("%d\n", sizeof(a));printf("%d\n", sizeof a);printf("%d\n", sizeof(int));return 0;}
1.2strlen
strlen是C语言库函数,功能是求字符串长度。
函数原型是:
size_t strlen ( const char * str );
统计的是从strlen函数的参数str中这个地址开始向后,\0之前字符串中字符的个数。
注:strlen 函数会一直向后找 \0 字符,直到找到为止,所以可能存在越界查找。
代码如下:
#include <stdio.h>
int main()
{char arr1[3] = {'a', 'b', 'c'};char arr2[] = "abc";printf("%d\n", strlen(arr1));printf("%d\n", strlen(arr2));printf("%d\n", sizeof(arr1));printf("%d\n", sizeof(arr2));return 0;
}
运行结果如下:

1.3sizeof和strlen的对比
| sizeof | strlen |
|---|---|
| 1.sizeof是操作符 | 1.strlen是库函数,使用需要包含头文件string.h |
| 2.sizeof计算操作数所占内存的大小,单位是字节 | 2.strlen是求字符串长度的,统计的是\0之前字符的个数 |
| 3.不关注内存中存放什么数据 | 3.关注内存中是否有\0,如果没有\0,就会持续往后找,可能会越界 |
| 4.sizeof括号中有表达式的话,表达式是不参与计算的!!! |
用代码检验4,代码如下:
#include <stdio.h>
int main()
{
int a = 8;
short s = 4;
printf("%d\n",sizeof(s = a + 2));//2
printf("%d\n",s);//4
return 0;
}
运行结果如下:

那么为什么sizeof中的表达式不计算?
C语言是编译型语言,在编译期这个表达式并不会被执行,sizeof 运算的结果是在编译期间就已知的常数值,并不需要等到运行时才求解。因此,对于其中涉及到的操作数或者操作本身都不需要实际执行。
二、数组和指针笔试题解析
2.1 一维数组
*a == a[0] == *(a + 0)
数组名的理解:数组名是数组首元素(第一个元素)的地址。
但是有2个是例外:1.sizeof(数组名) —— 数组名表示整个数组,计算的是整个数组的大小,单位是字节。
2.&数组名 —— 数组名表示的是整个数组,取出的是整个数组的地址。
除此之外,所有的数组名是数组首元素(第一个元素)的地址。
笔试题代码和解析如下:
#include <stdio.h>
int main()
{
int a[] = {1,2,3,4};//数组有几个元素?//4
printf("%zd\n",sizeof(a));//16
printf("%zd\n",sizeof(a + 0));//a是首元素的地址 —— 类型是int*,a + 0还是首元素的地址,是地址大小就是4/8。
printf("%zd\n",sizeof(*a));//a是首元素的地址,*a是首元素,大小就是4个字节。
printf("%zd\n",sizeof(a + 1));//a是首元素地址,类型是int*,a + 1跳过1个整型,a + 1就是第二个元素的地址,是地址大小就是4/8。
printf("%zd\n",sizeof(a[1]));//a[1]就是第二个元素,大小是4个字节。
printf("%zd\n",sizeof(&a));//&a是数组的地址,数组的地址也是地址,是地址大小就是4/8字节。
printf("%zd\n",sizeof(*&a));//1.*&互相抵消了,等价于sizeof(a),16
//2.&a是数组的地址,类型是int(*)[4],对数组指针解引用访问的是数组,计算的是数组的大小,16
//char* —— 解引用访问的是char
//int* —— 解引用访问的是int
printf("%zd\n",sizeof(&a + 1));//&a + 1是跳过这个数组后的那个位置的地址,是地址大小就是4/8字节。
printf("%zd\n",sizeof(&a[0]));//首元素的地址,大小就是4/8字节。
printf("%zd\n",sizeof(&a[0] + 1));//&a[0] + 1 —— 数组第二个元素的地址,大小就是4/8字节。
return 0;
}
运行结果如下图:

2.2 字符数组
2.2.1代码1:
笔试题代码和解析如下:
#include <stdio.h>
int main()
{
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n",sizeof(arr));//数组名单独放在sizeof内部,计算的是数组的大小,单位为字节,6。
printf("%d\n",sizeof(arr + 0));//arr是数组名表示首元素的地址,arr + 0还是首元素的地址,是地址就是4/8字节。
printf("%d\n",sizeof(*arr));//arr是首元素的地址,*arr就是首元素,大小就是1个字节。
//*arr == arr[0] == *(arr + 0)
printf("%d\n",sizeof(arr[1]));//arr[1]是第二个元素,大小也是1个字节。
printf("%d\n",sizeof(&arr));//&arr是数组的地址,数组的地址也是地址,是地址大小就是4/8个字节。
//&arr —— char(*)[6]
printf("%d\n",sizeof(&arr + 1));//4/8个字节,&arr + 1,跳过整个数组,指向了数组后边的空间。
printf("%d\n",sizeof(&arr[0] + 1));//第二个元素的地址,是地址就是4/8个字节。
return 0;
}
运行结果如下图:

2.2.2代码2:
笔试题代码和解析如下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n",strlen(arr));//arr是首元素的地址,数组中没有\0,就会导致越界访问,结果就是随机的。
printf("%d\n",strlen(arr + 0));//arr + 0是数组首元素的地址,数组中没有\0,就会导致越界访问,结果就是随机的。
printf("%d\n",strlen(*arr));//arr是首元素的地址,*arr是首元素,就是'a','a'的ASCII码值是97,就相当于97作为地址传递给了strlen,strlen得到的就是野指针,代码是有问题的。
printf("%d\n",strlen(arr[1]));//arr[1] —— 'b' —— 98,传给strlen函数也是错误的。
printf("%d\n",strlen(&arr));//&arr是数组的地址,起始位置是数组的第一个元素的位置,随机值。
printf("%d\n",strlen(&arr + 1));//随机值。
printf("%d\n",strlen(&arr[0] + 1));//从第二个元素开始向后统计的,得到的也是随机值。
return 0;
}
运行结果如下图:


2.2.3代码3:
笔试题代码和解析如下:
#include <stdio.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n",sizeof(arr));//7,计算的是数组总大小,数组名单独放在sizeof内部。
printf("%d\n",sizeof(arr + 0));//arr表示数组首元素的地址,arr + 0还是首元素的地址,4/8字节。
printf("%d\n",sizeof(*arr));//arr表示数组首元素的地址,*arr是首元素,大小是1字节。
printf("%d\n",sizeof(arr[1]));//arr[1]是第二个元素,大小是1个字节。
printf("%d\n",sizeof(&arr));//&arr是数组的地址,是地址就是4/8字节。
printf("%d\n",sizeof(&arr + 1));//&arr是数组的地址,是地址就是4/8字节。
printf("%d\n",sizeof(&arr[0] + 1));//&arr是数组的地址,+1跳过整个数组,还是地址,是地址就是4/8字节。
return 0;
}
运行结果如下图:

2.2.4代码4:
笔试题代码和解析如下:
#include <stdio.h>
#include <string.h>
int main()
{
char arr[] = "abcdef";
printf("%d\n",strlen(arr));//6
printf("%d\n",strlen(arr + 0));//arr首元素的地址,arr + 0还是首元素的地址,向后统计在\0之前的字符个数。//6
printf("%d\n",strlen(*arr));//'a' —— 97,出错。
printf("%d\n",strlen(arr[1]));//'b' —— 98.出错。
printf("%d\n",strlen(&arr));//&arr是数组的地址,也是从数组第一个元素开始向后找,6。
printf("%d\n",strlen(&arr + 1));//随机值。
printf("%d\n",strlen(&arr[0] + 1));//5
//&arr —— char(*)[7]
//size_t strlen(const char*s);
return 0;
}
运行结果如下图:


2.2.5代码5:
笔试题代码和解析如下:
#include <stdio.h>
int main()
{
const char*p = "abcdef";
printf("%d\n",sizeof(p));//p是指针变量,我们计算的是指针变量的大小,4/8个字节。
printf("%d\n",sizeof(p + 1));//p + 1是b的地址,是地址大小就是4/8个字节。
printf("%d\n",sizeof(*p));//p的类型是char*,*p就是char类型了,1个字节。
printf("%d\n",sizeof(p[0]));//1.p[0]->*(p + 0)->*p->'a',大小1个字节。
//1.把常量字符串想象成数组。
//2.p可以理解为数组名,p[0],就是首元素。
printf("%d\n",sizeof(&p));//取出的是p的地址,地址的大小就是4/8个字节。
printf("%d\n",sizeof(&p + 1));//&p + 1是跳过p指针变量后的地址,地址的大小是4/8个字节。
printf("%d\n",sizeof(&p[0] + 1));//4/8,取出首元素的地址,+1是第二个字符的地址。
return 0;
}
运行结果如下图:

2.2.6代码6:
笔试题代码和解析如下:
#include <stdio.h>
#include <string.h>
int main()
{
char*p ="abcdef";
printf("%d\n",strlen(p));//6
printf("%d\n",strlen(p + 1));//5
printf("%d\n",strlen(*p));//*p就是'a' —— 97,err
printf("%d\n",strlen(p[0]));//p[0]->*(p + 0)->*p//err
printf("%d\n",strlen(&p));//&p是指针变量p的地址,和字符串“abcdef”关系就不大了,从p这个指针变量的起始位置开始向后数的,p变量存放的地址是什么,不知道,所以答案是随机值。
printf("%d\n",strlen(&p + 1));//随机值
printf("%d\n",strlen(&p[0] + 1));//5
return 0;
}
运行结果如下图:



2.3 二维数组
二维数组笔试题代码和解析如下:
#include <stdio.h>
int main()
{
int a[3][4] = {0};
printf("%d\n",sizeof(a));//a是数组名,单独放在sizeof内部,计算的是数组的大小,单位是字节 —— 48 = 3*4*sizeof(int)。
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]并没有单独放在sizeof内部,所以这里的数组名a[0]就是数组首元素的地址,即a[0]->&a[0][0],+1后是&a[0][1]的地址,大小是4/8个字节。
printf("%d\n",sizeof(*(a[0] + 1)));//第一行第一个元素,大小是4
printf("%d\n",sizeof(a + 1));//a作为数组名并没有单独放在sizeof内部,a表示数组首元素的地址,是二维数组首元素的地址,也就是第一行的地址,a + 1,跳过一行,指向了第二行,a + 1是第二行的地址,a + 1是数组指针,是地址大小就是4/8个字节。
printf("%d\n",sizeof(*(a + 1)));//1.a + 1是第二行的地址,*(a + 1)就是第二行,计算的是第二行的大小 —— 16。2.*(a + 1) == a[1],a[1]是第二行的数组名,sizeof(*(a + 1))就相当于sizeof(a[1]),意思就是把第二行的数组名单独放在sizeof内部,计算的是第二行的大小。
printf("%d\n",sizeof(&a[0] + 1));//a[0]是第一行的数组名,&a[0]取出的就是数组的地址,就是第一行的地址,&a[0] + 1就是第二行的地址,是地址大小就是4/8字节。
printf("%d\n",sizeof(*(&a[0] + 1)));//对第二行地址解引用,访问的就是第二行,大小是16个字节。
printf("%d\n",sizeof(*a));//a作为数组名并没有单独放在sizeof内部,a表示数组首元素的地址,是二维数组首元素的地址,也就是第一行的地址,*a就是第一行,计算的就是第一行的大小,16个字节。
printf("%d\n",sizeof(a[3]));//a[3]无需真实存在,仅仅通过类型的推断就能算出长度,a[3]是第四行的数组名,单独放在sizeof内部,计算第四行的大小,16个字节。
//sizeof(int);//4
//sizeof(3+5);//4
return 0;
}
运行结果如下图:

三、指针运算笔试题解析
3.1题目1:
指针运算笔试题代码和解析如下:
#include <stdio.h>
int main()
{
int a[5] = {1,2,3,4,5};
int*ptr = (int*)(&a + 1);//&a —— int(*)[5]
printf("%d %d",*(a + 1),*(ptr - 1));//ptr跳过了原来a数组指向下一个位置,*(ptr-1)访问的就是数组a中的5。
return 0;
}
运行结果如下图:

3.2题目2:
在X86(32位)环境下,假设结构体的大小是20个字节,程序输出的结果是什么?
指针运算笔试题代码和解析如下:
#include <stdio.h>
struct Test
{
int Num;
char*PcName;
short sDate;
char cha[2];
short sBa[4];
}*p = (struct Test*)0x100000;//结构体指针+1,跳过一个结构体;整型值+1,就是+1。
//指针+-整数
int main()
{
printf("%p\n",p + 0x1);//0x100000 + 20 -> 00100014
printf("%p\n",(unsigned long)p + 0x1);//0x100000 + 1 ->0x100001 -> 00100001
printf("%p\n",(unsigned int*)p + 0x1);//0x100000 + 4 -> 0x100004 -> 00100004
return 0;
}
运行结果如下图:

3.3题目3:
指针运算笔试题代码和解析如下:
#include <stdio.h>
int main()
{
int a[3][2] = {(0,1),(2,3),(4,5)};//1 3 5//初始化
int*p;
p = a[0];//&a[0][0];
printf("%d",p[0]);//1//*(p + 0) -> *p
return 0;
}
运行结果如下图:

3.4题目4:
假设环境是X86环境,程序的输出结果是什么?
指针运算笔试题代码和解析如下:
#include <stdio.h>
int main()
{//%d —— 是打印有符号的整数
//%p —— 是打印地址的
int a[5][5];//a —— 类型是:int(*)[5]
int(*p)[4];//p —— 类型是:int(*)[4]//p是一个数组指针,p指向的数组是4个整型元素的
p = a;//类型的差异 —— 警告
printf("%p,%d\n",&p[4][2] - &a[4][2],&p[4][2] - &a[4][2]);//FFFFFFFC,-4
return 0;
}
//指针-指针绝对值得到的是指针和指针之间的元素个数
运行结果如下图:


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));//10 5
return 0;
}
//*(aa + 1)->aa[1],aa[1]是第二行的数组名,数组名表示首元素的地址。
//aa[1]也是&aa[1][0]
//*(aa + 1)->aa[1],&aa[1]->第二行的地址
//sizeof(aa[1])->计算的是第二行的大小
运行结果如下图:

3.6题目6:
指针运算笔试题代码和解析如下:
#include <stdio.h>
int main()
{
char*a[] = {"work","at","alibaba"};//a是指针数组
char**pa = a;
pa++;
printf("%s\n",*pa);//at//%s是打印字符串,给一个地址,从这个地址向后打印字符串,直到\0
return 0;
}
画图分析:

运行结果如下图:

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);//POINT
printf("%s\n",*--*++cpp + 3);//ER
printf("%s\n",*cpp[-2] + 3);//**(cpp - 2) + 3//ST
printf("%s\n",cpp[-1][-1] + 1);//*c*(cpp-1) - 1//EW
return 0;
}
运行结果如下图:

四、总结
本文深入探讨了C语言中关于sizeof、strlen、数组和指针的一些基础概念,并通过代码示例进行了详细的讲解。以下是对主要内容的总结:
1. sizeof与strlen的区别
sizeof是一个运算符,用于计算变量或类型所占的内存空间大小,单位是字节。它与数据存储内容无关,只关注内存的占用。例如,sizeof(int)会返回一个整数类型的大小,而sizeof(a)会返回数组a的总字节数。需要注意的是,sizeof中的表达式不会被计算,仅仅是编译时确定的常量。
与此不同,strlen是C标准库中的一个函数,用于计算以'\0'(空字符)结尾的字符串的长度。它统计的是字符串中的字符个数,而不包括'\0'字符。因此,strlen在处理字符串时,必须确保字符串正确地以'\0'结尾,否则可能导致越界访问。
2. 数组和指针的关系
数组和指针是C语言中常见的概念,它们密切相关。数组名通常被认为是指向数组首元素的指针。通过数组名,可以访问数组的元素,但是数组名和指针在某些情况下也有所不同。例如,sizeof(a)计算的是整个数组的大小,而sizeof(a + 1)计算的是数组中某个元素的指针大小。此外,数组名也可以通过&a表示整个数组的地址,&a[0]表示数组首元素的地址。
3. 字符数组与字符串
字符数组在内存中的存储方式可能导致不同的行为。在没有'\0'结尾的情况下,使用strlen函数可能会导致越界访问,进而产生随机结果。通过具体的代码示例,文章展示了不同数组类型在使用sizeof和strlen时的差异,特别是字符数组和字符串常量。
4. 指针运算
指针运算是C语言中强大的功能之一。指针可以进行加减操作,指向内存中的不同位置。通过对数组指针进行运算,可以访问数组中的不同元素。指针间的运算遵循指针类型的大小,比如int*指针加1时会跳过一个int类型的大小,指向下一个int类型的数据。文章通过一系列例子展示了指针和数组在内存中的操作,包括指针的解引用、指针数组的运算等。
总结
本篇文章深入分析了sizeof、strlen、数组与指针等概念,并通过一系列代码示例加深了对这些概念的理解。对于初学者来说,掌握这些基础知识是学习C语言的关键。文章不仅揭示了这些基本概念的使用方法,还通过具体例子帮助理解如何避免常见的错误,如越界访问和指针运算中的误解。
相关文章:
【C语言系列】深入理解指针(5)
深入理解指针(5) 一、sizeof和strlen的对比1.1sizeof1.2strlen1.3sizeof和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&#…...
JVM图文入门
往期推荐 【已解决】redisCache注解失效,没写cacheConfig_com.howbuy.cachemanagement.client.redisclient#incr-CSDN博客 【已解决】OSS配置问题_keyuewenhua.oss-cn-beijing.aliyuncs-CSDN博客 【排坑】云服务器docker部署前后端分离项目域名解析OSS-CSDN博客 微服…...
uv 安装包
是的,你可以使用 uv 来安装 Python 包。uv 是一个高性能的 Python 包安装器和解析器,由 astral.sh 团队开发,旨在替代 pip 和 pip-tools,提供更快的包安装体验。 ### 如何使用 uv 安装包 1. **安装 uv**: 如果你还…...
Level2逐笔成交逐笔委托数据分享下载:20250127
Level2逐笔成交逐笔委托数据分享下载 采用Level2逐笔成交与逐笔委托的毫秒级数据,可以揭露众多有用信息,如庄家策略、伪装交易,让所有交易行为透明化。这对于交易高手的策略分析极为有用,对人工智能领域的机器学习也极为合适&…...
使用 Ollama 在腾讯云服务器环境部署 DeepSeek 大模型实战指南
文章目录 前言Ollama核心特性 实战步骤安装 Ollama验证安装结果部署 DeepSeek 模型拉取模型启动模型 交互体验命令行对话调用 REST API 总结个人简介 前言 近年来,大语言模型(LLM)的应用逐渐成为技术热点,而 DeepSeek 作为国产开…...
C++ 学习:深入理解 Linux 系统中的冯诺依曼架构
一、引言 冯诺依曼架构是现代计算机系统的基础,它的提出为计算机的发展奠定了理论基础。在学习 C 和 Linux 系统时,理解冯诺依曼架构有助于我们更好地理解程序是如何在计算机中运行的,包括程序的存储、执行和资源管理。这对于编写高效、可靠…...
JS:将JS对象格式化为php语法形式(完美支持无unicode编码匹配的正则)
/*** 格式化Object数据为php语法形式* param {*} obj 任意数据* param {String} spaceLen 缩略符长度:必须在2~65536之间,否则默认为2* return {String} 格式化后的PHP语法字符串*/ function formatToPhp(obj, spaceLen) {formatToPhp function (obj, s…...
网络安全 | 零信任架构:重构安全防线的未来趋势
网络安全 | 零信任架构:重构安全防线的未来趋势 一、前言二、零信任架构的核心概念与原理2.1 核心概念2.2 原理 三、零信任架构的关键技术组件3.1 身份管理与认证系统3.2 授权与访问控制系统3.3 网络与安全监测系统3.4 加密与数据保护技术 四、零信任架构与传统安全…...
告别手动操作!用Ansible user模块高效管理 Linux账户
在企业运维环境中,服务器的用户管理是一项基础但非常重要的任务。比如,当有新员工加入时,我们需要在多台服务器上为他们创建账户并分配合适的权限。而当员工离职或岗位发生变化时,我们也需要迅速禁用或删除他们的账户,…...
将Windows下的USB设备共享给WSL(ubuntu)
前言 本文用于学习记录,文中提到的方法也来自于网上资料,如有不对请指出,谢谢! 微软官方参考链接:https://learn.microsoft.com/zh-cn/windows/wsl/connect-usb 如果没有特殊标注,以下命令均在Windows终…...
lneaught SyntaxError :lnexpected tokenPIaYE(at chunk 5728.bdff1b31.is:1:1)
1.遇到问题: lneaught SyntaxError :lnexpected tokenPIaYE(at chunk 5728.bdff1b31.is:1:1) 当我部署到nginx上之后,第一次测试 没有啥问题当我点击登录之后,然后测试一个删除按钮之后就爆这个错误。 2.原因分析: 我遇到的是缓…...
Vue el-input密码输入框 按住显示密码,松开显示*;阻止浏览器密码回填,自写密码输入框;校验输入非汉字内容;文本框聚焦到内容末尾;
输入框功能集合 <template><div style"padding: 10px"><!-- 密码输入框 --><el-input:type"inputType"v-model"password"placeholder"请输入密码"auto-complete"new-password"id"pwd"style…...
Three.js实现炫酷图片粒子化效果:从聚合到扩散的动态演变
一、效果展示 本特效实现了一个基于图片像素的智能粒子系统,通过Three.js引擎驱动,呈现出以下惊艳效果: 图片粒子化:将任意图片转化为动态粒子系统智能聚合扩散:粒子在聚合状态与随机扩散状态间自然过渡物理运动模拟…...
MySQL中like模糊查询如何优化?
大家好,我是锋哥。今天分享关于【MySQL中like模糊查询如何优化?】面试题。希望对大家有帮助; MySQL中like模糊查询如何优化? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在MySQL中,LIKE模糊查询通常会影…...
为什么使用nohup 和 启动的python脚本,进程还在,但是不处理数据
使用 nohup 和 & 启动 Python 脚本后,进程仍然在运行但不处理数据,可能有几个原因: 1. 脚本内部问题(例如死循环、阻塞) Python 脚本内部可能存在阻塞操作或死循环,导致进程不执行预期的任务。你可以…...
Android 约束布局ConstraintLayout整体链式打包居中显示
Android 用约束布局ConstraintLayout实现将多个控件视作一个整体居中显示,使用 app:layout_constraintHorizontal_chainStyle"packed"实现 chain 除了链条方向有横向和竖向区分外, chain链条上的模式有 3种 spread - 元素将被展开&#…...
在 MySQL 8 中配置主从同步(主从复制)是一个常见的需求,用于实现数据的冗余备份、读写分离等。
在 MySQL 8 中配置主从同步(主从复制)是一个常见的需求,用于实现数据的冗余备份、读写分离等。以下是详细的配置步骤: 一、环境准备 假设你有两台 MySQL 服务器: 主服务器(Master):IP 地址为 192.168.1.100,端口为 3306从服务器(Slave):IP 地址为 192.168.1.101,…...
4 前端前置技术(上):AJAX技术、Axios技术(前端发送请求)
文章目录 前言一、Ajax技术(从服务端获取数据,发送各种请求)0 接口文档管理:使用apipost等接口测试软件创建接口便于前端后端分离测试1 基本概念2 原生Ajax使用示例(几年前的早期用法) 二、 Axios技术(对原…...
【自学笔记】Python的基础知识点总览-持续更新
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 Python基础知识总览1. Python简介2. 安装与环境配置3. 基本语法3.1 变量与数据类型3.2 控制结构3.3 函数与模块3.4 文件操作 4. 面向对象编程(OOP&#…...
lambda表达式写java比较器
文章目录 示例 1:按字符串长度比较示例 2:按数字大小比较示例 3:按对象属性比较(简洁:推荐)示例 4:使用 Comparator 的静态方法示例 5:链式比较 在Java中,Comparator 是一…...
vim modeline
1. 什么是 Vim 模型行(modeline)? Vim 模型行是嵌入在文件中的特殊注释行,用于告诉 Vim 编辑器如何配置编辑选项。它的语法格式如下: # vim: 选项1值1:选项2值2:...它以 # vim: 开头(# 是注释符ÿ…...
【赵渝强老师】Spark RDD的依赖关系和任务阶段
Spark RDD彼此之间会存在一定的依赖关系。依赖关系有两种不同的类型:窄依赖和宽依赖。 窄依赖:如果父RDD的每一个分区最多只被一个子RDD的分区使用,这样的依赖关系就是窄依赖;宽依赖:如果父RDD的每一个分区被多个子RD…...
前缀和练习——洛谷P8218:求区间和
题目: 这道题很简单,直接根据题目无脑套公式 代码: #include<bits/stdc.h> using namespace std; const int N 1e5 9; using ll long long; ll a[N], perfix[N]; int main() {ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);//取消同步输…...
Python----Python高级(并发编程:线程Thread,多线程,线程间通信,线程同步,线程池)
一、线程Thread 1.1、线程 线程(Thread)是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位线程是程序执行的最小单位,而进程是操作系统分配资源的最小单位;一个进程由一个或多个线程…...
八大排序算法细讲
目录 排序 概念 运用 常见排序算法 插入排序 直接插入排序 思想: 步骤(排升序): 代码部分: 时间复杂度: 希尔排序 思路 步骤 gap的取法 代码部分: 时间复杂度: 选择排序 直接选…...
组合总和III(力扣216)
这道题在回溯的基础上加入了剪枝操作。回溯方面我就不过多赘述,与组合(力扣77)-CSDN博客 大差不差,主要讲解一下剪枝(下面的代码也有回溯操作的详细注释)。我们可以发现,如果我们递归到后面,可能集合过小,无法满足题目…...
鲜牛奶订购系统的设计与实现
🍅点赞收藏关注 → 添加文档最下方联系方式咨询本源代码、数据库🍅 本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目希望你能有所收获,少走一些弯路。🍅关注我不迷路🍅 项目视频 基…...
python:内置函数与高阶函数
1.内置函数 abs() round() print(abs(-6))#求绝对值 print(round(3.56))#四舍五入运行结果 6 4 2.高阶函数 高阶函数:把一个函数作为参数传递给另外一个函数 实例一:绝对值加减法与四舍五入 def add_num(a,b):return abs(a)abs(b) print(add_num…...
postgresql 函数错误捕捉
BEGIN 逻辑块 EXCEPTION WHEN 错误码(如:unique_violation) or others THEN 异常逻辑块 END; 在PL/pgSQL函数中,如果没有异常捕获,函数会在发生错误时直接退出,与其相关的事物也会随之回滚。我们可以通过使…...
Java面试场景题分享
假设你在做电商秒杀活动,秒杀开始时,成千上万的用户同时请求抢购商品。你会如何设计系统来处理这些请求,确保库存不超卖 你如何保证库存的准确性? 这个问题引导你思考如何在高并发下确保库存更新的原子性,最直接的方式…...
