C语言学习--指针

提示:指针是C语言中一个极其重要且功能强大的概念,它允许程序直接操作内存地址,从而实现对数据的灵活访问和控制。

目录

前言

14.1 指针基本介绍

14.2 什么是指针

14.3 指针的算术运算

14.3.1 指针递增操作(++)

14.3.2 指针递减操作(--)

14.3.3 指针+、-操作

14.3.4 课堂练习

14.4 指针的比较

14.5 指针数组

14.5.1 基本介绍

14.5.2 指针数组定义

14.5.3 指针数组快速入门 和 内存布局示意图

14.5.4 指针数组应用实例

14.6 指向指针的指针(多重指针)

14.6.1 基本介绍

14.6.2 多重指针(二级,三级)快速入门案例

14.6.3 对应的内存布局图(!!!)

14.7 传递指针(地址)给函数

14.7.1 案例 1-传地址或指针给指针变量

14.7.2 案例 2-传数组给指针变量

14.8 返回指针的函数

14.8.1 快速入门案例

14.8.2 指针函数注意事项和细节

14.8.3 应用实例

14.9 函数指针(指向函数的指针)

14.9.1 基本介绍

14.9.2 函数指针定义

14.9.3 应用案例

14.9.4 函数指针的内存布局

14.10回调函数

14.10.1 基本介绍

14.10.2 应用实例

14.11指针的注意事项和细节

14.12动态内存分配

14.12.1 C 程序中,不同数据在内存中分配说明:

14.12.2 内存动态分配的相关函数

14.12.3 应用实例

14.12.4 动态分配内存的基本原则

总结

附录


前言

指针是C语言中一个极其重要且功能强大的概念,它允许程序直接操作内存地址,从而实现对数据的灵活访问和控制。然而,指针的使用也带来了一定的复杂性,它涉及到内存的直接操作,稍有不慎就可能导致程序错误甚至崩溃。本章将深入探讨指针的基本概念、操作以及在C语言编程中的应用,旨在帮助读者全面理解指针的工作原理和使用技巧。


14.1 指针基本介绍

1) 指针是 C 语言的精华,也是 C 语言的难点。

2) 指针,也就是内存的地址;所谓指针变量,也就是保存了内存地址的变量。关于指针的基本使用,在讲变量的时候做了入门级的介绍

3) 获取变量的地址,用&,比如: int num = 10, 获取 num 的地址:&num

4) 指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值

比如:int *ptr = # ptr 就是指向 int 类型的指针变量, 即 ptr 是 int * 类型。

5) 获取指针类型所指向的值,使用:*(取值符号),比如:int * ptr , 使用*ptr 获取 ptr 指向的值

14.2 什么是指针

指针是一个变量,其值为另一个变量的地址(前示意图已经说明),即,内存位置的直接地址。就像其他变量或常量一样,在使用指针存储其他变量地址之前,对其进行声明。指针变量声明的一般形式为:

int *ip; /* 一个整型的指针 */

double *dp; /* 一个 double 型的指针 */

float *fp; /* 一个浮点型的指针 */

char *ch; /* 一个字符型的指针 */

34c1897cde234b45a0b338b4ffecb565.png

14.3 指针的算术运算

指针是一个用数值表示的地址。可以对指针执行算术运算。可以对指针进行四种算术运算:++、--、+、-。

14.3.1 指针递增操作(++)

1) 案例演示

#include <stdio.h>

const int MAX = 3;//常量

int main () {

int var[] = {10, 100, 200}; // int 数组

int i, *ptr; // ptr 是一个 int* 指针

ptr = var; // ptr 指向了 var 数组的首地址

for ( i = 0; i < MAX; i++) {

printf("var[%d] 地址= %p \n", i, ptr );

printf("存储值:var[%d] = %d\n", i, *ptr );

ptr++;// ptr = ptr + 1(1 个 int 字节数); ptr 存放值+4 字节(int)

}

getchar();

return 0;

}

 

2) 示意图(!!)

b9a7f3f430df42e5b4659952b12b41c2.png

3) 小结

  • 数组在内存中是连续分布的
  • 当对指针进行++时,指针会按照它指向的数据类型字节数大小增加,比如 int * 指针,每++ , 就增加 4 个字节(老师的电脑), 【案例演示 int -> short】

14.3.2 指针递减操作(--)

1) 案例演示

#include <stdio.h>

const int MAX = 3;

int main () {

int var[] = {10, 100, 200};

int i, *ptr;

/* 指针中最后一个元素的地址 */

ptr = &var[MAX-1]; // &var[2]

for ( i = MAX; i > 0; i--) {// 反向遍历

printf("ptr 存放的地址=%p\n", ptr);

printf("存储值:var[%d] = %d\n", i-1, *ptr );

ptr--; // ptr = ptr - 1(1 个 int 的字节数 [4 个字节])

}

getchar();

return 0;

}

 

2) 示意图(!!)

同上图

3) 小结

  • 数组在内存中是连续分布的
  • 当对指针进行--时,指针会按照它指向的数据类型字节数大小减少,比如 int * 指针,每-- , 就减少 4 个字节(老师的电脑), 【案例演示 int -> short】

14.3.3 指针+、-操作

1) 案例演示

#include <stdio.h>

int main () {

int var[] = {10, 100, 200};

int i, *ptr;

ptr = var; // 将 var 的首地址 赋给 ptr

ptr += 2; // ptr 的存储的地址 + 2 个 int 的字节 (8 个字节)

printf("var[2]=%d var[2]的地址=%p ptr 存储的地址=%p ptr 指向的值=%d",

var[2], &var[2], ptr, *ptr);

getchar();

return 0;

}

 

2) 示意图

同上图

3) 小结

可以对指针按照指定的字节数大小进行 + 或者 – 的操作,可以快速定位你要的地址 【案例演示】

14.3.4 课堂练习

int main ()

{

int var[] = {10, 100, 200, 400, 9, 12};

int i, *ptr;

ptr = &var[2]; // ptr 指向了 第 3 个元素

ptr -= 2;

printf("ptr 指向的值=%d", *ptr); // 10

getchar();

return 0;

}

14.4 指针的比较

指针可以用关系运算符进行比较,如 ==、< <= 和 > >=。如果 p1 和 p2 指向两个变量,比如同一个数组中的不同元素,则可对 p1 和 p2 进行大小比较, 看下面代码,说明输出什么?

案例 1

#include <stdio.h>

int main () {

int var[] = {10, 100, 200};

int *ptr;

ptr = var;//ptr 指向 var 首地址(第一个元素)

//if(ptr == var[0]) {//错误,类型不一样 (int *) 和 (int )

// printf("ok1");

//}

if(ptr == &var[0]) { // 可以

printf("\nok2"); //输出

}

if(ptr == var) { //可以

printf("\nok3"); //输出

}

if(ptr >= &var[1]) { //可以比较,但是返回 false

printf("\nok4");//不会输出

}

getchar();

return 0; }

案例 2

#include <stdio.h>

const int MAX = 3;

int main () {

int var[] = {10, 100, 200};

int i, *ptr;

ptr = var;

i = 0;

while ( ptr <= &var[MAX - 2] )//&var[1]

{

printf("Address of var[%d] = %x\n", i, ptr );

printf("Value of var[%d] = %d\n", i, *ptr );

ptr++;

i++;

} //会输出 10 , 100

getchar();

return 0; }

 

14.5 指针数组

14.5.1 基本介绍

要让数组的元素 指向 int 或其他数据类型的地址(指针)。可以使用指针数组。

14.5.2 指针数组定义

数据类型 *指针数组名[大小];

  1. 比如: int *ptr[3];
  2. ptr 声明为一个指针数组
  3. 由 3 个整数指针组成。因此,ptr 中的每个元素,都是一个指向 int 值的指针。

14.5.3 指针数组快速入门 和 内存布局示意图

#include <stdio.h>

const int MAX=3;

int main ()

{

int var[] = {10, 100, 200};

int i, *ptr[3];

for ( i = 0; i < MAX; i++)

{

ptr[i] = &var[i]; /* 赋值为整数的地址 */

}

for ( i = 0; i < MAX; i++) //指针数组来获取各个值

{

printf("Value of var[%d] = %d ptr[%d]本身的地址=%p \n ", i, *ptr[i] , i, &ptr[i]); // 10, 100, 200

}

getchar();

return 0;

}

 

指针数组的内存布局

dc566158b56b4c918109c2fd3e4b1b61.png

 

14.5.4 指针数组应用实例

请编写程序,定义一个指向字符的指针数组来存储字符串列表(四大名著书名), 并通过遍历 该指针数组,显示字符串信息 , (即:定义一个指针数组,该数组的每个元素,指向的是一个字符串)

#include <stdio.h>

void main() {

//定义一个指针数组,该数组的每个元素,指向的是一个字符串

char *books[] = {

"三国演义",

"西游记",

"红楼梦",

"水浒传"

};

char * pStr = "abc";

//遍历

int i, len = 4;

for(i = 0; i < len; i++) {

printf("\nbooks[%d] 指向字符串是=%s pStr 指向的内容=%s", i , books[i], pStr);

}

getchar();

}

 

14.6 指向指针的指针(多重指针)

14.6.1 基本介绍

指向指针的指针是一种多级间接寻址的形式,或者说是一个指针链。通常,一个指针包含一个变量的地址。当我们定义一个指向指针的指针时,第一个指针包含了第二个指针的地址,第二个指针指向包含实际值的位置(如下图)

8a88e806368d47ef8363844095ba58ab.png

14.6.2 多重指针(二级,三级)快速入门案例

1) 一个指向指针的指针变量必须如下声明,即在变量名前放置两个星号。例如,下面声明了一个指向 int 类型指针的指针:

int **ptr; // ptr 的类型是 int **

2) 当一个目标值被一个指针间接指向到另一个指针时,访问这个值需要使用两个星号运算符, 比如 **ptr

3) 案例演示+内存布局图

#include <stdio.h>

int main () {

int var;

int *ptr; //一级指针

int **pptr; //二级指针

int ***ppptr; // 三级指针

var = 3000;

ptr = &var; // var 变量的地址赋给 ptr

pptr = &ptr;// 表示将 ptr 存放的地址,赋给 pptr

ppptr = &pptr; // 表示将 pptr 存放的地址,赋给 ppptr

printf("var 的地址=%p var = %d \n", &var, var );// 0x1133 3000

printf("ptr 的本身的地址=%p ptr 存放的地址=%p *ptr = %d \n", &ptr, ptr, *ptr );

printf("pptr 本身地址 = %p pptr 存放的地址=%p **pptr = %d\n", &pptr, pptr, **pptr);

printf("ppptr 本身地址 = %p ppptr 存放的地址=%p ***pptr = %d\n", &ppptr, ppptr, ***ppptr);

getchar();

return 0;

}

 

14.6.3 对应的内存布局图(!!!)

b61cca9c006a4773b7efc1fb38f9ac5e.png

14.7 传递指针(地址)给函数

当函数的形参类型是指针类型时,是使用该函数时,需要传递指针,或者地址,或者数组给该形参,举例说明:

14.7.1 案例 1-传地址或指针给指针变量

1) 内存布局图

2) 代码分析输出

3) 代码演示

#include <stdio.h>

void test2(int *p); //函数声明,接收 int *

void main() {

int num=90;

int *p = # //将 num 的地址赋给 p

test2(&num); //传地址

printf("\nmain() 中的 num=%d", num); // num = 91

test2(p); //传指针

printf("\nmain() 中的 num=%d", num);// num = 92

getchar();

}

void test2(int *p) {

*p += 1; //*p 就访问 num 的值

}

 

//代码的内存分析

 

92c9a015294f403daf29b43329e7b759.png

14.7.2 案例 2-传数组给指针变量

数组名本身就代表该数组首地址,因此传数组的本质就是传地址。

1) 内存布局图

2) 代码分析输出

3) 代码演示

#include <stdio.h>

/* 函数声明 */

double getAverage(int *arr, int size); //函数声明

double getAverage2(int *arr, int size); //函数声明

int main ()

{

/* 带有 5 个元素的整型数组 */

int balance[5] = {1000, 2, 3, 17, 50};

double avg;

/* 传递一个指向数组的指针作为参数 */

avg = getAverage( balance, 5 ) ;

/* 输出返回值 */

printf("Average value is: %f\n", avg );

getchar();

return 0;

}

//说明

//1. arr 是一个指针,

double getAverage(int *arr, int size)

{

int i, sum = 0;

double avg;

for (i = 0; i < size; ++i)

{

// arr[0] = arr + 0

// arr[1] = arr + 1 个 int 字节(4)

// arr[2] = arr + 2 个 int 字节(8)

//...

sum += arr[i];// arr[0] =>数组第一个元素的地址 arr[1]

printf("\narr 存放的地址=%p ", arr);

}

avg = (double)sum / size;

return avg;

}

double getAverage2(int *arr, int size)

{

int i, sum = 0;

double avg;

for (i = 0; i < size; ++i)

{

sum += *arr;

printf("\narr 存放的地址=%p ", arr);

arr++; // 指针的++运算, 会对 arr 存放的地址做修改

}

avg = (double)sum / size;

return avg;

}

 

//分析的内存布局图

a34ede5488ac49ae9a10cb01327f8db1.png

4) 思路题

如果在 getAverage()函数中,通过指针修改了数组的值,那么 main 函数的 balance 数组的值是否会相应变化? 会的

 

因为 getVerage 函数中的指针,指向的就是 main 函数的数组。

14.8 返回指针的函数

C 语言 允许函数的返回值是一个指针(地址),这样的函数称为指针函数。

14.8.1 快速入门案例

请编写一个函数 strlong(),返回两个字符串中较长的一个。

#include <stdio.h>

#include <string.h>

char *strlong(char *str1, char *str2){ //函数返回的 char * (指针)

printf("\nstr1 的长度%d str2 的长度%d", strlen(str1), strlen(str2));

if(strlen(str1) >= strlen(str2)){

return str1;

}else{

return str2;

}

}

int main(){

char str1[30], str2[30], *str; // str 是一个指针类型,指向一个字符串

printf("\n 请输入第 1 个字符串");

gets(str1);

printf("\n 请输入第 2 个字符串");

gets(str2);

str = strlong(str1, str2);

printf("\nLonger string: %s \n", str);

getchar();

return 0;

}

14.8.2 指针函数注意事项和细节

1) 用指针作为函数返回值时需要注意,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针不能指向这些数据【案例演示】

2) 函数运行结束后会销毁该函数所有的局部数据,这里所谓的销毁并不是将局部数据所占用的内存全部清零,而是程序放弃对它的使用权限,后面的代码可以使用这块内存 【案例演示】

3) C 语言不支持在调用函数时返回局部变量的地址,如果确实有这样的需求,需要定义局部变量为 static 变量

【案例演示】

4) 代码演示

#include <stdio.h>

int *func(){

//int n = 100;//局部变量, 在 func 返回时,就会销毁

static int n = 100; // 如果这个局部变量是 static 性质的,那么 n 存放数据的空间在静态数据区

return &n;

}

int main(){

int *p = func(); //func 返回指针

int n;

printf("okoook~~"); //可能是使用到 局部变量 int n = 100 占用空间

printf("okoook~~");

printf("okoook~~");

n = *p;

printf("\nvalue = %d\n", n);// 思考,是否能够输出 100? 不一定

getchar();

return 0;

}

 

14.8.3 应用实例

编写一个函数,它会生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们。

代码演示:

#include <stdio.h>

#include <stdlib.h>

//编写一个函数,返回一个一维数组

int * f1() {

static int arr[10]; //必须加上 static ,让 arr 的空间在静态数据区分配

int i = 0;

for (i = 0; i < 10;i++) {

arr[i] = rand();

}

return arr;

}

void main() {

int *p;

int i;

p = f1(); //p 指向是在 f1 生成的数组的首地址(即第一个元素的地址)

for ( i = 0; i <10; i++) {

printf("\n%d", *(p+i));

}

getchar();

}

14.9 函数指针(指向函数的指针)

14.9.1 基本介绍

1) 一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。

2) 把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是函数指针。

14.9.2 函数指针定义

return Type (*pointerName)(param list);

1) return Type 为函数指针指向的函数返回值类型

2) pointerName 为函数指针名称

3) param list 为函数指针指向的函数的参数列表

4) 参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称

5) 注意( )的优先级高于*,第一个括号不能省略,如果写作 return Type *pointerName(param list);就成了函数原型,它表明函数的返回值类型为 return Type *

14.9.3 应用案例

用函数指针来实现对函数的调用, 返回两个整数中的最大值.

#include <stdio.h>

//说明

//1. max 函数

//2. 接收两个 int ,返回较大数

int max(int a, int b){

return a>b ? a : b;

}

int main(){

int x, y, maxVal;

//说明 函数指针

//1. 函数指针的名字 pmax

//2. int 表示 该函数指针指向的函数是返回 int 类型

//3. (int, int) 表示 该函数指针指向的函数形参是接收两个 int

//4. 在定义函数指针时,也可以写上形参名 int (*pmax)(int x, int y) = max;

int (*pmax)(int , int ) = max; //

printf("Input two numbers:");

scanf("%d %d", &x, &y);

// (*pmax)(x, y) 通过函数指针去调用 函数 max

maxVal = (*pmax)(x, y);

printf("Max value: %d pmax=%p pmax 本身的地址=%p\n", maxVal, pmax, &pmax);

getchar();

getchar();

return 0;

}

 

14.9.4 函数指针的内存布局

b5bdde21dcd742dfa25e7b5c6f3bd30c.png

14.10回调函数

14.10.1 基本介绍

1) 函数指针变量可以作为某个函数的参数来使用的,回调函数就是一个通过函数指针调用的函数。

2) 简单的讲:回调函数是由别人的函数执行时调用你传入的函数(通过函数指针完成)

14.10.2 应用实例

使用回调函数的方式,给一个整型数组 int arr[10] 赋 10 个随机数。

Ø 代码演示

#include <stdlib.h>

#include <stdio.h>

// 回调函数

//1. int (*f)(void)

//2. f 就是 函数指针 , 它可以接收的函数是 (返回 int ,没有形参的函数)

//3. f 在这里被 initArray 调用,充当了回调函数角色

void initArray(int *array, int arraySize, int (*f)(void)) {

int i ;

//循环 10

for ( i=0; i<arraySize; i++) {

array[i] = f(); //通过 函数指针调用了 getNextRandomValue 函数

}

}

// 获取随机值

int getNextRandomValue(void) {

return rand();//rand 系统函数, 会返回一个随机整数

}

int main(void) {

int myarray[10],i; //定义一个数组和 int

//说明

//1. 调用 initArray 函数

//2. 传入了一个函数名 getNextRandomValue (地址), 需要使用函数指针接收

initArray(myarray, 10, getNextRandomValue);

//输出赋值后的数组

for(i = 0; i < 10; i++) {

printf("%d ", myarray[i]);

}

printf("\n");

getchar();

return 0;

}

 

14.11指针的注意事项和细节

1) 指针变量存放的是地址,从这个角度看指针的本质就是地址。

2) 变量声明的时候,如果没有确切的地址赋值,为指针变量赋一个 NULL 值是好的编程习惯。

3) 赋为 NULL 值的指针被称为空指针,NULL 指针是一个定义在标准库 <stdio.h>中的值为零的常量 #define NULL 0 [案例]

4) 指针使用一览 (见后)

5) 案例演示

#include <stdio.h>

void main() {

int *p = NULL; // p 空指针

int num = 34;

p = #

printf("*p=%d", *p); // 34

getchar();

}

 

14.12动态内存分配

14.12.1 C 程序中,不同数据在内存中分配说明:

1) 全局变量——内存中的静态存储区

2) 非静态的局部变量——内存中的动态存储区——stack 栈

3) 临时使用的数据---建立动态内存分配区域,需要时随时开辟,不需要时及时释放——heap 堆

4) 根据需要向系统申请所需大小的空间,由于未在声明部分定义其为变量或者数组,不能通过变量名或者数组名来引用这些数据,只能通过指针来引用

76fb63d68f8f413c9a94c8c9b2f68cb3.png

14.12.2 内存动态分配的相关函数

1) 头文件 #include <stdlib.h> 声明了四个关于内存动态分配的函数

2) 函数原型 void * malloc(usigned int size) //memory allocation

  • 作用——在内存的动态存储区(堆区)中分配一个长度为 size 的连续空间。
  • 形参 size 的类型为无符号整型,函数返回值是所分配区域的第一个字节的地址,即此函数是一个指针型函数,返回的指针指向该分配域的开头位置。
  • malloc(100); 开辟 100 字节的临时空间,返回值为其第一个字节的地址

3) 函数原型 void *calloc(unsigned n,unsigned size)

  • 作用——在内存的动态存储区中分配 n 个长度为 size 的连续空间,这个空间一般比较大,足以保存一个数组,用 calloc 函数可以为一维数组开辟动态存储空间,n 为数组元素个数,每个元素长度为 size。
  • 函数返回指向所分配域的起始位置的指针;分配不成功,返回 NULL。
  • p = calloc(50, 4); //开辟 50*4 个字节临时空间,把起始地址分配给指针变量 p

4) 函数原型:void free(void *p)

  • 作用——释放变量 p 所指向的动态空间,使这部分空间能重新被其他变量使用。
  • p 是最近一次调用 calloc 或 malloc 函数时的函数返回值
  • free 函数无返回值
  • free(p); // 释放 p 所指向的已分配的动态空间

5) 函数原型 void *realloc(void *p,unsigned int size)

  • 作用——重新分配 malloc 或 calloc 函数获得的动态空间大小,将 p 指向的动态空间大小改变为 size,p 的值不变,分配失败返回 NULL
  • realloc(p, 50); // 将 p 所指向的已分配的动态空间 改为 50 字节

6) 返回类型说明

5e9f849f71d9411d892a17452119bdb4.png

f706b776f8f84288aee62981cf163580.png

14.12.3 应用实例

动态创建数组,输入 5 个学生的成绩,另外一个函数检测成绩低于 60 分的,输出不合格的成绩。

Ø 代码演示

#include <stdlib.h>

#include <stdio.h>

int main() {

void check(int *);

int * p,i;

// 在堆区开辟一个 5 * 4 的空间,并将地址 (void *) , 转成 (int *) , 赋给 p

p = (int *)malloc(5*sizeof(int));

for( i = 0; i < 5; i++){

scanf("%d", p + i);

}

check(p);

//free(p); //销毁 堆区 p 指向的空间

getchar();

getchar();

return 0;

}

void check(int *p) {

int i;

printf("\n 不及格的成绩 有: ");

for(i =0; i < 5; i++){

if(p[i] < 60) {

printf(" %d ", p[i]);

}

}

}

内存分析图

00ce6878c0634ecc9f21b24ec32df604.png

14.12.4 动态分配内存的基本原则

1) 避免分配大量的小内存块。分配堆上的内存有一些系统开销,所以分配许多小的内存块比分配几个大内存块的系统开销大

2) 仅在需要时分配内存。只要使用完堆上的内存块,就需要及时释放它(如果使用动态分配内存,需要遵守原则:谁分配,谁释放), 否则可能出现内存泄漏

3) 总是确保释放以分配的内存。在编写分配内存的代码时,就要确定在代码的什么地方释放内存

4) 在释放内存之前,确保不会无意中覆盖堆上已分配的内存地址,否则程序就会出现内存泄漏。在循环中分配内存时,要特别小心

5) 指针使用一览

cc6d202e48014c08872540e16ce63fa8.png


总结

通过本章的学习,我们对指针有了全面的了解。从指针的基本概念和声明,到指针的算术运算、指针数组、多重指针,再到函数指针和回调函数,我们学习了指针在C语言中的多种应用形式。同时,我们也掌握了如何通过指针传递函数参数、返回函数结果,以及如何使用动态内存分配来管理程序的内存使用。

指针作为C语言的核心特性之一,其灵活的内存操作能力极大地增强了语言的表现力和控制力。然而,指针的使用也需要谨慎,不当的指针操作可能会导致内存泄漏、野指针等严重问题。因此,掌握指针的正确使用方法对于编写高效、稳定的C程序至关重要。

在实际编程中,合理利用指针可以提高程序的运行效率和内存使用效率。动态内存分配为程序提供了更大的灵活性,但同时也要求程序员具备良好的内存管理能力。通过本章的学习,读者应该能够更加自如地运用指针,编写出更加高效和健壮的C语言程序。

附录

参考:【尚硅谷C语言零基础快速入门教程-哔哩哔哩】 https://b23.tv/vS3vTDp

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值