当前位置: 首页 > news >正文

C语言深入知识——(2)指针的深入理解

1、字符指针

(1)字符指针的普通用法

char a = 'A';
char* pa = &a;

但是一般来说字符指针很少这么用……更多是拿来存储一个字符串

(2)字符串的两种存储以及区别

  • 现在有了两种存储数组的方法
    • ①一个是使用char类型数组存储
    • ②另外一个是使用指向char类型的指针存储数组的首元素地址,将其当成字符串的“标记”
#include <stdio.h>
int main()
{char str1[] = "hello word.";char str2[] = "hello word.";const char *str3 = "hello word.";//将字符串的首字母h的地址存储在str3里面const char *str4 = "hello word.";if(str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if(str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return 0;
}
  • 两个数组存储不同的字符串,尽管他们的内容是相同的
  • 两个字符指针都指向内容相同的字符串

这意味着str3和str4指向的是同一个常量字符串,C/C++会把常量字符串存储到一个单独的内存区域,当几个指针指向同一串字符串时,他们实际是指向同一块内存。但是用相同的常量字符串去初始化不同数组时,数组会对常量字符串进行拷贝,开辟出不同的内存块,所以str1!=str2,但是str3==str4

(3)存储多个字符串----字符指针数组

int main()
{char* arr[3] = { "abcd", "cdf", "jiuh" };int i = 0;for(i = 0; i < 3; i++){printf("%s\n", arr[i]);}return 0;
}

2、指针数组

比较简单,直接写下code就可以

char* arr[4];//存储了4个char*指针
char** arr[10];//存储了10个char**指针

3、数组指针

(1)数组的基础概念

  • 数组名字有两种情况如下code
//复习数组的名字含义
#include <stdio.h>
int main()
{int arr[10] = { 0 };printf("%p\n", arr);//数组名字就是首元素地址printf("%p\n", &arr[0]);//取出了首元素地址printf("%p\n, &arr);//1、取出来整个数组的地址,尽管&arr和&arr[0]的值一样,但是意义不一样(类型不一样),前者是数组类型int[10],后者是整型类型intprintf("%zd\n", sizeof(arr));//2、这里的arr依旧是整个数组return 0;
}

①sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小
②&数组名,这里取出来的是整个数组地址,尽管它的值和数组的首元素地址相同,两者是有区别的

最大的区别就在于int arr[10]声明后,arr是首元素地址,指针类型是int*,这是个数组指针。而能存放&arr这个地址的指针类型是int(*)[10]。这点在对两种指针进行+/-整数的时候会更加明显,因为指针会根据指向的类型对地址值进行增加 (数组指针后面会讲)

(2)数组指针的定义

数组指针也是指针

int (*p)[10];//p是一个指向一维整型数组的指针,该数组内含10个int类型

注意[]和()具有相同的优先级,结合性是从左向右结合。并且优先级都比*高。

(3)数组指针的使用

//第一种使用方法
int main()
{int arr[10] = {1, 2, 3, 4, 5};int (*p)[10] = &arr;return 0;
}语法逻辑没毛病,可以,但是一般不会这么使用
//第二种使用方法
#include <stdio.h>
void print_arr1(int arr[3][5], int row, int col)
{int i = 0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}
}void print_arr2(int (*arr)[5], int row, int col)
{int i = 0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}
}int main()
{int arr[3][5] = {1,2,3,4,5,6,7,8,9,10};//数组名arr,表示首元素的地址//但是二维数组的首元素是二维数组的第一行,指向这一行的指针类型可以写成int [][5]或者int (*)[5]//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址print_arr1(arr, 3, 5);print_arr2(arr, 3, 5);return 0;
}

(4)更多数组指针的解读

int arr[5];//单纯是个整型数组int* parr1[10];//单纯是一个指针数组,每一个指针都指向一个intint (*parr2)[10];//数组指针,该指针指向一个包含10个int元素的数组int (*parr3[10])[5];//指针数组,可以思考成“int(*)[5] parr3[10]”(与int arr[5]是类似的)很明显,这是一个包含10个元素的数组,每个元素都int(*)[5]这种类型的指针,这种指针指向一包含5个元素的数组

4、数组传参和指针传参

(1)一维数组传参

#include <stdio.h>
void test1(int arr[])//可以这么写
{//code
}
void test1(int arr[10])//10写与不写都行,无所谓,C会将它忽略
{//code
}
void test1(int *arr)//可以的,传过来的arr1的拷贝是一个int元素地址
{//code
}void test2(int *arr[20])//20写与不写都行,C依旧会将它忽略
{//code
}
void test2(int **arr)//也可以,传过来的arr2的拷贝是一个int*元素的地址
{//code
}int main()
{int arr[10] = {0};int *arr2[20] = {0};test(arr1);test2(arr2);
}

(2)二维数组传参

void test(int arr[3][5])//可以使用,不过3会被忽略
{//code
}
void test(int arr[][])//不可以使用,5必须留下来
{//code
}
void test(int arr[][5])//可以使用
{//code
}
//二维数组传参,函数形参的设计只能省略第一个[]的数字。
//对一个二维数组,可以不知道有多少行,但是必须知道一行多少元素。void test(int *arr)//不行,类型不匹配,拷贝过来的参数是一个指向一维数组的指针,而这个参数仅仅是一个一维指针
{//code
}
void test(int* arr[5])//不行,这是一个指针数组,根本没有关系 
{//code
}
void test(int (*arr)[5])//可以这么写,指针类型匹配了
{//code
}
void test(int **arr)//不行,指针类型不匹配
{//code
}int main()
{int arr[3][5] = {0};test(arr);
}
//使用二维数组指针(深刻理解)
void print(int(*p)[20], int x, int y)
{//二维数组的名字就是首元素的地址,其地址就是第一行数组的地址,也就是指向一维数组类型的指针,因此不能写形参为int**//又因为一维数组的整体地址&arr和其首元素地址&arr[0]起始位置相同,故从值来看是一样的,但是两者的指针类型完全不同for (int i = 0; i < x; i++){for (int j = 0; j < y; j++){printf("%d", *(* (p + i) + j));//得到数组名,利用i得到每一行的数组名,利用j得到某一行的每一列的元素地址}}
}
int main()
{int arr[10][20] = { {1, 2, 3}, {2, 3, 4} };print(arr, 10, 20);return 0;
}

(3)一级指针传参

#include <stdio.h>
void print(int *p, int sz)
{int i = 0;for(i=0; i<sz; i++){printf("%d\n", *(p+i));}
}
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9};int *p = arr;int sz = sizeof(arr)/sizeof(arr[0]);//一级指针p,传给函数print(p, sz);return 0;
}

(4)二级指针传参

#include <stdio.h>
void test(int** ptr)
{printf("num = %d\n", **ptr);
}
int main()
{int n = 10;int*p = &n;int **pp = &p;test(pp);test(&p);return 0;
}

(5)总结

指针的类型一定要匹配好,尽管类型不匹配的时候依旧可以进行传参(因为所有地址在同一个平台都是一样大小的,只是存储一个地址,理论上用什么类型的指针都可以存储),但是在后续使用指针的时候(解引用指针)就会发生错误,指针会根据指针类型访问不同大小的内存

5. 函数指针

  • 整型指针int*
  • 字符指针char*
  • 指向数组int arr[10]的数组指针int (*p)[10]
  • 指向函数function()的函数指针int (*pf)(int, int) = function(或者int (*pf)(int, int) = &function)其中函数function()是一个有两个int参数,返回值为int的函数

(1)函数指针

  • 对于函数function(),其函数指针类型为【返回值 (*指针名) (参数类型的列表)】

  • 若想使用这个函数就要进行解引用,使用【(* pf)(参数列表)】或者【pf(参数列表)】都可以。编译器在处理的时候,没有 * 也行,但是要用 * 就一定要加括号

    • 尽管这样很矛盾,但是调用函数指针时,使用*pf和pf是一样的,即:函数名==函数的地址,而(&函数名)==函数的地址
    • 若是理解pf为指针,则*pf变成函数名字,*pf()就相当于function()
    • 若是理解pf为函数名,则pf本身就是函数的名字,pf()就相当于function()
    • C允许这两种写法,认为两种都合理
//例子
char* test(int c, float* pf)
{//某些代码
}
int main()
{char* (*pt)(int, float*)pf = test;test(参数列表)return 0;
}

(2)有关函数指针的一些有趣的代码

//代码1
(*(  void (*)()  )0)();//从最里面开始理解void(*)()是一个指向“返回值为空,参数列表为空”函数的函数指针
//然后将0的int类型强制转化为函数指针类型,于是0成了一个函数指针类型的地址
//再解引用0这个地址,得到0地址处的函数,然后使用这个函数
//代码2
void (*  signal(int , void(*)(int))  )(int);//等价代码如下
//typedef void(*pfun_t)(int);//注意pfun_t是一个和void(*)(int)同类型名,将pfun_t放在*旁边是为了指明pfun_t是一个指针而已,这只是语法形式要求
//pfun_t signal(int, pfun_t);//因此有一个简化代码的技巧就是使用typedef

这两段代码来自于《C陷阱与缺陷》,是本出名的C语言书籍

6. 函数指针数组

(1)使用例子

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a*b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;do{printf("*************************\n");printf(" 1:add             2:sub \n");printf(" 3:mul             4:div \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);switch (input){case 1:printf("输入操作数:");scanf("%d %d", &x, &y);ret = add(x, y);printf("ret = %d\n", ret);break;case 2:printf("输入操作数:");scanf("%d %d", &x, &y);ret = sub(x, y);printf("ret = %d\n", ret);break;case 3:printf("输入操作数:");scanf("%d %d", &x, &y);ret = mul(x, y);printf("ret = %d\n", ret);break;case 4:printf("输入操作数:");scanf("%d %d", &x, &y);ret = div(x, y);printf("ret = %d\n", ret);break;case 0:printf("退出程序\n");breark;default:printf("选择错误\n");break;}} while (input);return 0
}

(2)改良后

#include <stdio.h>
int add(int a, int b)
{return a + b;
}
int sub(int a, int b)
{return a - b;
}
int mul(int a, int b)
{return a*b;
}
int div(int a, int b)
{return a / b;
}
int main()
{int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表,即函数指针数组,这里的0(或者写NULL)起到占位的作用,理论上放什么都行,只要后续处理好就行…while (input){printf("*************************\n");printf(" 1:add           2:sub \n");printf(" 3:mul           4:div \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);if ((input <= 4) && (input >= 1)){printf("输入操作数:");scanf("%d %d", &x, &y);ret = (*p[input])(x, y);}else{printf("输入有误\n");}printf("ret = %d\n", ret);}return 0;
}
//当计算器后续需要加入更多的运算函数时,那么使用开关语句就会显得冗长,但是使用函数指针数组就不会有这个问题,这将会大大缩减代码。但是使用函数指针也具有有缺点,它只能存放同样函数签名(函数签名定义了函数的输入和输出,即:函数签名==参数+返回值)的函数

(3)转移表的概念

像类似上面使用函数指针数组的方法就叫做转移表,具有一种跳转使用函数的效果。即“函数指针数组”==“转移表”

7. 指向函数指针数组的指针

void test(const char* str)
{printf("%s\n", str);
}
int main()
{//声明函数指针pfun,并且进行初始化void (*pfun)(const char*) = test;//声明一个函数指针的数组pfunArrvoid (*pfunArr[5])(const char* str) = { pfun };pfunArr[0] = test;//指向函数指针数组pfunArr的指针ppfunArrvoid (*(*ppfunArr)[5])(const char*) = &pfunArr;return 0;
}
//*代表ppfunArr是指针,[]代表这个指针指向一个内含5元素的数组,而每个元素的类型都是void (*)(const char*)
//因此按照运算符的顺序来解读是比较快的    

8. 回调函数

  • 回调函数就是一个通过函数指针调用的函数。
  • 如果你把函数的指针(地址)作为参数传递给另外一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
  • 回调函数不是由该函数的实现方式直接调用,而是在特定的事件或条件发生时由另外一方调用的,用于对该事件或条件进行响应

(1)例子一:使用qsort

①前要:C库函数qsort能对数组进行排序

void qsort(void *base,//指向了待排序数组的第一个元素 size_t nitems,//排序的元素个数size_t size,//每个元素的大小,单位是字节int (*compar)(const void*, const void*)//指向一个函数,这个函数可以比较两个元素的大小);//其底层是使用快速排序的方法来排序的,依靠compar指向的不同函数内部不同的比较,可以解决不同类型的数据快速排序

②使用qsort:对数组进行排序

#include <stdio.h>
#include <stdlib.h>
//qosrt函数的使用者得实现一个比较函数
int int_cmp(const void * p1, const void * p2)
{return ( *(int*)p1 - *(int*)p2 );//注意不能直接解引用void指针,另外如果倒过来就是逆序输出了
}
int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };int i = 0;qsort(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++){printf( "%d ", arr[i]);}printf("\n");return 0;
}

(2)例子二:模拟实现类似qsort函数的bubble函数(底层采用冒泡函数)

#include <stdio.h>
int int_cmp(const void * p1, const void * p2)//其中一个比较函数,这个是整型比较,是用户决定这个函数应该如何编写
{return (*(int*)p1 - *(int*)p2);//不过注意void不能直接解引用!!!
}void _swap(void *p1, void * p2, int size)//其中一个排序方法,这个是排序是冒泡排序,可以由开发者决定底层排序的方法,在qsort中使用的底层函数是快排
{int i = 0;for (i = 0; i< size; i++)//之所以这么做,是因为没有办法预测有多少个字节,只能通过一个一个字节进行交换,最后所有字节进行交换,即两个数据进行了交换{char tmp = *((char*)p1 + i);*((char*)p1 + i) = *((char*)p2 + i);*((char*)p2 + i) = tmp;}
}void bubble(void *base, int count, int size, int(*cmp )(void*, void*))//相当于qsort,但是实现逻辑不仅仅是快速排序,内部的_swap函数也可能是其他的排序算法,cmp函数可能比较不同类型的数据。     注意base是void*类型,写int*会写死的,只能限定于整型
{int i = 0;int j = 0;for (i = 0; i < count - 1; i++){int flag = 1;//①优化代码,若是没有交换就说明不需要经过排序就是有序的了for (j = 0; j < count - i - 1; j++){if (cmp ((char*) base + j * size, (char*)base + (j + 1) * size) > 0)//比较函数,这里改成(char*)就可以利用size适应不同的字节{flag = 0;_swap((char*)base + j * size, (char*)base + (j + 1) * size, size);//排序函数,这里改成(char*)就可以利用size适应不同的字节}if(flag == 1){break;}}}
}int main()
{int arr[] = { 1, 3, 5, 7, 9, 2, 4, 6, 8, 0 };//char *arr[] = {"aaaa","dddd","cccc","bbbb"};int i = 0;bubble(arr, sizeof(arr) / sizeof(arr[0]), sizeof (int), int_cmp);for (i = 0; i< sizeof(arr) / sizeof(arr[0]); i++){printf( "%d ", arr[i]);}printf("\n");return 0;
}

注意我们不是在模拟qsort函数,而是作一个类似qsort函数的“冒泡排序通用的bubble函数”

相关文章:

C语言深入知识——(2)指针的深入理解

1、字符指针 &#xff08;1&#xff09;字符指针的普通用法 char a A; char* pa &a;但是一般来说字符指针很少这么用……更多是拿来存储一个字符串 &#xff08;2&#xff09;字符串的两种存储以及区别 现在有了两种存储数组的方法 ①一个是使用char类型数组存储②另外…...

Git使用笔记

分支branch切换到另一个分支git checkout 你要切换到的分支的名字git checkout master将本地的这个分支branch1和gitee上的branch1进行合并&#xff08;本地的branch1有的&#xff0c;gitee上branch1没有的增加上去&#xff09;git merge branch1git merge 分支的名字查看本地是…...

数据库管理-第五十八期 倒腾PDB(20230226)

数据库管理 2023-02-26第五十八期 倒腾PDB1 克隆本地PDB2 没开归档总结第五十八期 倒腾PDB 其实本周过的不大好&#xff0c;连着两天熬夜&#xff0c;一次是割接一次是处理ADG备库的异常&#xff0c;其实本周有些内容是以前处理过的问题&#xff0c;到了周末还肚子痛。哎… 1…...

我看谁还敢说不懂git

文章目录一、Git介绍1.1、Git的作用1.2、Git的理念1.3、Git的特点1.4、Git对比SVN二、Git的概念2.1、Git基础概念三、Git的基本操作3.1、使用Git管理一个代码仓库的流程3.2、Git常用命令介绍四、Git状态的变化五、Git安装和配置5.1、Git的安装5.2、Git的配置六、Git的高级操作6…...

Scratch少儿编程案例-算法练习-实现加减乘除练习题

专栏分享 点击跳转=>Unity3D特效百例点击跳转=>案例项目实战源码点击跳转=>游戏脚本-辅助自动化点击跳转=>Android控件全解手册点击跳转=>Scratch编程案例👉关于作者...

【离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计】

离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计离线数仓-9-数据仓库开发DWS层设计要点-1d/nd/td表设计一、DWS层设计要点二、DWS层设计分析 - 1d/nd1.DWS层设计一&#xff1a;不考虑用户维度2.DWS层设计二&#xff1a;考虑用户维度2.DWS层设计三 &#xff1a;考虑用户商…...

python网络数据获取

文章目录1网络爬虫2网络爬虫的类型2.1通用网络爬虫2.1.12.1.22.2聚焦网络爬虫2.2.1 基于内容评价的爬行策略2.2.2 基于链接结构的爬行策略2.2.3基于增强学习的爬行策略2.2.4基于语境图的爬行策略2.3增量式网络爬虫深层网页爬虫3网络爬虫基本架构3.1URL管理模块3.2网页下载模块3…...

[Datawhale][CS224W]图机器学习(六)

目录一、简介二、概述三、算法四、PageRank的缺点五、Python实现迭代法参考文献一、简介 PageRank&#xff0c;又称网页排名、谷歌左侧排名、PR&#xff0c;是Google公司所使用的对其搜索引擎搜索结果中的网页进行排名的一种算法。 佩奇排名本质上是一种以网页之间的超链接个…...

aws ecr 使用golang实现的简单镜像转换工具

https://pkg.go.dev/github.com/docker/docker/client#section-readme 通过golang实现一个简单的镜像下载工具 总体步骤 启动一台海外区域的ec2实例安装docker和awscli配置凭证访问国内ecr仓库编写web服务实现镜像转换和自动推送 安装docker和awscli sudo yum remove awsc…...

【20230225】【剑指1】分治算法(中等)

1.重建二叉树class Solution { public:TreeNode* traversal(vector<int>& preorder,vector<int>& inorder){if(preorder.size()0) return NULL;int rootValuepreorder.front();TreeNode* rootnew TreeNode(rootValue);//int rootValuepreorder[0];if(preo…...

「JVM 高效并发」Java 线程

进程是资源分配&#xff08;内存地址、文件 I/O 等&#xff09;的基本单位&#xff0c;线程是执行调度&#xff08;处理器资源调度&#xff09;的基本单位&#xff1b; Loom 项目若成功为 Java 引入纤程&#xff08;Fiber&#xff09;&#xff0c;则线程的执行调度单位可能变为…...

ADAS-可见光相机之Cmos Image Sensor

引言 “ 可见光相机在日常生活、工业生产、智能制造等应用有着重要的作用。在ADAS中更是扮演着重要的角色&#xff0c;如tesla model系列全车身10多个相机&#xff0c;不断感知周围世界。本文着重讲解下可见光相机中的CIS(CMOS Image Sensor)。” 定义 光是一种电磁波&…...

【ESP 保姆级教程】玩转emqx MQTT篇③ ——封装 EmqxIoTSDK,快速在项目集成

忘记过去,超越自己 ❤️ 博客主页 单片机菜鸟哥,一个野生非专业硬件IOT爱好者 ❤️❤️ 本篇创建记录 2023-02-26 ❤️❤️ 本篇更新记录 2023-02-26 ❤️🎉 欢迎关注 🔎点赞 👍收藏 ⭐️留言📝🙏 此博客均由博主单独编写,不存在任何商业团队运营,如发现错误,请…...

Python自动化测试面试题-编程篇

前言 随着行业的发展&#xff0c;编程能力逐渐成为软件测试从业人员的一项基本能力。因此在笔试和面试中常常会有一定量的编码题&#xff0c;主要考察以下几点。 基本编码能力及思维逻辑基本数据结构&#xff08;顺序表、链表、队列、栈、二叉树&#xff09;基本算法&#xf…...

CIT 594 Module 7 Programming AssignmentCSV Slicer

CIT 594 Module 7 Programming Assignment CSV Slicer In this assignment you will read files in a format known as “comma separated values” (CSV), interpret the formatting and output the content in the structure represented by the file. Q1703105484 Learning …...

链路追踪——【Brave】第一遍小结

前言 微服务链路追踪系列博客&#xff0c;后续可能会涉及到Brave、Zipkin、Sleuth内容的梳理。 Brave 何为Brave&#xff1f; github地址&#xff1a;https://github.com/openzipkin/brave Brave是一个分布式追踪埋点库。 #mermaid-svg-riwF9nbu1AldDJ7P {font-family:"…...

Vision Transformer(ViT)

1. 概述 Transformer[1]是Google在2017年提出的一种Seq2Seq结构的语言模型&#xff0c;在Transformer中首次使用Self-Atttention机制完全代替了基于RNN的模型结构&#xff0c;使得模型可以并行化训练&#xff0c;同时解决了在基于RNN模型中出现了长距离依赖问题&#xff0c;因…...

104-JVM优化

JVM优化为什么要学习JVM优化&#xff1a; 1&#xff1a;深入地理解 Java 这门语言 我们常用的布尔型 Boolean&#xff0c;我们都知道它有两个值&#xff0c;true 和 false&#xff0c;但你们知道其实在运行时&#xff0c;Java 虚拟机是 没有布尔型 Boolean 这种类型的&#x…...

QML 颜色表示法

作者: 一去、二三里 个人微信号: iwaleon 微信公众号: 高效程序员 如果你经常需要美化样式(最常见的有:文本色、背景色、边框色、阴影色等),那一定离不开颜色。而在 QML 中,颜色的表示方法有多种:颜色名、十六进制颜色值、颜色相关的函数,一起来学习一下吧。 老规矩…...

基础数据结构--线段树(Python版本)

文章目录前言特点操作数据存储updateLazy下移查询实现前言 月末了&#xff0c;划个水&#xff0c;赶一下指标&#xff08;更新一些活跃值&#xff0c;狗头&#xff09; 本文主要是关于线段树的内容。这个线段树的话&#xff0c;主要是适合求解我们一个数组的一些区间的问题&am…...

【micropython】SPI触摸屏开发

背景&#xff1a;最近买了几块ESP32模块&#xff0c;看了下mircopython支持还不错&#xff0c;所以买了个SPI触摸屏试试水&#xff0c;记录一下使用过程。硬件相关&#xff1a;SPI触摸屏使用2.4寸屏幕&#xff0c;常见淘宝均可买到&#xff0c;驱动为ILI9341&#xff0c;具体参…...

【云原生】k8s中Pod进阶资源限制与探针

一、Pod 进阶 1、资源限制 当定义 Pod 时可以选择性地为每个容器设定所需要的资源数量。 最常见的可设定资源是 CPU 和内存大小&#xff0c;以及其他类型的资源。 当为 Pod 中的容器指定了 request 资源时&#xff0c;调度器就使用该信息来决定将 Pod 调度到哪个节点上。当还…...

AI - stable-diffusion(AI绘画)的搭建与使用

最近 AI 火的一塌糊涂&#xff0c;除了 ChatGPT 以外&#xff0c;AI 绘画领域也有很大的进步&#xff0c;以下几张图片都是 AI 绘制的&#xff0c;你能看出来么&#xff1f; 一、环境搭建 上面的效果图其实是使用了开源的 AI 绘画项目 stable-diffusion 绘制的&#xff0c;这是…...

应用场景五: 西门子PLC通过Modbus协议连接DCS系统

应用描述&#xff1a; 西门子PLC&#xff08;S7200/300/400/200SMART&#xff09;通过桥接器可以支持ModbusRTU串口和ModbusTCP以太网&#xff08;有线和无线WIFI同时支持&#xff09;两种通讯方式连接DCS系统&#xff0c;不需要编程PLC通讯程序&#xff0c;直接在模块中进行地…...

我继续问了ChatGPT关于SAP顾问职业发展前景的问题,大家感受一下

目录 SAP 顾问 跟其他IT工作收入情况相比是怎么样的&#xff1f; 如何成为SAP FICO 优秀的顾问 要想成为SAP FICO 优秀的顾问 &#xff0c;需要ABA开发技能吗 SAP 顾问中哪个类型收入最多&#xff1f; 中国的ERP软件能够取代SAP吗&#xff1f; 今天我继续撩 ChatGPT。随便问…...

Python小白入门---00开篇介绍(简单了解一下)

Python 小白入门 系列教程 第一部分&#xff1a;Python 基础 介绍 Python 编程语言安装 Python 环境变量和数据类型运算符和表达式控制流程语句函数和模块异常处理 第二部分&#xff1a;Python 标准库和常用模块 Python 标准库简介文本处理和正则表达式文件操作和目录操作时…...

【算法基础】C++STL容器

一、Vector 1. 初始化(定义) (1)vector最基本的初始化: vector <int> a;(2)定义长度为10的vector: vector <int> a(10);(3)定义长度为10的vector,并且把所有元素都初始化为-3: vector <int...

【经典蓝牙】蓝牙 A2DP协议分析

A2DP 介绍 A2DP(Advanced Audio Distribution Profile)是蓝牙高音质音频传输协议&#xff0c; 用于传输单声道&#xff0c; 双声道音乐&#xff08;一般在 A2DP 中用于 stereo 双声道&#xff09; &#xff0c; 典型应用为蓝牙耳机。 A2DP旨在通过蓝牙连接传输高质量的立体声音…...

Objective-C 构造方法的定义和声明规范

总目录 iOS开发笔记目录 从一无所知到入门 文章目录源码中 NSArray 的构造方法与命名规律自定义类的构造方法命名截图代码输出源码中 NSArray 的构造方法与命名规律 interface NSArray<ObjectType> (NSArrayCreation) (instancetype)array;(instancetype)arrayWithObject…...

Matlab图像处理学习笔记

Matlab图像处理 Matlab基础 数组 1、向量 生成方式1: x = [值] x = [1 2 3] % 行向量 y = [4; 5; 6] % 列向量 z = x % 行向量转列向量...

怎么注册公司支付宝账号/seo网站排名优化价格

现在的家庭多多少少都会选择购买一辆汽车&#xff0c;改革开放开始我国的城镇化建设已经得到了很大的加强&#xff0c;对于农村地区的建设我们也要有着很大的发展。而和家电下乡同样的就是汽车下乡了&#xff0c;明年开始新一轮的汽车下乡又要来了&#xff0c;农民买车补贴金额…...

全国做膏药的网站有多少家呢/如何开发一款app软件

在今天的Build大会上&#xff0c;微软宣布发布一款同时支持Windows、Mac OS X和Linux平台的原生Visual Studio应用——Visual Studio Code&#xff0c;旨在为所有开发者提供一款专注于代码本身的免费的编辑器。它虽然是Visual Studio家族的一员&#xff0c;但它与传统VS IDE的功…...

wordpress主题metro/互联网宣传方式有哪些

伺服电机控制方式有脉冲、模拟量和通讯这三种&#xff0c;在不同的应用场景下&#xff0c;我们该如何选择伺服电机的控制方式呢&#xff1f;记得收藏关注呀&#xff01;万一你找不到我了呢0 1伺服电机脉冲控制方式在一些小型电机设备&#xff0c;选用脉冲控制实现电机的定位&am…...

wordpress评论表情插件/网站seo技术能不能赚钱

前言&#xff1a;通过使用视图&#xff08;views&#xff09;可以获得其他实现了Collection接口和Map接口的对象。映射类的keySet方法就是一个示例。keySet方法返回一个实现Set接口的类对象&#xff0c;这个类的方法对原映射进行操作。这种集合称为视图。 1、轻量级集合包装器…...

商城网站建设流程图/如何查询百度收录情况

语法 switch(n) { case 1:执行代码块 1break; case 2:执行代码块 2break; default:n 与 case 1 和 case 2 不同时执行的代码 }工作原理&#xff1a;首先设置表达式 n&#xff08;通常是一个变量&#xff09;。随后表达式的值会与结构中的每个 case 的值做比较。如果存在匹配&am…...

北京的广告公司网站建设/世界最新新闻

1 web2 查看网页源码&#xff0c;看到flag。 ———————————— 2 计算器 打开检查&#xff0c;找到对应输入答案的源码 <input type"text" class"input" maxlength"1">可以看到maxlength“1”&#xff0c;表示表单中输入数据最…...