C_深入理解指针(五) —— sizeof和strlen的对比、数组和指针笔试题解析、指针运算笔试题解析

目录

一、sizeof和strlen的对比

1、sizeof

2、strlen

[3、sizeof 和 strlen的对比](#3、sizeof 和 strlen的对比)

二、数组和指针笔试题解析

1、⼀维数组

重点学习代码:sizeof与一维整型数组类型

2、字符数组

代码1:sizeof与字符数组类型

代码2:strlen与字符数组类型

代码3:sizeof与字符串数组类型

代码4:strlen与字符串数组类型

代码5:sizeof与字符指针数组类型

代码6:strlen与字符指针数组类型

3、二维数组

三、指针运算笔试题解析

1、题目一

2、题目二

3、题目三

4、题目四

5、题目五

6、题目六

7、题目七


一、sizeof和strlen的对比

1、sizeof

  1. sizeof 可以计算变量所占内存的内存空间大小,单位是字节,它是一个操作符,不是函数
  2. 如果操作数类型的话,则计算的是使用类型创建的变量所占内存空间的大小
  3. sizeof 只关注占用内存空间的大小,不在乎内存中存放什么数据。
cpp 复制代码
#inculde <stdio.h>
int main()
{
    int a = 10;
    printf("%d\n", sizeof(a));//4    
    printf("%d\n", sizeof(int));//4

    int arr[10] = { 100, 200};
    printf("%zd\n",sizeof(arr));//40
 
    return 0;
}

2、strlen

函数原型如下:

cpp 复制代码
size_t strlen ( const char * str );

重点总结:

  1. strlen 是C语言库函数,使用需要包含头文件 <string.h>;
  2. 其功能是求字符串长度,只能针对字符串(字符数组),统计的是字符串中\0之前的字符个数。
  3. 统计的是从 strlen 函数的参数 str 中这个地址开始向后, \0 之前字符串中字符的个数。strlen 函数会⼀直向后找 \0 字符,直到找到为止,所以可能存在越界查找。
cpp 复制代码
#include <stdio.h>
int main()
{
    char arr1[3] = {'a', 'b', 'c'};
    char arr2[] = "abc";
    printf("%d\n", strlen(arr1));//随机值
    printf("%d\n", strlen(arr2));//3
 
    printf("%d\n", sizeof(arr1));//3
    printf("%d\n", sizeof(arr2));//4
    return 0;
}

3、sizeof 和 strlen的对比

|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------|
| sizeof | strlen |
| 1. sizeof是操作符 2. sizeof计算操作数所占内存的大小,单位是字节 3. 不关注内存中存放什么数据 | 1. strlen是库函数,使⽤需要包含头文件 string.h 2. srtlen是求字符串⻓度的,统计的是 \0 之前字符的个数 3. 关注内存中是否有 \0 ,如果没有 \0 ,就会持续往后找,可能会越界 |

二、数组和指针笔试题解析

1、⼀维数组

数组名是数组首元素的地址,但有两个例外

  1. 第一,sizeof(数组名),表示整个数组的大小
  2. 第二,&数组名,表示的是整个数组,取出的是数组的地址

**重点学习代码:**sizeof与一维整型数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    int a[] = {1,2,3,4};

    printf("%d\n",sizeof(a));//16
    //数组名a单独放在sizeof内部,a表示整个数组,计算的是整个数组的大小,单位是字节

    printf("%d\n",sizeof(a+0));
    //这里的a是数组名表示首元素的地址,a+0还是首元素的地址
    //这里sizeof计算的是首元素地址的大小 4/8

    printf("%d\n",sizeof(*a));//4 
    //这里的a是数组名表示首元素的地址,*a 就是首元素,就是a[0]
    //*a--*(a+0)-- a[0]

    printf("%d\n",sizeof(a+1));
    //这里的a是数组名表示首元素的地址,a+1是第二个元素的地址(&a[1])
    //计算的是地址的大小 4/8

    printf("%d\n",sizeof(a[1]));//4

    printf("%d\n",sizeof(&a));
    //&a -这里的数组名a表示整个数组,&a是整个数组的地址
    //数组的地址也是地址,是地址就是 4/8 个字节的长度

    printf("%d\n",sizeof(*&a));
    //1.*&a,这里的*和&抵消了,所以sizeof(*&a)== sizeof(a) 16
    //2. &a - 这是数组的地址,类型是:int(*)[4],*&a 访问的就是这个数组
    
    printf("%d\n",sizeof(&a+1));
    //&a是数组的地址,&a+1是跳过整个数组后的那个位置的地址
    //&a+1是地址,地址都是4/8个字节

    printf("%d\n",sizeof(&a[0]));//4/8

    printf("%d\n",sizeof(&a[0]+1));//第二个元素的地址 4/8

    return 0;
}

2、字符数组

重点学习代码:

代码1: sizeof与字符数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", sizeof(arr));
    //计算整个数组的大小    6

    printf("%d\n", sizeof(arr+0));
    //首元素的地址          4/8

    printf("%d\n", sizeof(*arr));
    //通过首元素地址访问首元素  1

    printf("%d\n", sizeof(arr[1]));
    //第二个元素的大小        1

    printf("%d\n", sizeof(&arr));
    //取地址数组名,即取出的是整一个数组,根据计算机的编译环境来确定
    //4/8

    printf("%d\n", sizeof(&arr+1));
    //取地址数组名,即取出的是整一个数组,根据计算机的编译环境来确定    
    //加上1即为跳过整个数组
    //4/8

    printf("%d\n", sizeof(&arr[0]+1));
    //首元素的地址+1,得出来的是第二个元素的地址
    //4/8

    return 0;
}

代码2: strlen与字符数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>
    
int main()
{
    char arr[] = {'a','b','c','d','e','f'};

    printf("%d\n", strlen(arr));
    //表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(arr+0));
    //表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(*arr));
    //arr是数组名表示首元素的地址
    //*arr 是首元素 ------'a'-97,传递给strlen后,strlen 会认为97就是地址,然后去访问内存
    //error -- 程序奔溃

    printf("%d\n", strlen(arr[1]));//'b'------98  error -- 程序奔溃
    printf("%d\n", strlen(&arr));
    //取整个地址名的地址为表示首元素的地址,往后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(&arr+1));
    //取整个地址名的地址为表示首元素的地址,加上1即为跳过一个数组,其跳过的长度为6个字符,再往 
      后数有多少个元素,直到找到\0
    //随机值

    printf("%d\n", strlen(&arr[0]+1));
    //表示首元素的地址,加上1即为跳过一个数组,其跳过的长度为1个字符,也就是到了字符b的位置,再            
      往后数有多少个元素,直到找到\0
    //随机值

    return 0;
}

代码3:sizeof与字符串数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

//数组名是数组首元素的地址,但有两个例外:
//第一,sizeof(数组名),表示整个数组的大小;第二,&数组名,表示整个数组,取出的是数组的地址。

int main()
{
    char arr[] = "abcdef";

    printf("%d\n", sizeof(arr));//7
    //数组名单独放在sizeof内部,计算的是数组的大小

    printf("%d\n", sizeof(arr+0));
    //arr+0是数组首元素的地址,大小就是4/8个字节

    printf("%d\n", sizeof(*arr));//1
    //*arr是首元素,sizeof(*arr)  

    printf("%d\n", sizeof(arr[1]));
    //数组第二个元素的大小     1

    printf("%d\n", sizeof(&arr));
    //&arr是数组的地址,大小为4/8个字节

    printf("%d\n", sizeof(&arr+1));
    //&arr是数组的地址,&arr+1跳过了整个数组,指向了数组后面的那个位置
    //&arr+1为地址,大小为4/8个字节

    printf("%d\n", sizeof(&arr[0]+1));
    //&arr[0]是首元素的地址,&arr[0]+1是第二个元素的地址,大小为4/8个字节

    return 0;
}

代码4:strlen与字符串数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char arr[] = "abcdef";

    printf("%d\n", strlen(arr));//6
    //arr 是首元素的地址,strlen是从第一个元素开始统计\0之前的字符的个数 
    
    printf("%d\n", strlen(arr+0));//6
    //arr 是首元素的地址,arr+0还是首元素的地址
    
    printf("%d\n", strlen(*arr));
    //arr 是首元素的地址,*arr是首元素-'a'-97,97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃

    printf("%d\n", strlen(arr[1]));
    //同上,字符数组第二个的元素传过去会被当成地址
    //error -程序崩溃

    printf("%d\n", strlen(&arr));//6
    //-=&arr是数组的地址,数组的地址和数组首元素的地址是指向同一个位置的
    //那么strlen也是从第一个元素的位置开始向后访问的

    printf("%d\n", strlen(&arr+1));
    //&arr是数组的地址,&arr+1跳过了整个数组,指向了数组后面的那个位置
    //随机值

    printf("%d\n", strlen(&arr[0]+1));//5
    //&arr[0]是数组首元素的地址,&arr[0]+1跳过了一个元素,指向了数组中的第二个元素

    return 0;
}

代码5:sizeof与字符指针数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char *p = "abcdef";
    //这段代码的意思是将这个字符串的首地址存到指针变量p中去

    printf("%d\n", sizeof(p));
    //p是指针变量,计算的是指针变量p的大小,存的是地址,地址大小为4/8个字节

    printf("%d\n", sizeof(p+1));
    //p为char*类型的指针变量,因此p+1是第二个元素的地址,地址的大小为4/8个字节

    printf("%d\n", sizeof(*p));//1
    //p的类型是char*,所以*p只能访问1个字节

    printf("%d\n", sizeof(p[0]));
    //p[0] -->*(0+0)-- * -- 1个字节

    printf("%d\n", sizeof(&p));
    //&p是指针变量p的地址,也是地址,是地址就是4/8个字节
    //&p -- char**二级指针

    printf("%d\n", sizeof(&p+1));
    //&p是p的地址,&p+1是跳过p变量,指向了p的后边
    //&p+1是地址,就是4/8个字节

    printf("%d\n", sizeof(&p[0]+1));
    //&p[0]+ 1 就是b的地址
    //p[0]-- *(p+0)-- *p

    return 0;
}

代码6:strlen与字符指针数组类型

cpp 复制代码
#include <stdio.h>
#include <string.h>

int main()
{
    char *p = "abcdef";
    //这段代码的意思是将这个字符串的首地址存到指针变量p中去

    printf("%d\n", strlen(p));//6
    //从字符串的首元素的地址开始数元素个数

    printf("%d\n", strlen(p+1));//5
    //从字符串的首元素的下一个位置的地址开始数元素个数
    
    printf("%d\n", strlen(*p));
    //*p ------ 'a' ------ 97
    //97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃

    printf("%d\n", strlen(p[0]));
    //p[0] ------ *(p+0)
    //97作为地址传给给了strlen
    //但是97这个地址不能被访问-程序会崩溃
    
    printf("%d\n", strlen(&p));//随机值
    //p本来就是一个指针变量,然后又取p的地址,即为二级指针

    printf("%d\n", strlen(&p+1));//随机值
    //p本来就是一个指针变量,然后又取p的地址,即为二级指针,+1之后也是一个指向下一位置的二级指针

    printf("%d\n", strlen(&p[0]+1));//5
    //&p[0]为第一个元素的地址,+1之后为第二个元素的地址,往后数直到遇到\0

    return 0;
}

3、二维数组

二维数组的直观表示图形:

cpp 复制代码
#include <stdio.h>
int main()
{
    int a[3][4] = {0};

    printf("%d\n",sizeof(a));//48
    //a作为数组名,单独放在sizeof内部了,a表示的是整个数组,计算的是整个数组的大小,单位是字节

    printf("%d\n",sizeof(a[0][0]));//4
    //a[0][0]是第一行第一个元素,大小是4个字节    

    printf("%d\n",sizeof(a[0]));//16
    //a[0]是第一行的数组名,单独放在sizeof内部,计算的是数组的大小 4*4 = 16个字节

    printf("%d\n",sizeof(a[0]+1));
    //a[0]是第一行的数组名,但是没有单独放在sizeof内部,
    //那么只能是数组首元素的地址,那就是第一行第一个元素的地址 - &a[0][0]
    //a[0]+1 == &a[0][0]+1 == &a[0][1]
    //地址的大小为4/8个字节

    printf("%d\n",sizeof(*(a[0]+1)));
    //*(a[0]+ 1)是第一行第二个元素,大小是4个字节

    printf("%d\n",sizeof(a+1));
    //a是二维数组的数组名,并没有单独放在sizeof内部,a表示首元素的地址-也就是第一行的地址
    //a+1 是第二行的地址,是地址大小就是4/8个字节

    printf("%d\n",sizeof(*(a+1)));//16
    //1.*(a+1)--a[1]--是第二行的数组名,单独放在sizeof内部,计算的是第二行的大小
    //2.a+1是第二行的地址,类型是int(*)[4],数组指针,解引用访问的是这个数组,大小是16个字节

    printf("%d\n",sizeof(&a[0]+1));//4/8
    //a[0]是第1行的数组名,&数组名其实就是第一行的地址,&a[0]+1就是第二行的地址,是地址就是4/8个字节

    printf("%d\n",sizeof(*(&a[0]+1)));//16    

    printf("%d\n",sizeof(*a));//16
    //1.a- 首元素的地址(第一行的地址),*a是第一行了
    //2:*a--*(a+0)-- a[0]

    printf("%d\n",sizeof(a[3]));//16
    //sizeof内部的表达式是不会真实计算的
    //a[3]- 第四行的数组名 int [4]

    return 0;
}

重点:sizeof内部的表达式是不会真实计算的,体现在:

cpp 复制代码
#include <stdio.h>

int main()
{
    short s=8;//2
    int n= 12;//4

    printf("%zd\n",sizeof(s =n + 5));

    printf("%d\n",s);

    return 0;
}


数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址。

三、指针运算笔试题解析

1、题目一

cpp 复制代码
#include <stdio.h>

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };

    int *ptr = (int *)(&a + 1);
    //&数组名即为取整个数组的地址,类型为int(*)[5],
    //当&a+1时,即为跳过整个数组,即指针现在指向末尾的位置,类型还是为int(*)[5];
    //(int*)为强制类型转化,将&a+1强制类型转化为int*的指针变量,再放入ptr的指针变量中

    printf( "%d,%d", *(a + 1), *(ptr - 1));
    //*(ptr-1)为往前倒退一个元素位置再解引用,*(a+1)为往后前进一个元素位置再解引用

    return 0;
}

解题分析思路:

&数组名即为取整个数组的地址,类型为int(*)[5],当&a+1时,即为跳过整个数组,即指针现在指向末尾的位置,类型还是为int(*)[5];(int*)为强制类型转化,将&a+1强制类型转化为int*的指针变量,再放入ptr的指针变量中,*(ptr-1)为往前倒退一个元素位置再解引用,*(a+1)为往后前进一个元素位置再解引用。

以下为思路结构图:

2、题目二

cpp 复制代码
//在X86环境下
//假设结构体的⼤⼩是20个字节

#include <stdio.h>
#include <string.h>

struct Test
{
    int Num;
    char *pcName;
    short sDate;
    char cha[2];
    short sBa[4];
}*p = (struct Test*)0x100000;
//强制类型转化为struct Test*结构体指针类型
//p为结构体指针变量

int main()
{
    printf("%p\n", p + 0x1);
    //p是结构体指针,+1就是跳过一个结构体,一个结构体是20个字节
    //0x00100014    

    printf("%p\n", (unsigned long)p + 0x1);
    //unsigned long是无符号长整型
    //整数+1   0x00100001    

    printf("%p\n", (unsigned int*)p + 0x1);
    //unsigned int*是无符号整型指针类型
    //+1跳过一个unsigned int类型的变量,为4个字节
    //0x00100004

    return 0;
}

注意:

整数+n和指针变量+n是两种不同的概念,整数+n是直接加上所要加上的数字,而指针变量+n是跳过多少个字节,取决于编译器的环境是32位还是64位的。

3、题目三

cpp 复制代码
#include <stdio.h>

int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    //()里面为逗号表达式,是一种运算符号
    //逗号表达式运算顺序为从左往右计算,取最大的那个元素作为结果
    //()并不是二维数组的表达形式,正确的二维数组表达形式是用{}来表示的
    //即为int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };

    int *p;
    p = a[0];
    printf( "%d", p[0]);//1

    return 0;
}

解题思路分析:

  1. ()里面为逗号表达式,是一种运算符号
  2. 逗号表达式运算顺序为从左往右计算,取最大的那个元素作为结果
  3. ()并不是二维数组的表达形式,正确的二维数组表达形式是用{}来表示的即为int a[3][2] = { {0, 1}, {2, 3}, {4, 5} };
  4. 使用逗号表达式后,数组排序为前三个为逗号表达式的运算结果,而后三个元素用0补齐

该二维数组的直观思维图:

4、题目四

cpp 复制代码
//假设环境是x86环境,程序输出的结果是啥?
#include <stdio.h>
int main()
{
    int a[5][5];
    int(*p)[4];//数组指针

    p = a;//将数组的第一行的首元素地址赋给指针变量p
    //等号左边p的类型为int(*)[4],等号右边a的类型为int(*)[5]
    //两者类型不相同,强制赋值会报错警告  

    printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    //p[4][2]=*(*(p+4)+2)
    //两个地址相减得到的是元素与元素之间的个数,相差了几个元素
    //%p打印的是地址,即为相差几个元素作为中间值,再将其转化为补码的形式,这个补码就是地址,每四个连在一起的二进制数换成16进制的,环境为32位;
    //%d打印的是有符号整型,有符号整型是需要求出其原码再读
    //%u打印的无符号整型,无符号整型是需要求出其补码再读    

    return 0;
}

运行结果:

解题思路分析:

  1. 将数组的第一行的首元素地址赋给指针变量p;
  2. 等号左边p的类型为int(*)[4],等号右边a的类型为int(*)[5];
  3. 两者类型不相同,强制赋值会报错警告

数组的直观表示图:

  1. 其中的等价关系:p[4][2]=*(*(p+4)+2)
  2. 两个地址相减得到的是元素与元素之间的个数,相差了几个元素
  3. %p打印的是地址,即为相差几个元素作为中间值,再将其转化为补码的形式,这个补码就是地址,每四个连在一起的二进制数换成16进制的,环境为32位
  4. %d打印的是有符号整型,有符号整型是需要求出其原码再读
  5. %u打印的无符号整型,无符号整型是需要求出其补码再读(有关原反补码的知识详细请关注往后更新的博客)

5、题目五

cpp 复制代码
#include <stdio.h>
int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//二维数组
    
    int *ptr1 = (int *)(&aa + 1);
    //取数组名+1:&aa+1为跳过整个数组,指向数组末尾,再强制类型转化为int*类型赋给指针变量ptr1    

    int *ptr2 = (int *)(*(aa + 1));
    //数组名代表的是数组首元素的地址,即为aa[0]为第一行数组的地址;加上1则变成aa[1]为第二行数组的地址;解引用后再强制类型转化为int*类型赋给指针变量ptr2

    printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10   5
    //*(ptr1-1)为退后一个元素,指向前一个元素再解引用    
    //*(ptr2-1)为前进一个元素,指向后一个元素再解引用    

    return 0;
}

解题思路分析:

取数组名+1:&aa+1为跳过整个数组,指向数组末尾,再强制类型转化为int*类型赋给指针变量ptr1;数组名代表的是数组首元素的地址,即为aa[0]为第一行数组的地址;加上1则变成aa[1]为第二行数组的地址;解引用后再强制类型转化为int*类型赋给指针变量ptr2。

数组排序的逻辑直观图:

6、题目六

cpp 复制代码
#include <stdio.h>
int main()
{
    char *a[] = {"work","at","alibaba"};
    //一级指针数组a[]存的是字符串首元素的地址
    
    char**pa = a;//二级指针变量pa存的是a[]首元素的地址
    pa++;//指向a[1]的地址

    printf("%s\n", *pa);//打印at
    return 0;
}

主要内容:

最重要的是学会分别一级指针和二级指针的具体指向的内容,和指针的运算变化。

指向思维直观图:

7、题目七

cpp 复制代码
#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
    //先算++,再算*解引用,然后算--,再算*解引用,最后再算+3

    printf("%s\n", *cpp[-2]+3);//打印ST
    //等价关系*cpp[-2]+3 -> **(cpp-2) + 3
    //先算*解引用,再算+3

    printf("%s\n", cpp[-1][-1]+1);//打印EW
    //等价关系cpp[-1][-1]+1 -> *(*(cpp-1)-1) + 1    
    //先算(cpp-1),再算*(cpp-1)-1,然后算*(*(cpp-1)-1),最后再+1

    return 0;
}

指向直观思维图:

重要前提:

前面运算的++或--运算操作符,会影响后面的运算结果;而数组的等价转化的加减,是不会影响后面的运算结果的。

解题思路分析:

1.第一个打印:printf("%s\n", **++cpp);****//打印POINT
先运算++,cpp从原来的指向指针数组cpp的起始地址指向到cpp[1],即下一个地址中去;再运算*解引用,得到c+2(c[2]的地址),再*解引用打印得到POINT。

2.第二个打印:printf("%s\n", *--*++cpp+3);//打印ER

先算++,因为第一次打印cpp已经++过一次了,这次再++,会使cpp从原来的指向指针数组cpp的起始地址指向到cpp[2],即下一个地址中去;再算*解引用,得到c+1,然后--得到c,再*解引用得到ENTER字符串的首元素,最后+3,地址向后移动3位,再通过打印函数得到ER。

3.第三次打印: printf("%s\n", *cpp[-2]+3);//ST
等价关系*cpp[-2]+3 -> **(cpp-2) + 3;等价后先算cpp-2得到cpp当前指向的位置,再算解引用的到c+3(c[3]的地址),然后再解引用得到FIRST字符串的首元素,最后进行+3打印出ST。

4.第四次打印:printf("%s\n", cpp[-1][-1]+1);//打印EW

等价关系cpp[-1][-1]+1 -> *(*(cpp-1)-1) + 1;等价后先算(cpp-1)得到cpp当前指向的位置,再算*(cpp-1)得到c+2,然后再-1得到c+1(指向c[1]),经过*解引用之后得到NEW字符串的首元素,最后再+1跳过第一个字母打印。

相关推荐
拾木20012 分钟前
常见的限流算法
java·开发语言
处处清欢17 分钟前
MaintenanceController
java·开发语言
牵牛老人23 分钟前
Qt技巧(三)编辑框嵌入按钮,系统位数判断,判断某对象是否属于某种类,控件取句柄,支持4K,巧用QEventLoop,QWidget的窗体样式
开发语言·qt
Niu_brave28 分钟前
Python基础知识学习(2)
开发语言·python·学习
时间幻灭‘31 分钟前
数据结构(2):LinkedList和链表[2]
数据结构·链表
_feivirus_41 分钟前
神经网络_使用TensorFlow预测气温
人工智能·神经网络·算法·tensorflow·预测气温
神仙别闹43 分钟前
基于C#+Mysql实现(界面)企业的设备管理系统
开发语言·mysql·c#
大柏怎么被偷了1 小时前
【C++算法】位运算
开发语言·c++·算法
程序猿方梓燚1 小时前
C/C++实现植物大战僵尸(PVZ)(打地鼠版)
c语言·开发语言·c++·算法·游戏
CPP_ZhouXuyang1 小时前
C语言——模拟实现strcpy
c语言·开发语言·数据结构·算法·程序员创富