C语言学习笔记---指针

C语言学习笔记—指针

未完待续

指针

  • 内存单元是存储数据的具体实体;
  • 地址是用于定位内存单元的唯一标识;
  • 数据则是存放在具有特定地址的内存单元中的具体信息。

为了有效存取一个数据,除了需要知道位置信息,还需要有该数据的类型信息。因为只知道了地址信息,不知道大小是多少,我可以取四个字节当int型,取1个字节当char型。一般C语言上的地址是指带类型的地址。

指针即变量的地址

指针变量即存放变量地址的变量

在定义指针变量时必须指定基类型

* : 取值操作符(指针运算符、间接访问符), *p代表变量p指向的对象

& : 取址操作符,&a 是变量a的地址

int i=200;
printf("直接访问变量i的值:%d",i);

int* pointer;                                    // 这里的 * 表明是指针变量
pointer = &a;                                    // 这里的 & 是取址操作符,  &a 整型变量a的地址 
printf("间接访问变量i的值:%d\n",*pointer);        // 这里的 * 是取值操作符

指针变量

定义
类型名 *指针变量名
float a=3.14;
float *pointer_1;
float *pointer_2=&a;
pointer_1=&a;          
*pointer_1 = &a;        '错误的',即pointer_1是变量a           

在定义指针变量时,左侧应有类型名,否则就不是定义指针变量。指针变量依此从指针中获取变量的值

指针变量前面的 * 表示该变量是指针变量。指针变量名是pointer_1,而不是 *pointer_1

指针变量的赋值:pointer_1=&a;而不是 *pointer_1=&a; 后者代表是变量a,*代表的是取值操作符,取变量a地址上的值给pointer_1。会报错

指针变量只能存放地址 (指针)

引用
  • 给指针变量赋值

    p = &a;            // 把a的地址
    指针变量p的值就是变量a的地址,p指向a(即*p是a变量,相当于*p是变量a的别名)
    
  • 引用指针变量指向的指针

    printf("%d",*p);
    以整数形式输出指针变量p所指向的变量的值
    *p = 1;
    将整数1赋给p当前所指向的变量
    
  • 引用指针变量的值

    printf("p=%p",p);
    输出指针变量p的值,即指针变量所存储的内存地址
    

指针变量作函数参数

指针类型作为函数的参数,它的作用是将一个变量的地址传送到另一个函数中。这样就可以做到修改实参的值。(函数的形参是值传递的)。

C语言中实参变量和形参变量之间的数据传递时单向的 “值传递方式”,用指针变量作函数参数时同意要遵循这一规则,不能企图通过改变指针形参的值而是指针实参的值改变。但是可以改变实参指针变量所指变量的值

例如:

对输入的两个整数按大小顺序输出

#include<stdio.h>

int main() {
    void swap(int* p1, int* p2);
    int a=5, b=9;
    int* pointer_1, * pointer_2;
    pointer_1 = &a;
    pointer_2 = &b;
    if (a < b) {
        swap(pointer_1, pointer_2);                // 依然是值传递,传的是a和b的地址
    }
    printf("max=%d,min=%d\n", *pointer_1, *pointer_2);
    return 0;
}

void swap(int* p1, int* p2) {
    int *temp;
    temp = p1;                    // 这里的p1和p2只是swap函数里的局部变量,使用完swap函数后自动销毁。是实参创造出的副本,动副本的值并不改变原来的
    p1 = p2;                    
    p2 = temp;                    
}

结果:
max=5,min=9

指针引用数组元素

所谓数组元素指针就是数组元素的地址。

C语言中,数组名(不包括形参数组名)只代表数组中首元素(即序号为0的元素)的地址,不代表整个数组。

引用数组元素的方法:

  • 下标法,如a[3]

  • 指针法,如 *(a+i) 或 *(p+i) 即通过指向数组元素的指针找到所需的元素。使用指针法能够使目标程序质量高(占内存少,运行速度快)

    • 通过数组名计算数组元素地址,找出元素的指

    • 用指针变量指向数组元素

三种方法比较,第一种和第二种执行效率相同。编译器将a[i]转换为 *(a+i) 处理的,所以方法一和方法二找数组元素费时较多;第三种方法用指针变量直接指向元素,不必每次都重新计算地址,像p++这样的自加操作时比较快的。

  • 可以通过改变指针变量的值指向不同的元素,数组名不行,因为数组名代表数组首元素的地址,它是一个指针常量,它的值在程序运行期间是固定不变的

  • 在使用指针变量指向数组元素时,应切实保证指向的数组中有效的元素,如果超出了数组的长度编译器不会报错,会产生不必要的麻烦。

  • 指向数组元素的指针变量也可以带下标,如 p[i] ;因为编译器会自动把下标处理成 *(p+i) 的形式

下面两句等价
p = &a[0];            // 把数组a的首元素的地址赋给指针变量p
p = a;

int *p=&a[0];
等价于
int *p;
p=&a[0];
等价于
int *p=a;
指针的运算

当指针指向数组元素的时候,指针的加减运算才有意义。

当指针指向一个数组元素是:

  • 加一个整数(用+或+=),如p+1,是只p当前所指的数组元素的下一个元素(的地址),执行p+1不是单纯的加一,而是加上一个数组元素所占的字节数;

  • 减一个整数(用-或-=),如p-1;

  • 自加运算,如p++,++p;

  • 自减运算,如p–,–p;

两指针相减,如p1-p2,只有p1和p2都指向同一数组中的元素才有意义,代表着两个地址之差除以数组元素的长度,这样就可以知道两个元素的相对距离。

p1+p2;无意义

如果p的初值是&a[0],那么 p+i 和 a+i 就是数组元素 a[i] 的地址,*(p+i) 和 *(a+i) 就是所指向的数组元素 a[i] 。

使用指针引用数组元素的几个情况:

  • p++;                    // 是指针p指向下一个元素
    *p;                     // 输出下一个元素的#### 用数组名作为函数的参数
    
  • *p++; 与 *(p++)
    由于++与*同优先级,结合方向自右向左,等价于 *(p++); 先引用p的值,再p指向下一个元素。

    下面的两个代码片段是等价的
    for(i=0;i<10;i++,p++) {
        printf("%d",*p);
    }
    
    for(i=0;i<20;i++) {
        printf("%d",*p++);
    }
    
  • *(++p) ,先使p指向下一个元素,再取 *p(获取该元素的值)

  • ++(*p),表示p所指向的元素加一

  • 如果p当前指向a数组中第i个元素a[i],则:

    • *(p–) 相当于 a[i–]

    • *(++p) 相当于 a[++i]

    • *(–p) 相当于a[–i]

// 输出数组a的前100个元素
p=a;
while(p<a+100) {
  printf("%d ",*p++);
}
// 或
p=a;
while(p<a+100) {
    printf("%d ",*p);
    p++;
}

扩展: ++i 和 i++ 的用法

i++ : 先使用 i 的值,在使 i 自增1

++i : 先自增1,在使用 i 的值(此时的 i 的值比原先多1)

*(p++) : 先使用 *p 的值,再使p指向下一个元素

*(++p) : 先使p指向下一个元素,再使用 *p 的值

用数组名作函数的参数

当用数组名作为参数时,如果形参数组中元素的值发生改变,那么实参数组元素的值也发生改变。

实参数组名代表该数组首元素的地址,而形参是用来接受从实参传递过来的数组首元素的地址。实际上,C编译器将形参数组名作为指针变量来处理。例如:

foo(int arr[],int n) {......}
相当于
foo(int *arr,int n) {......}

常用这种方向通过调用一个函数来改变实参数组的值。

实参书数组名代表一个固定的地址,是指针常量,而形参数组名不是一个固定的地址,按照指针变量处理。

例如:

// 当用数组名作为参数时,如果形参数组中元素的值发生改变,那么实参数组元素的值也发生改变。
#include<stdio.h>

void func(int arr[], int n);

int main() {
    int arr[10] = { 0,1,2,3,4,5,6,7,8,9 };
    for (int i = 0; i < 10; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    func(arr, 10);
    return 0;
}

void func(int arr[],int n) {
    printf("%d\n", *arr);
    arr = arr + 3;
    printf("%d\n", *arr);
}

如果有一个实参数组,要想再函数中改变此数组中元素的值,实参与形参的对应关系有以下4种情况。

  1. 形参和实参都用数组名
    可以认为在函数调用期间,形参数组与实参数组公用一段内存单元。

    int main() {
        int a[10];
        foo(a,10)
    }
    int foo(int x[],int n){......}
    
  2. 实参用数组名,形参用指针变量

    int main() {
        int a[10];
        foo(a,10)
    }
    int foo(int *x,int n){......}
    
  3. 实参形参都用指针变量

    int main() {
        int a[10],*p=a;
        foo(a,10)
    }
    int foo(int *x,int n){......}
    
  4. 实参为指针变量,形参为数组名

    int main() {
        int a[10],*p=a;
        foo(a,10)
    }
    int foo(int x[],int n){......}
    

如果用指针变量作实参,必须先使指针变量有明确的值,指向一个已有的对象

通过指针引用多维数组

例如二维数组a[3][4],a[1]代表这是第二列,是一个一维数组,是第二列第一个元素的首地址;a[1][1] 代表的是第二行第二列的元素。

a[1] 和 *(a+1) 等价

a[i] 和 *(a+i) 等价

a[0]+1 和 *(a+0)+1 代表着是第一列的第二个元素的地址,等价于&a[0[1]

*(a+1)+2 ≠ *(a+1+2),后者等于 *(a+3) 是第四列首元素的地址;前者是 a[1][2] 的地址,等于&a[1][2]

输出二维数组的有关数据(地址和元素的值)

#include <stdio.h>

int main() {
    int a[3][4] = { 1,3,5,7,9,11,13,15,17,19,21,23 };
    printf("%p,%p\n", a, *a);                    // 0行起始地址和0行0列元素的地址
    printf("%p,%p\n", a[0], *(a + 0));            // 0行0列元素地址
    printf("%p,%p\n", &a[0], &a[0][0]);            // 0行起始地址和0行0列元素的地址
    printf("%p,%p\n", a[1], a + 1);                // 1行0列元素地址和1行的起始地址
    printf("%p,%p\n", &a[1][0], *(a + 1) + 0);    // 1行0列元素地址
    printf("%p,%p\n", a[2],*(a+2));                // 2行0列元素的地址
    printf("%p,%p\n", &a[2],a+2);                // 2行起始地址
    printf("%d,%d\n", a[1][0],*(*(a+1)+0));        // 1行0列元素的值
    printf("%d,%d\n", *a[2],*(*(a+2)+0));        // 第2行0列元素的值
    return 0;
}

二维数组名(如a)是指向行(一维数组)的。因此 a+1 中的 ”1“ 代表一行中全部元素所占的字节数。

一维数组名(如 a[0])是指向列元素的值。a[0]+1 代表 a 中一个元素所占的字节数。

例如:a 和 a+1 是指向行的指针,在它们面前加一个 * 就是 *a 和 *(a+1) ,它们就成为列的指针,分别指向a数组0行0列元素和1行0列元素。

在指向列的指针前面加 & ,就成为了指向行的指针,如 &a[0] 与 &*a与a等价,都指向二维数组的0行。

在指向列的指针前面加 * 就是获取该行该列的元素的值,如 *(*a+1)+1就是1行1列元素的值。

反正就是,不要简单地认为 *(a+i)是 a+i 所指单元中的内容。在一维数组中是正确的,但在二维数组中 a+i 不是指向具体存储单元的而是指向行(即一维数组,也可看做一维数组首元素的地址)。

在二维数组中, a+i 、 a[i] 、*(a+i) 、&a[i]、&a[i][0]的值是向相等的,即它们代表同一地址,但基类型不同。

#include<stdio.h>

int main() {
    void print_array2(int a[3][4]);
    void print_array22(int a[][4], int r);
    void print_array23(int a[], int r, int c);
    void print_array1(int a[], int n);
    int a[3][4] = { {1,3,5,7},{2,4,6,8},{1,2,3,4} };
    print_array2(a);
    print_array22(a, 3);
    print_array23(a, 3, 4);
    print_array1(a[0], 4);                // a[0]代表的是第一列的第一个元素的地址
    print_array1(*(a + 1), 4);            // a[1]与*(a+1)等价,同理a[i]和*(a+i)是等价的
    printf("%d\n", *(a[1] + 2));
    printf("%d\n", *(*(a + 1) + 2));    // *(a+1)+2=a[1]+2=&a[1][2]是第二列的第三个元素的`地址`    
    printf("%d\n", a[0][0]);

    return 0;
}

/// 打印二维数组
void print_array2(int a[3][4]) {
    printf("{");
    for (int i = 0; i < 3; i++) {
        printf(" { ");
        for (int j = 0; j < 4; j++) {
            printf("%d ", a[i][j]);
        }
        printf("}");
    }
    printf(" }\n");
}

void print_array22(int a[][4], int r) {
    printf("{");
    for (int i = 0; i < r; i++) {
        printf(" { ");
        for (int j = 0; j < 4; j++) {
            printf("%d ", a[i][j]);
        }
        printf("}");
    }
    printf(" }\n");
}

void print_array23(int a[], int r,int c) {
    printf("{");
    for (int i = 0; i < r; i++) {
        printf(" { ");
        for (int j = 0; j < c; j++) {
            printf("%d ", *(a+i*c+j));
        }
        printf("}");
    }
    printf(" }\n");
}

/// 打印一维数组
void print_array1(int a[],int n) {
    printf(" { ");
    for (int j = 0; j < n; j++) {
        printf("%d ", a[j]);
    }
    printf("}\n");
}
指向多维数组的元素的指针变量
  • 指向数组元素的指针变量
    有一个 3x4 的二维数组,要求用指向元素的指针输出二维数组各元素的值

    #include<stdio.h>
    
    int main() {
        int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
        int* p;
        for (p = a[0]; p < a[0] + 12; p++) {
            if ((p - a[0]) % 4 == 0) {
                printf("\n");
            }
            printf("%4d", *p);
        }
        printf("\n");
        p = &a;                                 // 等价与 p=a;p=a[0];
        printf("a[1][3]=%d\n", *(p + 1 * 4 + 3));        // a[i][j]的相对位置计算公式:i*m+j;m为二维数组的列数 
        return 0;
    }
    
    
  • 指向由m个元素组成的一维数组的指针变量

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值警告
#include<stdio.h>

int main() {
	int a[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
	int(*p)[4],i,j;	// 注:(*p)[4] ≠ *p[4];前者代表`指针变量`指向包含4个整型元素的一维数组,后者是`指针数组`
	// 可以把它看作是int a[4];*p=a;
	p = a;
	printf("please enter row and colum:");
	scanf("%d %d", &i, &j);
	printf("a[%d][%d]=%d\n", i, j, *(*(p + i) + j));
	return 0;
}
return 0;
}

指针引用字符串

举例

通过指针变量访问整型数据

#include<stdio.h>

int main() {
    int a = 100, b = 10;
    int* pointer_1, * pointer_2;
    pointer_1 = &a;
    pointer_2 = &b;
    printf("a=%d b=%d\n", a, b);
    printf("*pointer_1=%d  *pointer_2=%d\n", *pointer_1, *pointer_2);
    printf("pointer_1=%p  pointer_2=%p\n", pointer_1, pointer_2);        // 存储的是内存单元的地址,不包括类型信息
    return 0;
}

输入a和b两个整数,按先后大小的顺序输出a和b

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值警告

#include<stdio.h>

int main() {
    int* p1, * p2, * p, a, b;
    printf("please enter two interger numbers:");
    scanf("%d %d", &a, &b);
    p1 = &a;
    p2 = &b;
    if (a < b) {
        p = p1;
        p1 = p2;
        p2 = p;
    }
    printf("a=%d,b=%d,\n", a, b);
    printf("max=%d,min=%d\n", *p1, *p2);
    return 0;
}

用函数处理且用指针类型的数据作为函数的参数,输入a和b两个整数,按先后大小的顺序输出a和b

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值警告

#include<stdio.h>

int main() {
    void swap(int* p1, int* p2);
    int a, b;
    int* pointer_1, * pointer_2;
    printf("please enter a and b:");
    scanf("%d %d", &a, &b);
    pointer_1 = &a;
    pointer_2 = &b;
    if (a < b) {
        swap(pointer_1, pointer_2);          // 依然是值传递,传的是a和b的地址
    }
    printf("max=%d,min=%d\n", a, b);
  printf("max=%d,min=%d\n", *pointer_1, *pointer_2);
    printf("a=%d,b=%d\n", a, b);
    return 0;
}

void swap(int* p1, int* p2) {
    int temp;
    temp = *p1;                         // p1 <-> a
    *p1 = *p2;                          // p2 <-> b
    *p2 = temp;
}

输入3个整数a,b,c,要求由大到小的顺序将他们输出

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值警告

#include<stdio.h>

int main() {
    void exchange(int* q1, int* q2, int* q3);
    int a, b, c, * p1, * p2, * p3;
    printf("please enter three number: ");
    scanf("%d %d %d", &a, &b, &c);
    p1 = &a;
    p2 = &b;
    p3 = &c;
    exchange(p1, p2, p3);
    printf("the order is: %d,%d,%d\n", a, b, c);
    return 0;
}

void exchange(int* q1, int* q2, int* q3) {
    void swap(int* p1, int* p2);
    if (*q1 < *q2) {
        swap(q1, q2);
    }if (*q1 < *q3) {
        swap(q1, q3);
    }if (*q2 < *q3) {
        swap(q2, q3);
    }
}

void swap(int* p1, int* p2) {                
    int temp;
    temp = *p1;
    *p1 = *p2;                    
    *p2 = temp;                    
}

有一个整型数组a,有10个元素,要求输出数组中的全部元素

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值警告

#include<stdio.h>
/*
    通过指针引用数组元素的三种方法
    - 下标法
    - 通过数组名计算数组元素地址,找出元素的指
    - 用指针变量指向数组元素
*/

int main() {
    int a[10];
    int i, * p;
    printf("please enter 1o integer numbers: ");
    //for ( i = 0; i < 10; i++) {
    //    scanf("%d", &a[i]);            // 或用 a+i
    //    //scanf("%d", a + i);
    //}
    // 或
    for (p = a; p < (a + 10); p++) {
        scanf("%d", p);
    }

    for ( i = 0; i < 10; i++) {
        printf("%d ", a[i]);        // 数组元素用数组名和下标表示
    }
    printf("\n");
    for (i = 0; i < 10; i++) {
        printf("%d ", *(a + i));    // 通过数组名和元素序号计算元素地址,再找该元素
    }
    printf("\n");
    for (p = a; p < (a + 10); p++) {
        printf("%d ", *p);            // 用指针指向当前的数组元素 
    }

    printf("\n");
    return 0;
}

错误分析:通过指针变量输出整型数组a的10个元素

#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:4996) // 禁止显示strcpy等不安全函数的警告
#pragma warning(disable:6031) // 禁止显示未经检查的返回值
#include<stdio.h>

int main() {
    int* p, i, a[10];
    p = a;
    printf("please enter 10 integer numbers: ");
    for ( i = 0; i < 10; i++) {
        scanf("%d", p++);                                
    }                                                // 此时p指向a的最后一个元素,需要使p重新指向数组元素a[0]
    //p = &a[0];
    for ( i = 0; i < 10; i++,p++) {
        printf("%d ", *p);
    }
    printf("\n");
    return 0;
}

// 输入:0 1 2 3 4 5 6 7 8 9
// 输出:-858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460 -858993460

将数组a中n个整数按相反顺序存放,三种方式


#include<stdio.h>

int main() {
    void inv(int x[], int n);
    void inv1(int *x, int n);
    int i, a[10] = { 3,7,9,11,0,6,7,5,4,2 },*p=a;         // 如果用指针变量作实参,必须先使指针变量有明确的值,指向一个已有的对象
    printf("the orginal array:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");


    inv(a, 10);                                    // 数组名作为实参
    printf("the array has benn inverted:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");


    inv1(a, 10);                                // 数组名作为实参
    printf("the array has benn inverted:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");


    inv1(p, 10);                                // 指针变量作为实参
    printf("the array has benn inverted:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

void inv(int x[], int n) {                    // 用数组名作为形参
    int temp, i, j, m = (n - 1) / 2;
    for (i = 0; i <= m; i++) {
        j = n - 1 - i;
        temp = x[i];
        x[i] = x[j];
        x[j] = temp;
    }
}

void inv1(int *x, int n) {                        // 用指针变量作为形参
    int *p,temp, *i, *j, m = (n - 1) / 2;
    i = x; j = x + n - 1; p = x + m;
    for ( ; i <= p; i++, j--) {
        temp = *i;
        *i = *j;
        *j = temp;
    }
}

用指针方法对10个整数按由大到小顺序排序

#include<stdio.h>

int main() {
    void sort(int x[], int n);        // 用数组名作为形参,用a[i](下标法)引用数组元素
    void sort1(int x[], int n);        // 用指针变量作形参,用*(p+i)引用数组元素
    int i, * p, a[10];
    p = a;
    printf("please enter 10 integer numbers:");
    for (int i = 0; i < 10; i++) {
        scanf("%d", p++);
    }
    p = a;                        // 使p指向数组首元素
    sort1(p, 10);
    for ( p=a, i = 0; i < 10; i++) {
        printf("%d ", *p);
        p++;
    }
    printf("\n");
    return 0;
}

void sort(int x[], int n) {
    int i, j, k, t;
    for (i = 0; i < n - 1; i++) {
        k = i;
        for (j = i + 1; j < n; j++) {
            if (x[j] > x[k]) {
                k = j;
            }
            if (k != i) {
                t = x[i];
                x[i] = x[k];
                x[k] = t;
            }
        }
    }
}

void sort1(int *x, int n) {
    int i, j, k, t;
    for (i = 0; i < n - 1; i++) {
        k = i;
        for (j = i + 1; j < n; j++) {
            if (*(x + j) > *(x + k)) {
                k = j;
            }
            if (k != i) {
                t = *(x + i);
                *(x + i) = *(x + k);
                *(x + k) = t;
            }
        }
    }
}

visual studio调试功能尝试


#include<stdio.h>

int main() {
    void inv(int x[], int n);
    void inv1(int *x, int n);
    int i, a[10] = { 3,7,9,11,0,6,7,5,4,2 };
    printf("the orginal array:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    inv(a, 10);
    printf("the array has benn inverted:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    inv1(a, 10);
    printf("the array has benn inverted:\n");
    for (int i = 0; i < 10; i++) {
        printf("%d ", a[i]);
    }
    printf("\n");
    return 0;
}

void inv(int x[], int n) {
    int temp, i, j, m = (n - 1) / 2;
    for (i = 0; i <= m; i++) {
        j = n - 1 - i;
        temp = x[i];
        x[i] = x[j];
        x[j] = temp;
    }
}

void inv1(int *x, int n) {
    int *p,temp, *i, *j, m = (n - 1) / 2;
    i = x; j = x + n - 1; p = x + m;
    for ( ; i <= p; i++, j--) {
        temp = *i;
        *i = *j;
        *j = temp;
    }
}

在这里插入图片描述

  • 31
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

childish_tree

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值