C指针那点事儿

指针: 用来存放变量地址的变量,就成为”指针变量”.

定义: 一般形式:类名标识符 *指针变量名;

int *p;float *q;

“*”是说明符,用来说明这个变量是个指针变量,是不能省略的,但不属于变量名的一部分

前面的类型标志符表示指针变量所只想的变量的类型,而且只能指向这种类型的变量

示例1:值交换

 ```c void swap(char *v1, char *v2) {// 中间变量char temp;// 取出v1指向的变量的值temp = *v1;// 取出v2指向的变量的值,然后赋值给v1指向的变量*v1 = *v2;// 赋值给v2指向的变量*v2 = temp;}int main(){char a = 10, b = 9;printf("更换前:a=%d, b=%d\n", a, b);swap(&a, &b);printf("更换后:a=%d, b=%d", a, b);return 0;}``` 

示例2:函数多个返回值

```c   // 计算2个整型的和与差    int sumAndMinus(int v1, int v2, int *minus) {    // 计算差,并赋值给指针指向的变量    *minus = v1 - v2;// 计算和,并返回和    return v1 + v2;    }    int main()    {    // 定义2个int型变量    int a = 6, b = 2;    // 定义2个变量来分别接收和与差    int sum, minus;    // 调用函数    sum = sumAndMinus(a, b, &minus);    // 打印和    printf("%d+%d=%d\n", a, b, sum);    // 打印差    printf("%d-%d=%d\n", a, b, minus);    return 0;    } ```

示例3:用指针遍历字符串

// 定义一个指针pchar *p;// 定义一个数组s存放字符串char s[] = "mj";// 指针p指向字符串的首字符'm'p = s; // 或者 p = &s[0];for (; *p != '\0'; p++) {    printf("%c \n", *p);}

指针也是C语言中的一种数据类型,因此一个函数的返回值肯定可以是指针类型的。返回指针的函数的一般形式为:类型名 * 函数名(参数列表)

示例4:比如下面这个函数,返回一个指向char类型变量的指针

 ```c// 将字符串str中的小写字母变成大写字母,并返回改变后的字符串// 注意的是:这里的参数要传字符串变量,不能传字符串常量char * upper(char *str) {// 先保留最初的地址。因为等会str指向的位置会变来变去的。char *dest = str;// 如果还不是空字符while (*str != '\0') {    // 如果是小写字母    if (*str >= 'a' && *str <= 'z') {        // 变为大写字母。小写和大写字母的ASCII值有个固定的差值        *str -= 'a' - 'A';    }        // 遍历下一个字符    str++;}// 返回字符串return dest;}

“`

指向函数的指针函数作为一段程序,在内存中也要占据部分存储空间,它也有一个起始地址,即函数的入口地址。函数有自己的地址,那就好办了,我们的指针变量就是用来存储地址的。因此,可以利用一个指针指向一个函数。其中,函数名就代表着函数的地址。定义的一般形式:函数的返回值类型 (*指针变量名)(形式参数1, 形式参数2, …);

#include <stdio.h>int sum(int a, int b) {    return a + b;}int main(){    // 定义一个指针变量p,指向sum函数    int (*p)(int a, int b) = sum;    // 或者 int (*p)(int, int) = sum;    // 或者 int (*p)() = sum;        // 利用指针变量p调用函数    int result = (*p)(1, 3);    // 或者 int result = p(1, 3);        printf("%d", result);    return 0;}

指向指针的函数注意

1> 由于这类指针变量存储的是一个函数的入口地址,所以对它们作加减运算(比如p++)是无意义的。难道p++就会指向下一个函数了?可笑至极!!没这回事。

2> 返回指针的函数的定义char upper(char str) 和 指向函数的指针的定义int ( *p)(int a, int b)非常相似,使用时特别注意区分

3> 指向函数的指针变量主要有两个用途:

调用函数

将函数作为参数在函数间传递。我这么一说,可能还不是很明白,举个例子。

#include <stdio.h>// 减法运算int minus(int a, int b) {    return a - b;}// 加法运算int sum(int a, int b) {    return a + b;}// 这个counting函数是用来做a和b之间的计算,至于做加法还是减法运算,由函数的第1个参数决定void counting( int (*p)(int, int) , int a, int b) {    int result = p(a, b);    printf("计算结果为:%d\n", result);}int main(){    // 进行加法运算    counting(sum, 6, 4);        // 进行减法运算    counting(minus, 6, 4);        return 0;}

每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量

结构体指针变量的定义形式:struct 结构体名称 *指针变量名

有了指向结构体的指针,那么就有3种访问结构体成员的方式

结构体变量名.成员名(*指针变量名).成员名指针变量名->成员名

#include <stdio.h>int main(int argc, const char * argv[]) {    // 定义一个结构体类型    struct Student {        char *name;        int age;    };        // 定义一个结构体变量    struct Student stu = {"MJ", 27};        // 定义一个指向结构体的指针变量    struct Student *p;        // 指向结构体变量stu    p = &stu;    /*     这时候可以用3种方式访问结构体的成员     */    // 方式1:结构体变量名.成员名    printf("name=%s, age = %d \n", stu.name, stu.age);        // 方式2:(*指针变量名).成员名    printf("name=%s, age = %d \n", (*p).name, (*p).age);        // 方式3:指针变量名->成员名    printf("name=%s, age = %d \n", p->name, p->age);        return 0;}

一个人,一条路,人在途中,心随景动,

C指针那点事儿

相关文章:

你感兴趣的文章:

标签云: