【C語言】深度剖析指針(三):回調機制、通用排序與數組指針邏輯

文章目錄

  • 一、回調函數:通過函數指針實現靈活調用
    • 1.1 什么是回調函數?
    • 1.2 回調函數的實際應用:簡化計算器代碼
  • 二、qsort函數
    • 2.1 qsort函數的參數說明
    • 2.2 使用qsort排序整型數據
    • 2.3 使用qsort排序結構體數據
      • 示例:學生信息排序
    • 2.4 qsort函數的模擬實現:用冒泡排序理解通用排序
      • 2.4.1 模擬實現思路
        • 1. `main()`主程序:
        • 2. `bubble_sort()`
        • 3.`swap():`
      • 2.4.2 模擬實現代碼
  • 三、`sizeof`與`strlen`
    • 3.1 sizeof:計算內存大小
    • 3.2 strlen:計算字符串長度
    • 3.3 核心區別對比
  • 四、數組與指針筆試題解析
    • 4.1 一維數組:數組名
    • 4.2 字符數組:`\0`
      • 代碼1:無`\0`的字符數組(`sizeof`解析)
      • 代碼2:無`\0`的字符數組(`strlen`解析)
      • 代碼3:含`\0`的字符數組(字符串)
      • 代碼4:字符指針指向常量字符串
    • 4.3 二維數組:行地址與元素地址的嵌套
    • 4.4 指針運算
      • 題目1:數組地址的跨越
      • 題目2:結構體指針的算術運算
      • 題目3:逗號表達式與數組初始化
      • 題目4:二維數組與指針偏移差異
      • 題目5:數組地址與元素地址的轉換
      • 題目6:指針數組的偏移
      • 題目7:三級指針的嵌套訪問

一、回調函數:通過函數指針實現靈活調用

1.1 什么是回調函數?

回調函數是一種特殊的函數調用方式:當一個函數的指針(地址)作為參數傳遞給另一個函數,并且這個指針在被調用時指向的函數被執行,那么這個被執行的函數就稱為回調函數

簡單來說,回調函數不是由函數本身直接調用,而是在特定條件下由其他函數通過指針觸發,用于響應特定事件或完成特定邏輯

1.2 回調函數的實際應用:簡化計算器代碼

以計算器程序為例,傳統實現中,switch語句需要重復處理輸入操作數、調用計算函數、輸出結果等邏輯,代碼冗余度高。

改造前(傳統寫法)

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("******************");printf(" ******0:退出 *****");printf(" ******1:add *****");printf(" ******2:sub *****");printf(" ******3:mul *****");printf(" ******4:div *****");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");break;}} while (input != 0);return 0;
}

我們發現每個case下都有大量的重復語句,可以把這些語句封裝成函數calc,提高代碼的可利用性。但是每個case下調用的函數不一樣,不能直接用一個函數籠統表示。這就需要利用函數指針,把需要調用的函數作為參數傳給calc

改造后(回調函數版)

// 定義通用計算函數,接收函數指針作為參數
void calc(int(*pf)(int, int)) {int x, y, ret;printf("輸入操作數:");scanf("%d %d", &x, &y);ret = pf(x, y);  // 通過函數指針調用回調函數printf("ret = %d\n", ret);
}// 主函數中直接通過函數名調用
case 1: calc(add); break;   
case 2: calc(sub); break;  
case 2: calc(mul); break;  
case 2: calc(div); break;  

優勢:將重復的輸入輸出邏輯封裝到calc函數中,通過傳遞不同的計算函數指針(add/sub等)實現靈活調用,減少代碼冗余,提高可維護性。

二、qsort函數

qsort是C語言標準庫中的快速排序函數,支持對任意類型的數據進行排序(整型、結構體等),其核心是通過回調函數定義排序規則。

2.1 qsort函數的參數說明

void qsort(void* base,        // 待排序數組的起始地址size_t nmemb,      // 數組元素個數size_t size,       // 每個元素的大小(單位:字節)int (*compar)(const void*, const void*)  // 比較函數(回調函數)
);
  • 比較函數:需用戶自定義,返回值規則:
    • p1 > p2,返回正數;
    • p1 == p2,返回0;
    • p1 < p2,返回負數。

注意:

  • 使用qsort()要先包含頭文件#include<stdlib.h>
  • void*是無具體類型的指針,不可以直接解引用,也不可以進行±整數的運算,必須先強制類型轉換

2.2 使用qsort排序整型數據

#include <stdio.h>
#include <stdlib.h>  // qsort所在頭文件int int_cmp(const void* p1, const void* p2) {// 將void*轉換為int*,再解引用獲取值return *(int*)p1 - *(int*)p2;
}int main() {int arr[] = {1, 3, 5, 7, 9, 2, 4, 6, 8, 0};int n = sizeof(arr) / sizeof(arr[0]);qsort(arr, n, sizeof(int), int_cmp);for (int i = 0; i < n; i++) {printf("%d ", arr[i]);  // 輸出:0 1 2 3 4 5 6 7 8 9}return 0;
}

2.3 使用qsort排序結構體數據

結構體包含多種類型成員(如姓名、年齡),可通過不同的比較函數實現按不同字段排序。

示例:學生信息排序

#include <stdio.h>
#include <stdlib.h>
#include <string.h>  // strcmp所在頭文件struct stu
{char name[20];int age;
};int cmp_stu_by_name(const void* p1, const void* p2)
{return strcmp(((struct stu*)p1)->name, ((struct stu*)p2)->name);
}int cmp_stu_by_age(const void* p1, const void* p2)
{return ((struct stu*)p1)->age - ((struct stu*)p2)->age;
}int main()
{struct stu arr[3] = { {"rare",20},{"daisy",18}, {"sivan",22} };int sz = sizeof(arr) / sizeof(arr[0]);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_name);qsort(arr, sz, sizeof(arr[0]), cmp_stu_by_age);return 0;
}

在這里插入圖片描述

注意:

  • 比較字符串大小可以用strcmp()函數,其所在的頭文件是string.h
  • strcmp()是按照對應字符的ASCII碼值比較的,不是比較長度。例如:"abq">"abcd"
  • 結構體中指針的訪問要用->

2.4 qsort函數的模擬實現:用冒泡排序理解通用排序

qsort的核心是通用性(支持任意類型),其底層可基于冒泡、快速排序等算法實現。以下用冒泡排序模擬qsort的邏輯。

2.4.1 模擬實現思路

1. main()主程序:
  • 創建一個無序數組
  • 計算數組元素個數sz
  • 調用bubble_sort()函數
2. bubble_sort()
  • qsort()四個參數:
    • 首個地址void* base
    • 元素個數size_t sz
    • 每個元素大小size_t width
    • 自定義比較函數int(*cmp)(const void* p1 , const void* p2)
  • 調用cmp比較大小:
    • 將首個元素地址轉為char*類型,因為char大小為1字節,方便不同類型傳入,進行比較。
    • 這里相當于“指針 ± 整數”,指針類型是char*,所以 ± 整數都是跳過整數個字節,j*width就是跳過一個元素的長度。因此這里傳入的是第jj+1個元素進行比較。
  • 調用swap 升序排序,cmp()>0則交換。這里原理同上,傳入第jj+1個元素的地址。
3.swap():
  • 逐字節進行交換,循環次數就是width,每個元素的大小。

2.4.2 模擬實現代碼

#include <stdio.h>
int cmp_int(const void* p1, const void* p2)
{return *((int*)p1) - *((int*)p2);
}void swap(char* buf1, char* buf2, size_t width)
{for (int i = 0; i < width; i++){char temp = *buf1;*buf1 = *buf2;*buf2 = temp;buf1++;buf2++;//逐字節交換}
}void bubble_sort(void* base,size_t sz,size_t width,int(*cmp)(const void* p1 ,const void* p2))
{for (int i = 0; i < sz - 1; i++){for (int j = 0;j < sz - 1 - i;j++){if ( cmp( (char*)base + j * width,(char*)base + ( j + 1 )*width   )> 0){swap((char*)base + j * width, (char*)base + (j + 1) * width,width);}}}
}int main()
{int arr[10] = { 1,2,7,6,9,8,10,6,4,9 };int sz = sizeof(arr) / sizeof(arr[0]);bubble_sort(arr,sz,sizeof(arr[0]),cmp_int);for (size_t i = 0; i < 10; i++){printf("%d ", arr[i]);}return 0;
}

三、sizeofstrlen

3.1 sizeof:計算內存大小

sizeof是C語言的操作符,其核心功能是計算變量或類型所占用的內存空間大小(單位:字節)。它的特點是:

  • 只關注內存占用,不關心內存中存儲的數據
  • 操作數可以是變量,也可以是類型(如sizeof(int));
  • 對于數組名,sizeof(數組名)計算的是整個數組的大小(其他情況數組名通常表示首元素地址)。

示例代碼

#include <stdio.h>
int main() {int a = 10;printf("%zd\n", sizeof(a));    // 結果:4(int類型占4字節)printf("%zd\n", sizeof a);     // 結果:4(變量名可省略括號)printf("%zd\n", sizeof(int));  // 結果:4(int類型的大小)return 0;
}

3.2 strlen:計算字符串長度

strlen是C語言標準庫函數(聲明于<string.h>),功能是計算字符串的長度,其核心邏輯是:

  • 從傳入的地址開始,逐個字符計數,直到遇到\0停止\0不計入長度);
  • 若字符串中沒有\0,會越界查找,導致結果未定義(UB)。

示例代碼

#include <stdio.h>
#include <string.h>
int main() {char arr1[3] = {'a', 'b', 'c'};  // 無\0char arr2[] = "abc";             // 隱含\0printf("%d\n", strlen(arr1));    // 結果:隨機值(越界查找)printf("%d\n", strlen(arr2));    // 結果:3(遇到\0停止)return 0;
}

3.3 核心區別對比

特性sizeofstrlen
本質操作符(編譯期計算)庫函數(運行期計算)
功能計算內存空間大小(字節)計算字符串長度(\0前字符數)
關注內容僅關心內存占用,與數據無關依賴\0結束符,無\0則越界
參數類型變量、類型、表達式等僅接受char*(字符串首地址)
返回值size_t(無符號整數)size_t(無符號整數)

sizeof()不會計算括號內的表達式,而strlen()會計算。

int main()
{int a = 0;short b = 4;printf("%d\n",sizeof(b = b + a));//輸出 2 ,取決于 b的類型printf("%d\n",b);//輸出4return 0;
}

四、數組與指針筆試題解析

4.1 一維數組:數組名

代碼示例

int a[] = {1,2,3,4};
printf("%d\n", sizeof(a));        // 16
printf("%d\n", sizeof(a+0));      // 4/8(首元素地址,指針大小)
printf("%d\n", sizeof(*a));       // 4(首元素是int,占4字節)
printf("%d\n", sizeof(a+1));      // 4/8(第二個元素地址,指針大小)
printf("%d\n", sizeof(a[1]));     // 4
printf("%d\n", sizeof(&a));       // 4/8(數組地址,指針大小)
printf("%d\n", sizeof(*&a));      // 16(*&a等價于a,整個數組大小)
printf("%d\n", sizeof(&a+1));     // 4/8(跳過整個數組的地址,指針大小)
printf("%d\n", sizeof(&a[0]));    // 4/8(首元素地址,指針大小)
printf("%d\n", sizeof(&a[0]+1));  // 4/8(第二個元素地址,指針大小)

關鍵結論

  • 數組名asizeof(a)&a中表示整個數組,其他情況均表示首元素地址
  • 指針運算(如a+1)的結果仍是指針,大小為4/8字節。

4.2 字符數組:\0

字符數組的核心陷阱在于是否包含\0,這直接影響strlen的結果。

代碼1:無\0的字符數組(sizeof解析)

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));       // 6(6個char,每個1字節)
printf("%d\n", sizeof(arr+0));     // 4/8
printf("%d\n", sizeof(*arr));      // 1(首元素是char)
printf("%d\n", sizeof(&arr));      // 4/8
printf("%d\n", sizeof(&arr+1));    // 4/8

代碼2:無\0的字符數組(strlen解析)

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", strlen(arr));       // 結果:隨機值(無\0,越界查找)
printf("%d\n", strlen(arr+0));     // 結果:隨機值(同arr,首元素地址)
printf("%d\n", strlen(*arr));       
// 錯誤(*arr是'a',ASCII值97,相當于把 97作為地址傳給strlen,視為地址越界)

代碼3:含\0的字符數組(字符串)

char arr[] = "abcdef";             // 隱含'\0',共7個元素
printf("%d\n", sizeof(arr));       // 結果:7(包含'\0')
printf("%d\n", strlen(arr));       // 結果:6('\0'前共6個字符)

代碼4:字符指針指向常量字符串

char *p = "abcdef";  // p存儲字符串首地址
printf("%d\n", sizeof(p));        // 結果:4/8(指針大小)
printf("%d\n", strlen(p));        // 結果:6(字符串長度)
printf("%d\n", strlen(p+1));      // 結果:5(從'b'開始計數)

4.3 二維數組:行地址與元素地址的嵌套

代碼示例

int a[3][4] = {0};  // 3行4列的二維數組
printf("%d\n", sizeof(a));        // 結果:48(3×4×4字節,整個數組大小)
printf("%d\n", sizeof(a[0]));     // 結果:16(第0行數組大小:4×4字節)
printf("%d\n", sizeof(a[0]+1));   // 結果:4/8(第0行第1列元素地址)
printf("%d\n", sizeof(a+1));      // 結果:4/8(第1行的地址,行指針)
printf("%d\n", sizeof(*(a+1)));   // 結果:16(第1行數組大小)
printf("%d\n", sizeof(*a));       // 結果:16(第0行數組大小,*a等價于a[0])

核心邏輯

  • 二維數組a可視為“數組的數組”,a[i]是第i行的一維數組名。
  • a表示首行地址(行指針,類型為int(*)[4]),a+1指向第1行。

4.4 指針運算

題目1:數組地址的跨越

int a[5] = {1,2,3,4,5};
int *ptr = (int*)(&a + 1);  // &a是數組地址,+1跳過整個數組
printf("%d,%d", *(a+1), *(ptr-1));  // 結果:2,5
  • a+1指向第1個元素(值2),ptr-1指向數組最后一個元素(值5)。

題目2:結構體指針的算術運算

假設結構體大小為20字節

struct Test {int Num; char *pcName; short sDate;char cha[2]; short sBa[4];
};
struct Test *p = (struct Test*)0x100000; printf("%p\n", p + 0x1);       // 結果:0x100014(+20字節,指針按結構體大小偏移)
printf("%p\n", (unsigned long)p + 0x1);  // 結果:0x100001(整數+1)
printf("%p\n", (unsigned int*)p + 0x1);  // 結果:0x100004(+4字節,按int*偏移)

題目3:逗號表達式與數組初始化

int a[3][2] = { (0,1), (2,3), (4,5) };  // 逗號表達式取右值,等價于{1,3,5}
int *p = a[0];  // p指向第0行第0列
printf("%d", p[0]);  // 結果:1

注意:

  • 二維數組初始化要用{{},{},{}}!!!
  • 第一行相當于三個逗號表達式(依次執行每個表達式,結果為最后一個表達式的值),所以這里只初始化了三個元素,分別是1,3,5.
13
50
00

題目4:二維數組與指針偏移差異

x86環境下:

int a[5][5];
int(*p)[4] ;
p = a;  //類型差異,會發出警告,不影響運行
printf("%p %d", &p[4][2] - &a[4][2] , &p[4][2] - &a[4][2]);  
// 結果:fffffffc  -4

在這里插入圖片描述

  • 二維數組雖然以多行多列的表格形式理解起來更直觀,但其實在內存中也是連續存儲的,相當于一行多列的表格。
  • p[4][2]==*(*(p+4)+2) p指向元素個數為4的數組,p+整數 跳過一個數組的大小,也就是4個整型,16字節。
  • 根據圖示找到p[4][2]的位置,與a[4][2]做差,得到其中元素個數,%d用于打印有符號整數,結果為-4.
  • 內存中以補碼的形式存儲(x86):
-4 原碼:1000 0000 0000 0000 0000 0000 0000 0100
-4 補碼:1111 1111 1111 1111 1111 1111 1111 1100
十六進制:f    f    f    f    f    f    f    c
  • 因此%p打印結果:fffffffc
  • p只計算了指針偏移量,沒有訪問內容,所以不會造成野指針問題

題目5:數組地址與元素地址的轉換

int aa[2][5] = {1,2,3,4,5,6,7,8,9,10};
int *ptr1 = (int*)(&aa + 1);  // 跳過整個數組,指向數組后地址
int *ptr2 = (int*)(*(aa + 1));  
//aa是首元素地址,也就是第0行地址, +1跳過1行,等價于aa[1],指向第1行首元素
printf("%d,%d", *(ptr1-1), *(ptr2-1));  // 結果:10,5

題目6:指針數組的偏移

char *a[] = {"work","at","alibaba"};
//a 是指針數組,每個元素是char*類型 ,每個元素指向一個字符串
char **pa = a;  // pa指向指針數組首元素
pa++;  // 指向第二個元素("at")
printf("%s\n", *pa);  // 結果:at

在這里插入圖片描述

題目7:三級指針的嵌套訪問

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);    // 結果:ST
printf("%s\n", cpp[-1][-1]+1); // 結果:EW

圖解:
在這里插入圖片描述

printf("%s\n", **++cpp);      

在這里插入圖片描述

  • 跳過一個char**,解引用兩次得到是P的地址,%s打印完整字符串,輸出POINT
printf("%s\n", *--*++cpp + 3);   

在這里插入圖片描述

  • 第一次打印的++cpp會改變cpp指向的位置
  • ++cpp再跳過一個char**,解引用得到c+1,再自減,向前跳一個char*,再解引用得到E的地址
  • +3,得到E的地址,輸出結果為ER
printf("%s\n", *cpp[-2]+3);    

在這里插入圖片描述

  • 第二次打印的++cpp會改變cpp指向的位置
  • cpp[-2] ==*(cpp-2) cpp向前跳過2個char**,再解引用得到c+3,再解引用得到F的地址
  • +3得到S的地址,輸出結果為ST
printf("%s\n", cpp[-1][-1]+1);

在這里插入圖片描述

  • 第三次打印的cpp[-2]不會改變cpp的值,此時cpp依舊指向c+1
  • cpp[-1]向前跳過1個char**,再解引用得到c+2cpp[-1][-1]再向前跳過1個char*,再解引用得到N的地址
  • +1得到E的地址,輸出結果為EW

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/92006.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/92006.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/92006.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sql調優總結

sql調優 線上發現部分sql查詢時間過長。使用explain觀察是否命中表的索引。未命中索引&#xff0c;使用 TABLE add index 語句添加索引。 除此之外&#xff0c;單個字段命中聯合索引的情況也會導致查詢變慢 針對多個字段的查詢可添加聯合索引。 總結如下慢sql的原因&#xff1a…

如何在nuxt項目中使用axios進行網絡請求?

在 Nuxt 項目中使用 Axios 進行網絡請求有兩種常用方式&#xff1a;一是直接安裝 Axios 并全局配置&#xff0c;二是使用 Nuxt 官方推薦的 nuxtjs/axios 模塊&#xff08;更便捷&#xff09;。以下是詳細步驟&#xff1a; 方法一&#xff1a;使用官方推薦的 nuxtjs/axios 模塊&…

Unity 實現手機端和電腦項目在局域網內通信

電腦端啟動后自動廣播自身存在&#xff0c;手機端啟動后監聽廣播并發現服務器。發現后自動建立 UDP 連接&#xff0c;雙方可互發消息。內置心跳檢測&#xff0c;網絡中斷時會自動檢測并提示斷開using UnityEngine; using System.Net; using System.Net.Sockets; using System.T…

C++_389_定義一個禁用了賦值操作、具有線程同步資源保護的結構體,作為一些回調函數的參數,方便獲取響應操作的結果等信息

/* 回調參數。注意:此結構體禁用了賦值,會編譯報錯 */struct API_CALLBACK_T{public:API_CALLBACK_T(){eRet = e_fail;bWait = true;

uniapp基礎 (一)

目錄 UniApp 是什么&#xff1f;有什么優勢 跨平臺高效開發 Vue.js 技術生態 插件生態豐富 漸進式開發支持 UniApp 跨平臺兼容的實現原理 編譯時轉 運行時適配層 條件編譯 性能優化策略 1.預編譯模 2.原生組件混合渲 3.分包加載 UniApp 的生命周期鉤子有哪些&#x…

【圖像算法 - 10】進階入門:改進 YOLO11 安全帽檢測的關鍵參數與場景適配

一、項目背景與需求 視頻全文介紹 【圖像算法 - 10】進階入門&#xff1a;改進 YOLO11 安全帽檢測的關鍵參數與場景適配今天我們使用深度學習來訓練一個安全帽檢測系統&#xff0c;基于YOLO11的安全帽檢測系統。我們使用了兩萬張圖片的數據集訓練了這次的基于YOLO11的安全帽檢…

【C 學習】04.1-類型轉換浮點數

“知道做不到就是不知道”一、類型轉換1.自動類型轉換&#xff1a;當運算符&#xff08;常見、-、*、/、%&#xff09;兩邊出現不一致的類型時&#xff0c;編譯器會自動轉換成較大的&#xff08;范圍更大&#xff09;類型。從小到大&#xff1a;char-short-int-long-long long;…

基于反事實對比學習的魯棒圖像表征|文獻速遞-醫學影像算法文獻分享

Title題目Robust image representations with counterfactual contrastive learning基于反事實對比學習的魯棒圖像表征01文獻速遞介紹醫學影像中的對比學習已成為利用未標記數據的有效策略。這種自監督學習方法已被證明能顯著提升模型跨領域偏移的泛化能力&#xff0c;并減少訓…

機器學習(5):樸素貝葉斯分類算法

貝葉斯的核心思想就是&#xff0c;誰的概率高就歸為哪一類。貝葉斯推論P(A):先驗概率。即在B事件發生之前&#xff0c;我們對A事件概率的一個判斷。P(A|B)&#xff1a;后驗概率。即在B事件發生之后&#xff0c;我們對A事件概率的重新評估。P(B|A)/P(B)&#xff1a;可能性函數。…

Docker 容器內進行 frp 內網穿透

開始之前需要有一臺可以進行公網訪問的服務器 下載安裝 frp 這個直接到 github 官網就可以下載了 點擊Releases 就可以查看到可以下載的源&#xff0c;根據自己電腦的型號進行選擇就好了。 linux服務器上下載 如果是在linux的服務器上的話可以直接通過wget進行下載 例如&a…

復制網頁文字到Word、WPS文字?選中后直接拖放

要把網頁、PDF或其他應用中的文字內容復制到Word、WPS文字、記事本等&#xff0c;不一定要先復制、再粘貼&#xff0c;也可以選中文字后直接拖動到目標位置即可。多次操作&#xff0c;可以把窗口并排再拖動。如果你經常需要在不同應用之間引用文字&#xff0c;不妨試一試。操作…

Starrocks中的 Query Profile以及explain analyze及trace命令中的區別

背景 本文基于Starrocks 3.5.5 現有公司因為業務的不同&#xff0c;可能會更加關系單個SQL 的RT&#xff0c;因為如果一個SQL的RT比較大的話&#xff0c;影響的就是這個業務&#xff0c;從而影響收入&#xff0c;所以對于這方面我們就比較關心&#xff0c; 而最近在基于Starro…

網絡 —— 筆記本(主機)、主機虛擬機(Windows、Ubuntu)、手機(筆記本熱點),三者進行相互ping通

背景介紹最近在筆記本電腦上的虛擬機(Ubuntu、Windows Server搭配)上部署了"WD"開源手游服務器(舊版本)&#xff0c;手機連接上了筆記本電腦開啟的WIFI熱點&#xff0c;同時手機上安裝了"WD"手游客戶端。于是首先得保證網絡相互暢通才能玩游戲&#xff0c;…

裸露土堆識別準確率↑32%:陌訊多模態融合算法在生態監測的實戰解析

原創聲明本文為原創技術解析文章&#xff0c;涉及技術參數及架構描述均參考《陌訊技術白皮書》&#xff0c;禁止任何形式的轉載與抄襲。一、行業痛點&#xff1a;裸露土堆識別的現實挑戰在生態環境保護、建筑工地監管等場景中&#xff0c;裸露土堆的精準識別是遏制揚塵污染、防…

網站從HTTP升級到HTTPS網址方法

將網站從HTTP升級到HTTPS涉及幾個關鍵步驟&#xff0c;以確保安全連接以及用戶和搜索引擎的平穩過渡。獲取并安裝SSL/TLS證書&#xff1a;1、從CA機構授權提供商Gworg獲取SSL/TLS證書。選項包括域名驗證(DV)、組織驗證(OV)和擴展驗證(EV)證書&#xff0c;驗證嚴格度各不相同&am…

WaitForSingleObject 函數參數影響及信號處理分析

一、第二個參數&#xff08;超時時間&#xff09;的影響 DWORD result WaitForSingleObject(hHandle, 1000);中的第二個參數1000表示等待超時時間為1000毫秒&#xff08;1秒&#xff09;&#xff0c;其核心影響如下&#xff1a; 1. 函數行為控制 立即返回&#xff1a;若對象已…

dbeaver導入數據及配置講解

導入數據教程&#xff1a; 前提.csv文件&#xff1a;且只能導入一個sheet點擊下一步選中導入的.csv文件對應好數據字段和表字段&#xff0c;感覺不需要導入的可以skip配置一下&#xff0c;下面有介紹&#xff1a;以下為你詳細解析這些數據加載相關功能的含義與作用&#xff1a;…

JAVA學習筆記 自增與自減的使用-006

目錄 1 基本概述 2 自增與自減的用法 2.1單獨使用 2.2 參與運算 3 思考與練習 3.1 基礎題 3.2 中等題 3.3 進階題 4 總結 源計劃&#xff1a;我從來不認為自己的成功過程有多心酸&#xff0c;只是心中不懼失敗&#xff0c;能夠承受別人不能接受的失望而已&#xff01;…

從LCM到SomeIP,再到DDS:技術演進與工作原理剖析

文章目錄一、LCM&#xff1a;輕量級通信與編組庫工作原理C 代碼示例局限性二、SomeIP&#xff1a;面向服務的可擴展中間件工作原理C 代碼示例優勢與特點三、DDS&#xff1a;數據分發服務工作原理C 代碼示例優勢與應用場景四、技術演進總結在分布式系統通信領域&#xff0c;技術…

Redis里面什么是sdshdr,可以詳細介紹一下嗎?

文章目錄為什么 Redis 不直接使用 C 語言的字符串&#xff1f;sdshdr 的結構sdshdr 的不同類型sdshdr 帶來的優勢總結我們來詳細解析一下 Redis 的核心數據結構之一&#xff1a; sdshdr。sdshdr 是 “Simple Dynamic String header” 的縮寫&#xff0c;意為“簡單動態字符串頭…