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

3.C语言笔记:指针数组、函数

1.指针数组

有若干相同类型的指针变量构成的数组。

数据类型 * 数组名[大小]

指针数组:int * p[3];

数组指针:int (*p)[4] = a;

int a = 10,b = 20, c = 20; int * p[3]; p[0] = &a; p[1] = &b; p[2] = &c; printf("a-b-c:%d %d %d\n",a,b,c); printf("%d %d %d\n",*p[0], *p[1], *p[2]); printf("%p %p %p\n",&a, &b, &c); printf("%p %p %p\n",p[0],p[1],p[2];

p+1:p是指针数组名,+1就是移动一格指针的大小,8字节(64位)

原理:p退化成&p[0] 一级指针,对第一个元素p[0]取地址,+1就指向第二个

而p做为指针,p[0],p[1]p[2],每个元素占8个字节(64位)

为指针数组里面的指针定义指向谁,只能一个一个来

而数组指针,可以int (*p) [3] = a ;(这里a是二维数组a[2][3])

int a[] = {5,8,2,5,9,1}; int * p[5]; int i; for(i = 0; i < sizeof(a) / sizeof(int); i++){ p[i] = &a[i]; 为每个指针定义,指向数组的一个元素 } 或者可以: int *p[5] = {&a[0], &a[1], &a[2], &a[3], &a[4]}; for(i = 0; i < sizeof(a) / sizeof(int); i++){ printf("%d\n",*p[i]); } return 0;
指针数组指向字符串常量:
#include<stdio.h> int main (){ char * s[] = {"BeiJing", "ShangHai", "GuangZhou"}; int i; for(i = 0; i < sizeof(s) / sizeof(char *); i++){ printf("%s\n",s[i]); 这里说下;%s期望的到一个一级指针(地址) } s退化成&s[0],这是一个指针,指向的是s[0] return 0; 可是s[0]本身就是一个指针,指向字符串常量里面的第一个元素 } 这样s就变成二级指针了,与%s不符

这里再说一下,s[i]指向的是什么?首先,{"BeiJing", "ShangHai", "GuangZhou"}这并不是数组,这个叫【初始化列表】,"BeiJing"是初始化列表里面的【字符串字面量】。

所以s[i],比如s[0]指向的是"BeiJing"这个字符串字面量的首地址。

指针数组与二维数组

这里不能int *p = ap是数组名不可以成为赋值的左值

遇到数组,首先就想到,元素,使用元素!

int a[2][3] = {{3,5,1},{3,6,9}}; int * p[2]; a退化成&a[0][0] a是一级指针! p[0] = a[0]; //&a[0][0]; 这里不能int *p = a p是数组名不可以成为赋值的左值 p[1] = a[1]; //&a[1][0]; printf("%d\n",a[0][1]); 输出5 printf("%d\n",*(p[0] + 1)); 输出5 p[0] = a[0] = &a[0][0] 数组名在赋值时会退化 printf("%d\n",p[0][1]); 输出5 int i ,j; for(i = 0; i < 2; i++){ for(j = 0;j < 3;j++){ //printf("%d",a[i][j]); printf("%d %d",*(p[i] + j),p[i][j]);
数组指针和指针数组

int * p[5]

指针数组是一维数组,每个元素都是int *

指针数组经常结合二维数组使用,存储每行首元素的地址

本质是数组,存储内容是是指针而已,p是数组名,数组名不能被赋值。

int (*p)[5]

指向数组的指针

本质是指针,指向的内容是有5个元素的一维数组

一维数组名取地址,或者二维数组名,都可以赋给它。

int a[2][3] = {{3,5,1},{3,6,9}}; int (*p)[3] = a ; int i ,j; for(i = 0; i < 2; i++){ for(j = 0;j < 3;j++){ printf("%d",*(*(p + i) + j)); int b[3] ={1,5,9}; int *q = b; for(i = 0; i < 3; i++){ printf("%d",*(q + i)) // q是指向数组首地址的指针,q是&b[0] + i *(&b[0] + i) 等于b[i] int b[3] = {1,5,9}: int *p[3]; p = &b; for(i = 0; i < 3; i++){ printf("%d",*(*p + i)); p是&b 。 *p是b = &b[0] 所以 *p + i 是指向b[i] *(*p + i)是b[i]
我的理解:


int *p[3] :这是指针数组,p是数组名,默认指向p[0]这个指针(数组p的第一个元素),

每个p[0]都是int*类型,实际上p是int**类型。

p[0]需要手动赋值如:p[0] = a[0](a是二维数组) ;或p[0] = &a[0] (a是一维数组);p[0]始终是int*

一、这时要区分,如果a是二维数组,p[0] = a[0]

(注意:这里不是p[0]指向a[0],这里是赋值,指向应该是p[0] = &a[0],这就变成p[0]等于a了,类型不符合。)二维数组名a,是数组指针 类型是int(*)[4]

这时,p[0]是指向a[0][0] 也就是p[0] = &a[0][0] 。p[0]是一级指针!

二、如果a是一维数组,p[0] = a 才对,尽量写成对元素取地址的形式 p[0] = &a[0]

写法 p[0] = &a[0]; p[1] = &a[1]

a是个一维数组名也是一级指针,退化成&a[0]。p[0] = &a[0],p[0]是数组p的元素,是一个指针,一级指针,指向a[0]。*(p[0] + i)等于p[0][i] = *p[i]

如果是int (*p)[3]; a是a[2][3],p是指向a[0]的指针 ,a[0]是数组表达式,a[0]可退化成&a[0][0]

int (*p)[3] = a; 这时 p不是数组,p只是一个指针 p = a = &a[0]

p + 1 是指向a[1]的指针 *(p + 1)是a[1] 是 &a[1][0]

所以 *(*(p+1)) 等于a[1][0],*(*(p+i)+j)等于p[i][j] 等于a[i][j]

二维数组a[2][3]。a退化成&a[0]也就是指向一维数组的指针,也叫行指针。这个指针是一级指针。

int (*)[3] 是一级数组指针。所以int *p = a 可以。a退化成数组指针&a[0]

2.多级指针

指向指针变量的指针变量叫多级指针。

一级指针:指向处理数据的指针变量。

二级指针:指向一级指针的指针变量。

二级指针: 数据类型 ** 指针名

#include <stdio.h> int main (){ int a = 10 ; int * p = &a; int **q = &p; printf("%d %p %p", a, p, q); printf("%p %p %p", &a, &p, &q); printf("%ld %ld %ld", sizeof(a), sizeof(p), sizeof(q)); printf("%d%d%d", a , *p , **q); 输出10,10,10 printf("%p %P\n", p, p + 1); 0x724;0x728 printf("%p %p\n", q, q + 1); 0x728;0x730 0x728是指针p自己占的地址 return 0; }
多级指针运算

指针变量+1,是 向指针变大的方向移动一个目标数据。

多级指针运算也是以其目标变量为单位进行偏移。

多级指针运算:

int **p; p + 1移动一个int *变量所占的内存空间 8字节

int ***p;p + 1移动一格int **变量所占的内存空间 8字节

#include <stdio.h> int main (){ int a[5] = {4,6,9,10,20}; int *p[5]; int n = sizeof(a) / sizeof(int); int i; int **q; for(i = 0; i < n; i++){ 为指针数组里面的指针定义指向,只能一个一个来,可以循环 p[i] = &a[i]; } for(i = 0; i < n; i++){ printf("%d %d\n",a[i], *p[i]); } q = p; printf("%d %d %d %d " , a[1], *p[1], **(q + 1), *q[1]); 输出6666 return 0; } p是指针数组,p 退化成 &p[0] 。p[0]是指向a[0]的指针。p[0]不是数组名,p[0]不会退化。 p[0]是int *类型,所以p是int **类型。

char *s[5] = {"apple", "pear", "peach", "orange", "banana"}; char ** p = s; //&s[0] printf("%s\n",s[1]); pear printf("%s\n",*(p + 1)); pear p++; printf("%s\n", *p); pear return 0; }
void指针及用法

万能指针,泛指针,void * 没有类型,只指向地址。普通指针p + 1 ,void指针不可以

int a = 10; void *p; p = &a; printf("%d\n",*(int *)p);
#include <stdio.h> int main() { int a[3] = {10, 20, 30}; void *p; p = a; printf("%d", *((int *)p + 1)); // 输出 20 return 0; }
一维索引法:(平铺) #include <stdio.h> int main() { int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; void *p = a; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("%d ", *((int *)p + i * 3 + j)); p原来指向a[0] 转变后指向a[0][0] 其实:p指向的地址一直没变,改变的是指针类型 } printf("\n"); } return 0; }

void 的指针,强制转换时会失去步长,步长按新类型算。

#include <stdio.h> int main() { int a[2][3] = {{1, 2, 3}, {4, 5, 6}}; void *p = a; for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { printf("%d ", *(*((int(*)[3])p + i) + j)); int(*)[] 是数组指针类型 } printf("\n"); } return 0; }
const变量,const指针

常量化变量,使变量不能修改。

变量被const修饰时,用指针访问变量

就近原则,const修饰谁,谁不能改变

const修饰的变量必须初始化,只定义是不行的

const修饰的全局变量是只读段。const修饰的局部变量放栈区。

const int m = 10; //等价于 int const m = 10; //error: m++ 这时候m就不能修改了 int *p = &m; (*p)++; 可以用指针间接访问,这时候不报错,m变成了11。

常量化指针目标:

限制通过指针改变目标数值,但是指针本身存储的地址可以修改。

限制内容:不能用指针来修改变量。可以改变指针存的地址,改完还是不能通过指针修改

int m = 10; int n = 20; const int *p = &m; 这里可以直接m++;只要不用指针*p来改就行 //(*p)++;报错 *p指针只读,不能修改 p = &n; 没问题 printf("%d",*p); 输出20

常量化指针变量:

指针存的地址不能修改,但可以*p 来改变指针指向的变量的值

int m = 10; int n = 20; int * const p = &m; //p = &n; 报错 (*p)++; 可以 printf("%d",*p); 输出11

常量化指针及目标:

不能改指针存的地址,也不能改指针所指变量的值。

int m = 10; int n = 20; const int * const p = &m; //p = &n; 报错 //(*p)++; 报错

3.main函数的参数

argc:命令行参数的个数

argv:保存命令行参数的字符串指针

其中第0个参数是程序的全名,以后的参数为命令行后面跟着的用户输入的参数。

argv参数是字符串指针数组,其各元素值为命令行中各字符串的首字母。

指针数组的长度即为参数个数argc。

#include<stdio.h> int main (int argc, const char * argv[ ]){ if(argc != 3){ printf("usage: %s ip port\n",argv[0]); return 0; } int i; printf("argc = %d\n",argc); for(i = 0 ; i < argc; i++){ printf("%s\n",argv[i]); } return 0; }

4.函数

函数是一个完成特定功能的代码模块,其程序代码独立,通常要有返回值,返回值可以是空值。

数据类型 函数名 (形式参数说明){

内容

return 表达式(要与数据类型呼应);

}

如果没有类型,写void 如: void 函数名 ()

形式参数说明用逗号 , 分隔多个变量的说明形式。

{ }大括号里的叫函数体。

函数的目的是模块化代码,维护方便。

函数的调用

函数的使用:函数名(实际参数);

函数调用可以作为一个参数,放在表达式里来运算。

实际参数 :函数调用时,调用函数传递给被调用函数的数据。

编写函数:比较两个数谁最大 #include <stdio.h> int get_max(int a, int b){ if(a > b){ return b; }else{ return a; } } int main (){ int i,j; int ret; printf(">"); scanf("%d%d",&i, &j); ret = get_max(i, j); printf("max: %d\n",ret); return 0; }
函数的声明

编译器从上往下编译,所以声明函数要放到main函数前面。同时形参里变量的名称可以省略,但是变量的类型不能省略。

int get_max(int a, int b){

int get_max(int , int ){ 两种写法都对

#include<stdio.h> void print_hello(); 将声明的名称放main前面,编译时就不会报错。 int main(){ print_hello(); return 0; } void print_hello(){ printf("hello world\n"); 可以把详细的函数声明写后面。 }
编写函数:比较两个数谁最大 #include <stdio.h> int get_max(int , int ){ 这里可以不写形参里的变量名,但类型必须写 int main (){ int i,j; int ret; printf(">"); scanf("%d%d",&i, &j); ret = get_max(i, j); printf("max: %d\n",ret); return 0; } int get_max(int a, int b){ 这里必须写全 if(a > b){ return b; }else{ return a; } }

应用:

求幂 #include<stdio.h> double fun_pow(double x,int n); int main(){ double x = 2; int n = 5; double ret; 这里可以省略成:printf("%lf",fun_pow(x,n)); ret = fun_pow(x,n); printf("%lf\n",ret); return 0; } double fun_pow(double x,int n){ int i; double ret = 1; for(i = 0; i < n; i++){ ret *= x; return ret; 这里是整个函数运行结束后,发出的数据 } }
函数的传参-全局变量

形参:定义函数时用的参数,目的是:接收,调用该函数时收到的参数。

实参:主函数调用时,真正传给被调用函数的参数。

参数传递:程序运行时,将实际参数传递给被调用函数的形式参数的过程。

传递方式有三种:全局变量、值传递、指针传递。

全局变量:

全局变量是在所有函数体外说明的变量。不建议使用。所有函数都可以调用和修改它。

值传递:

调用函数将实参传递给被调用函数,被调用函数先创建新的形参(新地址),然后把实参的值赋给它。原地址的内容不修改

交换数值,值传递是创建新形参(新地址) #include<stdio.h> void fun_swap(int a, int b); int main (){ int x = 200, y = 100; printf("before:x=%d y=%d %p %p\n", x, y, &x, &y); 原数值,原地址 fun_swap(x,y); 交换后数值,新地址 printf("after:x=%d y=%d\n",x,y); 原数值,新地址 return 0; } void fun_swap(int a, int b){ int t = a; a = b; b = t; printf("a=%d b=%d %p %p\n",a , b, &a, &b); }

值传递应用:判断素数

#include<stdio.h> int fun_prime(int n); int main(){ int n = 23; if(fun_prime(n)){ printf("%d is prime\n",n); }else{ printf("%d is not prime\n",n); } return 0; } int fun_prime(int n){ int i; if(n == 1){ return 0; } for(i = 2; i < n; i++){ if(n % i == 0){ return 0; } } return 1; }

输入一个数,看看他以下有多少素数

#include<stdio.h> int fun_prime(int n); int fun_prime_sta(int n); int main(){ int n; printf("input "); scanf("%d",&n); int count; count = fun_prime_sta(n); printf("%d\n",count); return 0; } int fun_prime(int n){ int i; if(n == 1){ return 0; } for(i = 2; i < n; i++){ if(n % i == 0){ return 0; } } return 1; } int fun_prime_sta(int n){ int i; int sum = 0; for(i = 1; i < n; i++){ if(fun_prime(i)){ printf("%d\n",i); sum++; } } return sum; }
指针传递

按地址传递,实参为变量的地址,形参为同类型的指针。

被调用函数,对形参的操作,可以直接改变实参的值。

#include<stdio.h> void fun_swap(int * p,int *q); int main(){ int m = 10,n = 20; fun_swap(&m, &n); printf("%d %d",m ,n); 实参是地址,被指针操作修改了变量的原值 return 0; } void fun_swap(int *p,int *q){ int t = *q; *q = *p; *p = t; }

数组作为参数传递时,传的是数组的首地址。

5.函数的传参

练习:字符串统计
大小写转换并统计字母数量 #include <stdio.h> int fun_string(char *p); void fun_string_con(char *p,int *sum_p); int main(){ char s[100]; int sum = 0; scanf("%s", s); fun_string_con(s,&sum); /* sum = fun_string(s); printf("%s %d\n",s,sum); */ printf("%s %d\n",s,sum); return 0; } /*int fun_string(char *p){ int sum = 0; while(*p != '\0'){ if(*p >= 'a' && *p <='z'){ sum++; *p -= 32; }else if(*p >= 'A' && *p <='Z'){ sum++; *p += 32; } p++; } return sum; } */ void fun_string_con(char *p,int *sum_p){ while(*p != '\0'){ if(*p >= 'a' && *p <='z'){ (*sum_p)++; 针对sum,改成了直接指针修改 *p -= 32; }else if(*p >= 'A' && *p <='Z'){ (*sum_p)++; *p += 32; } p++; } }
一维数组在函数间传参

void fun(int *arr, int size);

void fun(int arr[ ], int size);

编写函数,计算一维数组所有整数的和 #include <stdio.h> int fun_sum(int * data, int n); int main (){ int a[] = {1,5,9,10,20,21}; int sum = 0; sum = fun_sum(a,sizeof(a) / sizeof(int )); printf("%d\n",sum); return 0; } int fun_sum(int * data, int n){ int i; int sum = 0; for(i = 0; i < n; i++){ sum += data[i]; } return sum; }

排序:

对整形数组排序: #include <stdio.h> void fun_sort(int * ,int ); void fun_printf(int * ,int); int main(){ int a[] = {1,5,9,10,20,21}; fun_sort(a,sizeof(a) / sizeof(int)); //fun_printf(a,sizeof(a) / sizeof(int)); int i; for(i = 0; i < sizeof(a) / sizeof(int); i++){ printf("%d\t",a[i]); } return 0; } void fun_sort(int * data,int n){ int i,j,t; for(i = 0; i < n - 1; i++){ for(j = 0; j < n - 1 - i; j++){ if(data[j] > data[j + 1]){ t = data[j + 1]; data[j + 1] = data[j]; data[j] = t; } } } } //void fun_printf(int * data, int n){ 这里data虽然是数组名,但是这里变成指针了 int i ; for(i = 0; i < n ;i++){ printf("%d",data[i]); } }
字符数组传参
函数删除字符数组里的空格 #include<stdio.h> void del_space(char *p); //char * del_space(char *s); int main (){ char s[100] = "asdf DDD sd"; del_space(s); printf("%s\n",s); // printf("%s\n",del_space(s)); return 0; } void del_space(char *s){ //char * del_space(char *s){ char * p = s; char * q = s; while (*q != '\0'){ if(*q != ' '){ *p = *q; p++; q++; }else{ q++; } } *p ='\0'; // return s; }
二维数组用一级指针传参
#include<stdio.h> void print_array(int *a, int n, int m); int main() { int a[3][4] = {{1,5,3,2}},{3,6,9,8},{},{} }; print_array(a[0],3,4); return 0; } void print_array(int *a, int n, int m){ int i; for(i = 0; i < n * m; i++){ printf("%d\n",*(a + i)); i++; } }
二维数组用行指针传参
#include<stdio.h> const int M = 4; void print_array(int *a,int n,int m) // int get_odd(int a[][M],int n, int m); int get_odd(int (*a)[M], int n,int m); int main() { int a[3][4] = {{1,5,3,2}},{3,6,9,8},{},{} }; print_array(a[0],3,4); int r; r = get_odd(a,3,4); printf("r = %d\n",r); return 0; } void print_array(int *a, int n, int m){ int i; for(i = 0; i < n * m; i++){ printf("%d\n",*(a + i)); i++; } } int get_odd(int a[][M],int n,int m){ int i,j,sum = 0; for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ if(a[i][j] % 2 != 0){ sum++; } } } return sum; }
二维数组用二级指针传参
#include<stdio.h> const int M = 4; void print_array(int *a,int n,int m) // int get_odd(int a[][M],int n, int m); int get_odd(int (*a)[M], int n,int m); int get_odd2(int **p,int n,int m); int main() { int a[3][4] = {{1,5,3,2}},{3,6,9,8},{},{} }; print_array(a[0],3,4); int r; int *p[3] = {a[0],a[1],a[2]}; r = get_odd2(p,3,4); printf("r = %d\n",r); return 0; } void print_array(int *a, int n, int m){ int i; for(i = 0; i < n * m; i++){ if((i + 1) % M == 0){ putchar('\n'); } printf("%d\n",*(a + i)); i++; } } int get_odd(int a[][M],int n,int m){ int i,j,sum = 0; for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ if(a[i][j] % 2 != 0){ sum++; } } } return sum; } int get_odd2(int **a,int n,int m){ int i,j,sum = 0; for(i = 0; i < n; i++){ for(j = 0; j < m; j++){ if(*(a[i] + j) % 2 != 0){ sum++; } } } return sum; }

6.指针函数

指针函数返回值是指针,如:int * fun(int x, int y) ; 返回值类型是int *

数据类型 * 函数名 (参数){ }

#include <stdio.h> char * get_string() { char * s = "hello"; return s; } char * get_char_array(){ char ch[10] = {'a', 'b', 'c', '\0'}; return ch; } int main() { char * s; s = get_char_array(); 函数运行完,局部变量就被释放,会报错 char *p; p = get_string(); printf("p = %s\n",p); 字符串常量存在静态存储区,函数结束了,仍然可以访问地址 return 0; }

字符串拷贝函数:char *strcpy(char *dest,const char *src);

#include<stdio.h> #include<string.h> int main() { char s1[100]; char s2[100]; char *s3 = "welcome"; 字符串常量存在静态存储区 strcpy(s2,strcpy(s1,s3)) // printf("%s\n",strcpy(s1,s2)); 输出welcome printf("%s\n",s1); 输出welcome printg("%s\n",s2); welcome return 0; }
指针函数的返回值
#include <stdio.h> #include <string.h> char s[20]; 可以定义全局变量地址。 char * mystring(){ //char s[20]; 函数结束地址就被释放了,报错 strcpy(s,"hello"); return s; } char * mystring2(){ char * s = "hello"; 字符串常量的地址返回有效 return s; } char * mystring3(char * s){ 传给他的地址,再返回地址,当然有效 *s = 'A'; 输出Aello return s; } int main(){ printf("%s\n",mystring()); return 0; }

指针函数可以返回什么样的指针?

全局变量的地址、字符串常量的地址、static变量的地址、堆的地址、主调函数中有效内存

指针函数:编写字符串拷贝函数
#include <stdio.h> #include<assert.h> char * my_strcpy(char * dest,const char * src); char * my_strcpy2(char * dest,const char * src); int main (){ char s1[100]; char s2[100]; char *s3 = "welcome"; //my_strcpy(s1,my_strcpy(s2,s3)); my_strcpy2(s1,my_strcpy(s2,s3)); puts(s1); puts(s2); puts(s3); return 0; } char * my_strcpy(char * dest,const char * src){ char * s = dest; //先保存dest起始地址 while(*src != '\0'){ *dest++ = *src++; } *dest = '\0'; //或*dest = *src; } return s; //此时dest已经移动了 } char * my_strcpy2(char * dest,const char * src){ char * s = dest; //先保存dest起始地址 assert(dest && src); 如果dest和src有一个为空,会报警 while(*dest++ = *src++) //表达式不等于'\0'就会一直循环 //*dest = '\0'; //或*dest = *src; 可以不加了。 } return s; //此时dest已经移动了 }
指针函数:编写字符串连接函数
#include<assert.h> #include <stdio.h> //#include <string.h> char * my_strcat(cjar *dest,const char *src); int main () { char s1[100] = "ab"; char s2[100] = "cd"; char * s3 = "welcome"; // strcat(s1,strcat(s2,s3)); my_stract(s1,mystrcat(s2,s3)); puts(s1); puts(s2); puts(s3); return 0; } char * my_strcat(char *dest,const char *src){ assert(dest && src != null); char *s = dest; while(*dest != '\0'){ //whi le(*dest++); dest--; dest++; } while(*src != '\0'){ //while(*dest = *src); *dest = *src; src++; dest++; } *dest = *src; return s; }
指针函数案例

编写函数,把整数123改成字符串"123".

#include <stdio.h> char * my_itoa(int,char *) int main (){ int a = 456; char s[100]; my_itoa(a,s); puts(s); return 0; } char * my_itoa(int a,char *s){ int i = 0; int j = 0; while(a != 0){ s[i] = a % 10 + 48; i++; a = a / 10; } s[i] = '\0'; i--; while(j < i){ t = s[j]; s[j] = s[i]; s[i] = t; j++; i--; } return s; }
int add(int a, int b) { return a + b; } int main() { int (*p)(int, int) = add; int result = (*p)(int, int); // 调用p指向的add函数 return 0; }
http://www.jsqmd.com/news/808076/

相关文章:

  • vue常见基础面试题
  • Spring中的Full模式和Lite模式,90%的开发都没搞明白
  • Gemini3.1Pro:商业分析框架搭建神器
  • 2026 国内明渠流量计十大品牌排行榜完整版 - 陈工日常
  • 2026最新文昌财税公司TOP8口碑推荐,代理记账乱账整理注册公司代办机构优选指南 - 品牌智鉴榜
  • 新手必看!用MP2451设计一个±12V双电源,聊聊反相Buck-Boost的PCB布局避坑指南
  • 别再只调包了!深入Kaggle糖尿病数据集:用逻辑回归前你必须做的5项数据诊断
  • 英雄联盟智能助手Seraphine:免费开源的终极游戏辅助神器,轻松提升你的游戏水平
  • 爱校哥会议屏租赁的口碑评价 - myqiye
  • 济南晨星驾驶培训:摩托车驾照一站式拿证指南,这些坑千万别踩! - 品牌策略师
  • JMeter 性能测试实战效果与能力全景展示
  • Cursor2API:开源代理工具实现免费AI接口协议转换与功能增强
  • 2026年陕西资质代办避坑指南:内行人揭秘行业猫腻 - COINUP
  • 【必收藏】2026年大模型学习全指南|小白程序员入门捷径,抓住百万年薪红利
  • 分析化学考研辅导班推荐:专门针对性培训机构评测 - michalwang
  • 告别ST-LINK依赖!在STM32CubeIDE 1.7+版本中,用DAP-LINK调试STM32F4的保姆级教程
  • 2026年口碑好的GEO公司推荐机构,上海翼锦领先 - myqiye
  • Gemini3.1Pro轻松搞定文献综述难题
  • 2026年5月国内专业酿醋设备厂家核心产品优势技术全维度解析 - 奔跑123
  • 软考 系统架构设计师历年真题集萃(254)
  • 【Web】使用Vue3开发3D游戏(十一)渲染3D高斯泼溅效果
  • 羽毛球每天必练的基本功:拉吊四方球战术、吊杀结合战术
  • 2026年常州高分子材料管业深度选购指南:编织网管与电池防护配件源头工厂直供全景对标 - 优质企业观察收录
  • 人机生殖隔离
  • 具身智能(Embodied AI):当Agent拥有了物理身体
  • 2026年4月冬令营推荐,恩格贝沙漠穿越/儿童生存训练营/少年游骑兵生存训练营/恩格贝沙漠夏令营/夏令营,冬令营选哪家 - 品牌推荐师
  • CSDN 创作同步插件与 AI 标注功能实测大纲
  • 神兽街靠谱吗? - 工业品牌热点
  • 2026年饲料颗粒机厂家怎么选?这三点关键别错过 - 天涯视角
  • 【Excel提效 No.074】一句话搞定周数星期自动计算