我是靠谱客的博主 动听红酒,最近开发中收集的这篇文章主要介绍C语言指针关键知识点总结,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

本文目录

    • 一、对星号 * 的总结
    • 二、各种指针总结
      • 1、数组指针
      • 2、字符串指针
      • 3、指针变量做函数参数
      • 4、指针作为函数返回值
      • 5、指针数组
      • 6、二维数组指针
      • 7、函数指针
    • 三、指针对比
    • 四、空指针NULL与NUL以及void指针

一、对星号 * 的总结

在我们目前所学到的语法中,星号主要有三种用途:

  • 表示乘法,例如int a = 3, b = 5, c; c = a * b;,这是最容易理解的。
  • 表示定义一个指针变量,以和普通变量区分开,例如int a = 100; int *p = &a;。
  • 表示获取指针指向的数据,是一种间接操作,例如int a, b, *p = &a; *p = 100; b = *p;。

二、各种指针总结

1、数组指针

如果一个指针指向了数组,我们就称它为数组指针(Array Pointer)

重点: 数组名是常量,它的值不能改变,而数组指针是变量(除非特别指明它是常量),它的值可以任意改变。也就是说,数组名只能指向数组的开头,而数组指针可以先指向数组开头,再指向其他元素。

2、字符串指针

表示方法

第一种方法直接使用字符数组表示字符串,声明一个指针指向字符数组的首地址:

char str[] = "http://c.biancheng.net";
char *pstr = str;

第二种方法是直接使用一个指针指向字符串(也称字符串常量):

char *str = "http://c.biancheng.net";

两种表示方法的区别:

它们最根本的区别是在内存中的存储区域不一样,字符数组存储在全局数据区或栈区,第二种形式的字符串存储在常量区。全局数据区和栈区的字符串(也包括其他数据)有读取和写入的权限,而常量区的字符串(也包括其他数据)只有读取权限,没有写入权限。

3、指针变量做函数参数

优点: 用指针变量作函数参数可以将函数外部的地址传递到函数内部,使得在函数内部可以操作函数外部的数据,并且这些数据不会随着函数的结束而被销毁。

实例:

void swap(int *p1, int *p2)

4、指针作为函数返回值

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

实例:

char *strlong(char *str1, char *str2){
    if(strlen(str1) >= strlen(str2)){
        return str1;
    }else{
        return str2;
    }
}

注意: 用指针作为函数返回值时需要注意的一点是,函数运行结束后会销毁在它内部定义的所有局部数据,包括局部变量、局部数组和形式参数,函数返回的指针请尽量不要指向这些数据,C语言没有任何机制来保证这些数据会一直有效,它们在后续使用过程中可能会引发运行时错误。

5、指针数组

定义:如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组。

定义形式:

dataType *arrayName[length];

[ ]的优先级高于*,该定义形式应该理解为:

dataType *(arrayName[length]);

6、二维数组指针

定义实例:

int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
int (*p)[4] = a;

括号中的*表明 p 是一个指针,它指向一个数组,数组的类型为int [4],这正是 a 所包含的每个一维数组的类型。

使用指针p访问二维数组中的每个元素

  1. p指向数组 a 的开头,也即第 0 行;p+1前进一行,指向第 1 行。

  2. *(p+1)表示取地址上的数据,也就是整个第 1 行数据。注意是一行数据,是多个数据,不是第 1 行中的第 0 个元素,下面的运行结果有力地证明了这一点:

    #include <stdio.h>
    int main(){
    int a[3][4] = { {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} };
    int (p)[4] = a;
    printf("%dn", sizeof(
    (p+1)));

     return 0;
    

    }

    运行结果:
    16

  3. *(p+1)+1表示第 1 行第 1 个元素的地址。

  4. ((p+1)+1)表示第 1 行第 1 个元素的值。很明显,增加一个 * 表示取地址上的数据。

指针数组和二维数组指针的区别

指针数组和二维数组指针在定义时非常相似,只是括号的位置不同:

int *(p1[5]);  //指针数组,可以去掉括号直接写作 int *p1[5];
int (*p2)[5];  //二维数组指针,不能去掉括号

7、函数指针

定义:一个函数总是占用一段连续的内存区域,函数名在表达式中有时也会被转换为该函数所在内存区域的首地址,这和数组名非常类似。我们可以把函数的这个首地址(或称入口地址)赋予一个指针变量,使指针变量指向函数所在的内存区域,然后通过指针变量就可以找到并调用该函数。这种指针就是函数指针

函数指针的定义形式为:

returnType (*pointerName)(param list);

returnType 为函数返回值类型,pointerNmae 为指针名称,param list 为函数参数列表。参数列表中可以同时给出参数的类型和名称,也可以只给出参数的类型,省略参数的名称,这一点和函数原型非常类似。

实例:

#include <stdio.h>

//返回两个数中较大的一个
int max(int a, int b){
    return a>b ? a : b;
}

int main(){
    int x, y, maxval;
    //定义函数指针
    int (*pmax)(int, int) = max;  //也可以写作int (*pmax)(int a, int b)
    printf("Input two numbers:");
    scanf("%d %d", &x, &y);
    maxval = (*pmax)(x, y);
    printf("Max value: %dn", maxval);

    return 0;
}

三、指针对比

辨析: 仅一个括号之差

int *p1[6];  //指针数组
int *(p2[6]);  //指针数组,和上面的形式等价
int (*p3)[6];  //二维数组指针
int (*p4)(int, int);  //函数指针

常见指针变量的定义

定 义含 义
int *p;p 可以指向 int 类型的数据,也可以指向类似 int arr[n] 的数组。
int **p;p 为二级指针,指向 int * 类型的数据。
int *p[n];p 为指针数组。[ ] 的优先级高于 *,所以应该理解为 int *(p[n]);
int (*p)[n];p 为二维数组指针。
int *p();p 是一个函数,它的返回值类型为 int *。
int (*p)();p 是一个函数指针,指向原型为 int func() 的函数。

四、空指针NULL与NUL以及void指针

1、NULL空指针

NULL 是“零值、等于零”的意思,在C语言中表示空指针。从表面上理解,空指针是不指向任何数据的指针,是无效指针,程序使用它不会产生效果。

NULL 是在stdio.h中定义的一个宏,它的具体内容为:

#define NULL ((void *)0)

(void *)0表示把数值 0 强制转换为void *类型,最外层的( )把宏定义的内容括起来,防止发生歧义。从整体上来看,NULL 指向了地址为 0 的内存,而不是前面说的不指向任何数据。

在进程的虚拟地址空间中,最低地址处有一段内存区域被称为保留区,这个区域不存储有效数据,也不能被用户程序访问,将 NULL 指向这块区域很容易检测到违规指针。

2、NUL

NUL 表示字符串的结束标志 ‘’,它是ASCII码表中的第 0 个字符。NUL 没有在C语言中定义,仅仅是对 ‘’ 的称呼,不能在代码中直接使用。

3、void 指针

void 用在函数定义中可以表示函数没有返回值或者没有形式参数,void * 表示指针指向的数据的类型是未知的。

void *表示一个有效指针,它确实指向实实在在的数据,只是数据的类型尚未确定,在后续使用过程中一般要进行强制类型转换。

C语言动态内存分配函数 malloc() 的返回值就是void *类型,在使用时要进行强制类型转换,请看下面的例子:

#include <stdio.h>

int main(){
    //分配可以保存30个字符的内存,并把返回的指针转换为 char *
    char *str = (char *)malloc(sizeof(char) * 30);
    gets(str);
    printf("%sn", str);
    return 0;
}

运行结果:
c.biancheng.net↙
c.biancheng.net

最后

以上就是动听红酒为你收集整理的C语言指针关键知识点总结的全部内容,希望文章能够帮你解决C语言指针关键知识点总结所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(50)

评论列表共有 0 条评论

立即
投稿
返回
顶部