【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行。因此,该代码将导致越界访问错误。

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

相关推荐
blammmp4 分钟前
Java:数据结构-枚举
java·开发语言·数据结构
何曾参静谧17 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
暗黑起源喵23 分钟前
设计模式-工厂设计模式
java·开发语言·设计模式
WaaTong27 分钟前
Java反射
java·开发语言·反射
Troc_wangpeng29 分钟前
R language 关于二维平面直角坐标系的制作
开发语言·机器学习
努力的家伙是不讨厌的30 分钟前
解析json导出csv或者直接入库
开发语言·python·json
Envyᥫᩣ44 分钟前
C#语言:从入门到精通
开发语言·c#
童先生1 小时前
Go 项目中实现类似 Java Shiro 的权限控制中间件?
开发语言·go
lulu_gh_yu1 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
Re.不晚2 小时前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea