【C】指针进阶(下)

指针进阶(二)

继上文,指针进阶(上)

这篇文章我们将结束指针进阶这一块知识~

文章目录

函数指针

函数指针是指向函数的指针变量。与指向变量和对象的指针类似,函数指针存储了函数的内存地址,可以用于间接调用该函数。函数指针的类型与函数的类型相匹配,包括返回类型和参数类型。

下面是一个简单的函数指针的示例:

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

int add(int a, int b) {
    return a + b;
}

int multiply(int a, int b) {
    return a * b;
}

int main() {
    int result;
    
    // 声明函数指针变量并初始化为指向add函数的指针
    int (*ptr)(int, int) = add; 

    // 通过函数指针调用add函数
    result = ptr(3, 4);
    printf("Addition result: %d\n", result);

    // 重新指向multiply函数
    ptr = multiply;

    // 通过函数指针调用multiply函数
    result = ptr(3, 4);
    printf("Multiplication result: %d\n", result);
    
    return 0;
}
//输出结果
Addition result: 7
Multiplication result: 12

在上面的示例中,我们声明了一个函数指针变量ptr,它的类型为int (*)(int, int),即指向参数为两个整数、返回类型为整数的函数指针。初始化时,我们将它指向了函数add,通过ptr间接调用add函数并打印结果。接着,将ptr重新指向了函数multiply,并再次通过ptr间接调用multiply函数并打印结果。

函数指针适用以下情况:

  1. 回调函数:函数指针可以作为参数传递给其他函数,用于实现回调机制。这使得函数能够在特定事件发生时调用传递的函数指针。
  2. 函数选择和切换:函数指针可以根据条件选择不同的函数来执行,从而实现函数的动态切换和选择。
  3. 函数数组:函数指针可以作为元素存储在数组中,通过数组索引可以方便地调用对应的函数。
  4. 函数指针表:函数指针可以作为函数指针表(函数指针数组)的一部分,提供多个函数以供选择和调用。

有意思的代码

c 复制代码
//代码1
(*(void (*)())0)();
//代码2
void (*signal(int , void(*)(int)))(int);
解读

代码1:(*(void (*)())0)();

这行代码使用函数指针调用一个地址为0的函数。在这里,(void (*)())是一个函数指针类型,表示指向返回类型为void,参数为空的函数。0表示一个空指针,(void (*)())0将地址为0的空指针强制转换为函数指针类型。最后,(*()语法对函数指针进行间接调用,()表示调用函数。由于这里的函数指针指向了空指针,实际上最终会引发一个错误,因为地址为0处没有有效的函数。

代码2:void (*signal(int, void(*)(int)))(int);

这行代码是一个函数声明,声明了一个名为signal的函数,该函数接受两个参数:一个整型参数和一个指向函数的指针参数,返回一个指向函数的指针。参数中的void(*)(int)表示接受一个整型参数并返回void的函数指针类型,整个返回类型void (*)(int)表示指向接受一个整型参数并返回void的函数的指针类型。

这行代码的功能是实现了一个用于处理信号的函数,它的参数包括信号的编号和一个指向信号处理函数的指针。函数signal的返回值是一个指向处理特定信号的函数的指针。


代码2简化:

c 复制代码
typedef void(*pfun_t)(int);
pfun_t signal(int, pfun_t);
  • void (*signal(int, void(*)(int)))(int);

这行代码声明了一个名为signal的函数,它接受两个参数:一个整型参数和一个指向接受整数参数并返回void的函数的指针。返回类型是指向接受整型参数并返回void的函数的指针。

这行代码的作用是定义一个函数,用于处理信号。它的参数包括信号的编号和一个指向信号处理函数的指针。函数signal根据传入的信号编号,返回一个指向处理该信号的函数的指针。

  • typedef void(*pfun_t)(int); pfun_t signal(int, pfun_t);

这段代码是对代码2的一种简化形式。首先,使用typedef关键字定义了一个新类型pfun_t,它是一个函数指针类型,表示指向接受整型参数并返回void的函数的指针。

然后,函数声明中使用这个新类型pfun_t来简化函数的返回类型和第二个参数的类型定义。相当于将代码1中的返回类型和第二个参数的部分提取出来,并用pfun_t代替。这样做的好处是可以增加代码的可读性和可维护性,使得函数声明更加清晰和简洁。

最终函数signal的作用与代码1中相同,用于处理信号,输入参数包括信号的编号和一个指向信号处理函数的指针,并返回一个指向处理该信号的函数的指针。

函数指针数组

函数指针数组是指一个数组,其中的每个元素都是一个函数指针 。换句话说,函数指针数组是一个存储了多个函数指针的数组变量

函数指针是一个指向函数的指针变量,它可以指向特定函数的起始地址。通过函数指针,我们可以在代码中动态地调用不同的函数。

函数指针数组的声明形式如下:

复制代码
返回类型 (*数组名[数组长度])(参数列表);

其中,返回类型是函数指针指向的函数的返回类型,*数组名[数组长度]表示一个函数指针数组的声明,参数列表表示函数指针指向的函数的参数列表。

下面是一个示例,展示了一个包含两个函数指针的函数指针数组的声明和使用:

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

void func1() {
    printf("This is function 1\n");
}

void func2() {
    printf("This is function 2\n");
}

int main() {
    void (*funcPtrArray[2])(); // 声明函数指针数组
    
    funcPtrArray[0] = func1;
    funcPtrArray[1] = func2;
    
    funcPtrArray[0](); // 调用函数指针数组的第一个函数指针,相当于调用函数 func1
    funcPtrArray[1](); // 调用函数指针数组的第二个函数指针,相当于调用函数 func2
    
    return 0;
}

运行这段代码会输出以下结果:

复制代码
This is function 1
This is function 2

这个示例定义了一个名为funcPtrArray的函数指针数组,包含两个函数指针元素。然后,将函数func1赋值给数组的第一个元素,将函数func2赋值给数组的第二个元素。通过调用函数指针数组中的函数指针,实际上是调用了对应的函数。

函数指针数组的用途:转移表

下面我们看一个例子:写一个计算器

c 复制代码
#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;
}

我们换成函数指针数组实现:

c 复制代码
#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 }; //转移表
     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;
}

指向函数指针数组的指针

指向函数指针数组的指针是一个 指针

指针指向一个 数组 ,数组的元素都是 函数指针。

当我们有一个函数指针数组时,我们可以定义一个指向该数组的指针,这个指针指向函数指针数组的首地址。通过这个指针,我们可以访问和操作函数指针数组中的元素。

下面是一个示例:

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

void func1() {
    printf("This is function 1\n");
}

void func2() {
    printf("This is function 2\n");
}

int main() {
    void (*funcPtrArray[2])() = {func1, func2}; // 定义函数指针数组并初始化
    void (*(*ptrToArray)[2])() = &funcPtrArray; // 定义指向函数指针数组的指针,并将其指向函数指针数组的地址
    
    // 通过指针访问函数指针数组中的元素
    (*ptrToArray)[0](); // 调用函数指针数组的第一个元素,相当于调用函数 func1
    (*ptrToArray)[1](); // 调用函数指针数组的第二个元素,相当于调用函数 func2
    
    return 0;
}

运行这段代码会输出以下结果:

复制代码
This is function 1
This is function 2

在这个示例中,我们首先定义了一个包含两个函数指针元素的函数指针数组 funcPtrArray,并且使用两个函数 func1func2 对其进行初始化。

然后,通过将 funcPtrArray 的地址赋给指向函数指针数组的指针 ptrToArray,我们创建了一个指向函数指针数组 funcPtrArray 的指针 ptrToArray

通过使用 (*ptrToArray)[0] 来访问函数指针数组的第一个元素,并且使用 (*ptrToArray)[1] 来访问函数指针数组的第二个元素,并通过调用函数指针来执行相应的函数。

通过指向函数指针数组的指针,我们可以在运行时动态地访问和操作函数指针数组中的元素,这为灵活地处理函数指针数组提供了一种方式。

回调函数

回调函数是指在编程中,将一个函数作为参数传递给另一个函数,并在后者内部调用该函数的过程。回调函数的使用可以增加代码的灵活性和扩展性,使得代码模块化,易于维护和重用。

一个常见的应用场景是在事件处理机制中,当某个事件发生时,调用传递的回调函数来处理事件。回调函数可以根据需要进行定义和实现,提供了一种在运行时动态决定代码行为的机制。

下面给个例子:

首先,我们需要定义一个函数类型作为回调函数的类型。函数类型定义的一般形式是:返回类型 (*函数类型名称)(参数列表)。

例如,假设我们有一个回调函数类型 CallbackFunc,定义如下:

c 复制代码
typedef void (*CallbackFunc)(int);

在这个例子中,我们定义了一个返回类型为 void,参数为 int 的回调函数类型 CallbackFunc

接下来,我们可以编写一个接收回调函数作为参数的函数,如下所示:

c 复制代码
void performTask(int value, CallbackFunc callback) {
    // 执行任务
    printf("Performing task with value %d\n", value);
    
    // 调用回调函数
    callback(value);
}

performTask 函数中,我们执行了某些任务,并将传递给该函数的 value 参数作为参数调用了传递的回调函数 callback

最后,我们可以定义和实现一个具体的回调函数,然后将其作为参数传递给 performTask 函数,如下所示:

c 复制代码
void callbackFunction(int value) {
    printf("Callback function called with value %d\n", value);
}

int main() {
    int value = 10;
    performTask(value, callbackFunction);
    
    return 0;
}

main 函数中,我们定义了一个值 value,然后将 callbackFunction 作为回调函数传递给了 performTask 函数。

运行这段代码,会输出以下结果:

复制代码
Performing task with value 10
Callback function called with value 10

在运行时,首先调用了 performTask 函数,输出了任务执行的信息。然后,在 performTask 函数内部调用了回调函数 callbackFunction,并将传递的 value 参数作为参数传递给回调函数。回调函数执行后,输出了相应的信息。

注意

在使用回调函数时,我们需要确保回调函数的定义和声明与预期的函数指针类型相匹配,以确保参数类型和返回类型的一致性。

指针和数组例题

例题1

一维数组

c 复制代码
//一维数组
int a[] = {1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));

解析:

  1. printf("%d\n",sizeof(a));sizeof(a) 返回整个数组的大小。在这种情况下,数组 a 所占的总字节数为 16 (4个整型元素每个占4个字节)。因此,输出结果为 16

  2. printf("%d\n",sizeof(a+0));a+0 是一个指针,指向数组 a 的第一个元素。sizeof(a+0) 返回指针的字节数,无论指针指向数组还是其他类型的对象,指针本身所占的字节数是固定的。在大多数系统上,指针占用的字节数通常为4或8。因此,输出结果为 48

  3. printf("%d\n",sizeof(*a));*a 是数组 a 的第一个元素的值。sizeof(*a) 返回元素类型的大小,即 int 类型所占的字节数。通常情况下,在大多数系统上, int 类型占用的字节数为 4。因此,输出结果为 4

  4. printf("%d\n",sizeof(a+1));a+1 是一个指针,指向数组 a 的第二个元素。与上述第二个例子类似,指针所占的字节数固定,在大多数系统上为 4 或 8。因此,输出结果为 48

  5. printf("%d\n",sizeof(a[1]));a[1] 是数组 a 的第二个元素的值。sizeof(a[1]) 返回元素类型的大小,与第三个例子中 sizeof(*a) 的输出结果相同,为 4

  6. printf("%d\n",sizeof(&a));&a 是指向整个数组 a 的指针。sizeof(&a) 返回指针的字节数大小,与第二个例子中 sizeof(a+0) 的输出结果相同,为 48

  7. printf("%d\n",sizeof(*&a));*&a 实际上是数组 a 本身,所以 *(&a) 等价于 a。因此,sizeof(*&a) 返回整个数组的大小,与第一个例子中 sizeof(a) 输出结果相同,为 16

  8. printf("%d\n",sizeof(&a+1));&a+1 是一个指针,指向数组 a 之后的位置。与第二个和第四个例子相似,指针的字节数大小固定,在大多数系统上为 4 或 8。因此,输出结果为 48

  9. printf("%d\n",sizeof(&a[0]));&a[0] 是指向数组 a 的第一个元素的指针。sizeof(&a[0]) 返回指针的字节数大小,与第二个例子中 sizeof(a+0) 输出结果相同,为 48

  10. printf("%d\n",sizeof(&a[0]+1));&a[0]+1 是一个指针,指向数组 a 的第二个元素的位置。与第二个和第四个例子类似,指针的字节数大小固定,在大多数系统上为 4 或 8。因此,输出结果为 48

总结起来,sizeof 运算符返回的是一个对象或类型所占的字节数。对于数组名,sizeof 返回的是整个数组所占的字节数;对于指针和数组元素,sizeof 返回的是指针或元素类型的字节数。需要注意的是,sizeof

例题2

c 复制代码
//字符数组
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));

printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));

char arr[] = "abcdef";
printf("%d\n", sizeof(arr));
printf("%d\n", sizeof(arr+0));
printf("%d\n", sizeof(*arr));
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
printf("%d\n", sizeof(&arr+1));
printf("%d\n", sizeof(&arr[0]+1));

printf("%d\n", strlen(arr));
printf("%d\n", strlen(arr+0));
printf("%d\n", strlen(*arr));
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
printf("%d\n", strlen(&arr[0]+1));

char *p = "abcdef";
printf("%d\n", sizeof(p));
printf("%d\n", sizeof(p+1));
printf("%d\n", sizeof(*p));
printf("%d\n", sizeof(p[0]));
printf("%d\n", sizeof(&p));
printf("%d\n", sizeof(&p+1));
printf("%d\n", sizeof(&p[0]+1));

printf("%d\n", strlen(p));
printf("%d\n", strlen(p+1));
printf("%d\n", strlen(*p));
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
printf("%d\n", strlen(&p+1));
printf("%d\n", strlen(&p[0]+1));

解析:

  1. printf("%d\n", sizeof(arr)); 输出结果为 6sizeof(arr) 返回的是 arr 数组的大小,而不是数组元素的数量。
  2. printf("%d\n", sizeof(arr+0)); 输出结果为 4sizeof(arr+0) 返回的是指针 arr+0 的大小,即 sizeof(char*)
  3. printf("%d\n", sizeof(*arr)); 输出结果为 1*arr 相当于 arr[0],即返回数组中第一个元素的大小。
  4. printf("%d\n", sizeof(arr[1])); 输出结果为 1arr[1] 返回数组中第二个元素的大小。
  5. printf("%d\n", sizeof(&arr)); 输出结果为 4&arr 返回的是数组指针的大小,即 sizeof(char(*)[6])
  6. printf("%d\n", sizeof(&arr+1)); 输出结果为 4&arr+1 返回的是指向下一个数组的指针大小。
  7. printf("%d\n", sizeof(&arr[0]+1)); 输出结果为 4&arr[0]+1 返回的是指向下一个字符的指针大小。
  8. printf("%d\n", strlen(arr)); 输出结果为 6strlen(arr) 返回的是字符串的长度,以空字符 \0 结尾。
  9. printf("%d\n", strlen(arr+0)); 输出结果为 6strlen(arr+0) 返回的是字符串的长度,以空字符 \0 结尾,arr+0 是指向 arr 字符串的指针。
  10. printf("%d\n", strlen(*arr)); 输出结果为 Error*arr 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  11. printf("%d\n", strlen(arr[1])); 输出结果为 Errorarr[1] 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  12. printf("%d\n", strlen(&arr)); 输出结果为 4strlen(&arr) 返回的是字符串的长度,以空字符 \0 结尾,&arr 是指向 arr 字符串的指针。
  13. printf("%d\n", strlen(&arr+1)); 输出结果为 Error&arr+1 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  14. printf("%d\n", strlen(&arr[0]+1)); 输出结果为 5strlen(&arr[0]+1) 返回的是从 &arr[0]+1 开始的字符串的长度,以空字符 \0 结尾。
  15. printf("%d\n", sizeof(p)); 输出结果为 4sizeof(p) 返回的是指针 p 的大小,即 sizeof(char*)
  16. printf("%d\n", sizeof(p+1)); 输出结果为 4sizeof(p+1) 返回的是指针 p+1 的大小,即 sizeof(char*)
  17. printf("%d\n", sizeof(*p)); 输出结果为 1*p 相当于 p[0],即返回指针 p 指向的字符的大小。
  18. printf("%d\n", sizeof(p[0])); 输出结果为 1p[0] 返回指针 p 指向的字符的大小。
  19. printf("%d\n", sizeof(&p)); 输出结果为 4&p 返回的是指向指针 p 的指针大小,即 sizeof(char**)
  20. printf("%d\n", sizeof(&p+1)); 输出结果为 4&p+1 返回的是指向下一个指针的指针大小。
  21. printf("%d\n", sizeof(&p[0]+1)); 输出结果为 4&p[0]+1 返回的是指向下一个字符的指针大小。
  22. printf("%d\n", strlen(p)); 输出结果为 6strlen(p) 返回的是字符串的长度,以空字符 \0 结尾。
  23. printf("%d\n", strlen(p+1)); 输出结果为 5strlen(p+1) 返回的是从 p+1 开始的字符串的长度,以空字符 \0 结尾。
  24. printf("%d\n", strlen(*p)); 输出结果为 Error*p 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  25. printf("%d\n", strlen(p[0])); 输出结果为 Errorp[0] 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  26. printf("%d\n", strlen(&p)); 输出结果为 Error&p 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  27. printf("%d\n", strlen(&p+1)); 输出结果为 Error&p+1 在此处是无效的,因为 strlen() 函数接受的参数应为一个指针类型。
  28. printf("%d\n", strlen(&p[0]+1)); 输出结果为 5strlen(&p[0]+1) 返回的是从 &p[0]+1 开始的字符串的长度,以空字符 \0 结尾。

例题3

c 复制代码
//二维数组
int a[3][4] = {0};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
printf("%d\n",sizeof(a[0]+1));
printf("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(*(a+1)));
printf("%d\n",sizeof(&a[0]+1));
printf("%d\n",sizeof(*(&a[0]+1)));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a[3]));

解析:

  1. printf("%d\n",sizeof(a)); 输出结果为 48sizeof(a) 返回的是二维数组 a 的大小,即 sizeof(int[3][4])。在这种情况下,数组的大小为3行4列,每个元素的大小为 sizeof(int)。因此,总大小为 3 * 4 * sizeof(int),即 48
  2. printf("%d\n",sizeof(a[0][0])); 输出结果为 4sizeof(a[0][0]) 返回的是二维数组 a[0][0] 单个元素的大小,即 sizeof(int)
  3. printf("%d\n",sizeof(a[0])); 输出结果为 16sizeof(a[0]) 返回的是一维数组 a[0] 的大小,即 sizeof(int[4])。在这种情况下,一维数组的大小为4个元素,每个元素的大小为 sizeof(int)。因此,总大小为 4 * sizeof(int),即 16
  4. printf("%d\n",sizeof(a[0]+1)); 输出结果为 4sizeof(a[0]+1) 返回的是指针 a[0]+1 的大小,即 sizeof(int*)
  5. printf("%d\n",sizeof(*(a[0]+1))); 输出结果为 4sizeof(*(a[0]+1)) 返回的是指针 a[0]+1 所指向的元素的大小,即 sizeof(int)
  6. printf("%d\n",sizeof(a+1)); 输出结果为 4sizeof(a+1) 返回的是指针 a+1 的大小,即 sizeof(int(*)[4])。指针 a+1 实际上指向第二行。
  7. printf("%d\n",sizeof(*(a+1))); 输出结果为 16sizeof(*(a+1)) 返回的是指针 a+1 所指向的一维数组的大小,即 sizeof(int[4])。在这种情况下,一维数组的大小为4个元素,每个元素的大小为 sizeof(int)。因此,总大小为 4 * sizeof(int),即 16
  8. printf("%d\n",sizeof(&a[0]+1)); 输出结果为 4sizeof(&a[0]+1) 返回的是指针 &a[0]+1 的大小,即 sizeof(int(*)[4])。指针 &a[0]+1 实际上指向第二行。
  9. printf("%d\n",sizeof(*(&a[0]+1))); 输出结果为 16sizeof(*(&a[0]+1)) 返回的是指针 &a[0]+1 所指向的一维数组的大小,即 sizeof(int[4])。在这种情况下,一维数组的大小为4个元素,每个元素的大小为 sizeof(int)。因此,总大小为 4 * sizeof(int),即 16
  10. printf("%d\n",sizeof(*a)); 输出结果为 16sizeof(*a) 返回的是指针 a 所指向的一维数组的大小,即 sizeof(int[4])。在这种情况下,一维数组的大小为4个元素,每个元素的大小为 sizeof(int)。因此,总大小为 4 * sizeof(int),即 16
  11. printf("%d\n",sizeof(a[3])); 输出结果为 Errora[3] 超出了数组 a 的范围,因为数组 a 只有3行。因此,该代码将导致越界访问错误。

至此,指针就讲到到这了~接下来会持续更新,敬请期待

相关推荐
Scott9999HH5 小时前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
码智社6 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海6 小时前
python 列表、元组、集合和字典
开发语言·python
萧瑟余晖7 小时前
JDK 26 新特性详解
java·开发语言
马优晨7 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
人邮异步社区9 小时前
怎么把C语言学到精通?
c语言·开发语言
心平气和量大福大10 小时前
C#-WPF-控件-TextBox 数据绑定
开发语言·c#·wpf
ttwuai10 小时前
Cursor 生成 CRUD 后,Go 后台接口别只测 200:JWT、RBAC 和 tenant_id 怎么验
开发语言·后端·golang
এ慕ོ冬℘゜10 小时前
前端基础:什么是时间戳?JS获取时间戳三种方法与实战用途
开发语言·前端·javascript
执明wa10 小时前
LayoutInflater详解: XML是如何变成View的?
android·xml·开发语言·android studio