【c语言指针详解】指针的高级应用

简介: 【c语言指针详解】指针的高级应用


一、指针和字符串

1.1 字符串和字符数组的关系

在 C 语言中,字符串是由字符组成的字符数组,以空字符(‘\0’,ASCII 值为 0)作为结尾。

下面是一个示例代码,演示了字符串和字符数组的关系:

#include <stdio.h>
#include <string.h>
int main() {
    // 直接初始化字符数组
    char str1[] = "Hello, World!";
    // 声明字符数组并赋值
    char str2[15];
    str2[0] = 'H';
    str2[1] = 'e';
    str2[2] = 'l';
    str2[3] = 'l';
    str2[4] = 'o';
    str2[5] = '\0';  // 字符串的结尾需要加上空字符
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    // 通过字符数组逐个字符访问和修改字符串
    str1[7] = 'w';
    printf("Modified str1: %s\n", str1);
    // 使用字符数组进行字符串拼接
    char str3[30] = "Welcome ";
    char name[] = "Alice";
    strcat(str3, name);
    printf("str3: %s\n", str3);
    return 0;
}

输出结果如下:

1.2 字符串常量和字符指针的使用

在 C 语言中,字符串常量是由连续的字符组成的字符数组,以空字符 '\0' 结束。字符串常量使用双引号 " 括起来。例如:

char str[] = "Hello, World!"; // 字符数组,其内容为字符串常量

字符串常量在内存中被存储为只读数据,在大多数情况下,不能对其进行修改。因此,通常将字符串常量声明为字符指针(const char* 类型),来指向字符串常量的首地址。例如:

const char* str = "Hello, World!"; // 字符指针,指向字符串常量

以下是一个关于字符串常量和字符指针的使用示例代码:

#include <stdio.h>
int main() {
    // 声明字符串常量
    char str1[] = "Hello, World!"; // 字符数组
    const char* str2 = "Hello, World!"; // 字符指针
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);
    // 使用字符指针访问字符串
    char* ptr = str1; // 字符指针指向字符数组
    while (*ptr != '\0') {
        printf("%c", *ptr);
        ptr++;
    }
    printf("\n");
    return 0;
}

输出结果如下:

1.3 字符串函数库的指针参数

C 语言提供了一组字符串函数库(如 <string.h>)来操作字符串。 这些字符串函数通常使用指针参数来接收和处理字符串数据。例如strlen、strcpy、strcat、strcmp 等。

1.3.1 strlen 函数

strlen 函数接受一个指向字符串的指针,并返回该字符串的长度,即字符的个数。

示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char str[] = "Hello,WeTab!";
    size_t len = strlen(str);
    printf("Length of the string: %zu\n", len);
    return 0;
}

输出结果如下:

注意:strlen 函数只计算字符串中的字符数目,不包括字符串末尾的空字符 \0。这是因为在 C 语言中,字符串以空字符作为结束标志。

1.3.2 strcpy 函数

strcpy 函数接受两个参数,一个目标字符串和一个源字符串的指针。它将源字符串中的内容复制到目标字符串中,并返回目标字符串的指针。

示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char source[] = "Hello, WeTab!";
    char destination[50];
    strcpy(destination, source);
    printf("Copied string: %s\n", destination);
    return 0;
}

输出结果如下:

注意:strcpy 函数会将源字符串中的内容复制到目标字符串中,包括末尾的空字符 \0。因此,在目标字符串中需要有足够的空间来存储源字符串的内容。建议在使用 strcpy 函数时,确保目标字符串足够大,以避免发生缓冲区溢出的问题。

1.3.3 strcat 函数

strcat 函数接受两个参数,一个目标字符串和一个源字符串的指针。它将源字符串中的内容追加到目标字符串的末尾,并返回目标字符串的指针。

示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char destination[50] = "Hello,";
    char source[] = " WeTab!";
    strcat(destination, source);
    printf("Concatenated string: %s\n", destination);
    return 0;
}

输出结果如下:

注意:strcat 函数会将源字符串中的内容追加到目标字符串的末尾,并在末尾加上空字符 \0。因此,在使用 strcat 函数之前,目标字符串必须以空字符结尾,并且有足够的空间来存储源字符串的内容和终止空字符。此外,类似 strcpy 函数,使用 strcat 函数时也应注意目标字符串的长度和避免发生缓冲区溢出的问题。

1.3.4 strcmp 函数

strcmp 函数接受两个参数,两个字符串的指针。它将两个字符串进行比较,并返回一个整数:

如果 str1 按照字典序小于 str2,返回负数;

如果 str1 等于 str2,返回 0;

如果 str1 按照字典序大于 str2,返回正数。

示例代码:

#include <stdio.h>
#include <string.h>
int main() {
    char str1[] = "hello";
    char str2[] = "world";
    char str3[] = "hello";
    int result1 = strcmp(str1, str2);
    int result2 = strcmp(str1, str3);
    printf("strcmp(str1, str2) 返回值: %d\n", result1);
    printf("strcmp(str1, str3) 返回值: %d\n", result2);
    return 0;
}

输出结果如下:

二、指针的高级应用

2.1 函数指针的定义和使用

函数指针是指向函数的指针,可以将其视为指向包含函数代码的内存位置的指针。

函数指针的类型定义为:返回类型 (*指针变量名)(参数列表)。

可以通过名称或指针来调用函数,函数指针可以用来动态调用函数。

示例代码:

#include <stdio.h>
// 声明一个函数指针类型
typedef int (*Operation)(int, int);
// 定义加法函数
int add(int a, int b) {
    return a + b;
}
// 定义减法函数
int subtract(int a, int b) {
    return a - b;
}
int main() {
    // 定义函数指针变量
    Operation op;
    // 把函数赋值给函数指针变量
    op = add;
    // 通过指针变量调用函数
    int result = op(5, 3);
    printf("加法的结果: %d\n", result);
    // 修改指针变量的值,指向减法函数
    op = subtract;
    // 通过指针变量调用函数
    result = op(5, 3);
    printf("减法的结果: %d\n", result);
    return 0;
}

输出结果如下:

2.2 回调函数和函数指针数组的应用

2.2.1 回调函数

回调函数是指当我们调用一个函数时,把另一个函数的指针作为一个参数传递给它,在这个函数完成后再调用这个指针所指向的函数,这就是回调函数。

示例代码:

#include <stdio.h>
// 回调函数类型
typedef void (*Callback)(int);
// 函数指针变量数组类型
typedef Callback CallbackArray[3];
// 回调函数实现
void my_callback(int number) {
    printf("回调函数被调用,参数为:%d\n", number);
}
// 调用函数
void call_function(Callback callback_func) {
    printf("调用函数执行...\n");
    callback_func(123);
    printf("调用函数结束。\n");
}
int main() {
    // 使用回调函数
    printf("使用回调函数:\n");
    call_function(my_callback);
    // 使用函数指针数组
    printf("使用函数指针数组:\n");
    CallbackArray callbacks = { my_callback, my_callback, my_callback };
    callbacks[0](1);
    callbacks[1](2);
    callbacks[2](3);
    return 0;
}

输出结果如下:

2.2.2 函数指针数组

函数指针数组是指向函数指针的指针数组,可以用于存储多个函数指针。

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

ReturnType (*FunctionName[])(ParameterTypes) = {Function1, Function2, ..., FunctionN};

其中,ReturnType表示函数的返回类型,FunctionName表示函数指针数组的名称,ParameterTypes表示函数的参数类型,Function1FunctionN表示要存储在数组中的函数指针。

示例代码:

#include <stdio.h>
// 函数原型
void Function1();
void Function2();
void Function3();
int main() {
    // 定义函数指针数组
    void (*functionPointers[])(void) = {Function1, Function2, Function3};
    // 调用函数指针数组中的函数
    functionPointers[0](); // 调用Function1
    functionPointers[1](); // 调用Function2
    functionPointers[2](); // 调用Function3
    return 0;
}
void Function1() {
    printf("This is Function1.\n");
}
void Function2() {
    printf("This is Function2.\n");
}
void Function3() {
    printf("This is Function3.\n");
}

输出结果如下:

函数指针数组在C语言中经常用于实现回调机制和多态。通过存储不同函数的指针,我们可以在运行时动态地选择执行不同的函数,从而实现程序的可扩展性和灵活性。

目录
相关文章
|
28天前
|
存储 算法 C语言
通义灵码在考研C语言和数据结构中的应用实践 1-5
通义灵码在考研C语言和数据结构中的应用实践,体验通义灵码的强大思路。《趣学C语言和数据结构100例》精选了五个经典问题及其解决方案,包括求最大公约数和最小公倍数、统计字符类型、求特殊数列和、计算阶乘和双阶乘、以及求斐波那契数列的前20项和。通过这些实例,帮助读者掌握C语言的基本语法和常用算法,提升编程能力。
|
24天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
45 0
|
22天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
15 2
|
23天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
23天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
29天前
|
存储 C语言
C语言32位或64位平台下指针的大小
在32位平台上,C语言中指针的大小通常为4字节;而在64位平台上,指针的大小通常为8字节。这反映了不同平台对内存地址空间的不同处理方式。
|
29天前
|
存储 算法 C语言
C语言:什么是指针数组,它有什么用
指针数组是C语言中一种特殊的数据结构,每个元素都是一个指针。它用于存储多个内存地址,方便对多个变量或数组进行操作,常用于字符串处理、动态内存分配等场景。
|
29天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
30天前
|
C语言
C语言指针(3)
C语言指针(3)
11 1
|
30天前
|
C语言
C语言指针(2)
C语言指针(2)
13 1