我是靠谱客的博主 稳重日记本,最近开发中收集的这篇文章主要介绍C语言指针使用总结前言指针常量常量指针指针的指针数组指针指针数组函数指针,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

这篇博客是转载@qyuhen大神知名的C99学习笔记,总结了一下其中关于指针内容的介绍。

项目中需要用到大量的c编程,所以借着学习的机会顺便记录读书笔记。


指针常量

指针常量就是指“类型为常量的指针”,初始化后不能被修改,固定指向某个内存地址。也就是说,我们不能修改指针自身的值,但是可以修改指针指向目标的值。

int x[] = {1, 2, 3, 4};
int* const p = x;

for (int i = 0; i < 4; i ++) {
    int v = *(p + i);
    *(p + i) = ++v;

    printf("%dn", v);

    // p ++; // Compile Error!
}

常量指针

常量指针是指“指向常量数据的指针”,指针指向的目标被当作常量处理,不能通过指针做赋值操作。指针自身并非常量,可以指向其他位置,但依然不能做赋值操作。

int x = 1, y = 2;

const int *p = &x;
// *p = 100; // Compile Error!

p = &y;
printf("%dn", *p);

// *p = 100; // Compile Error!

区别指针常量和常量指针方法非常简单:看const修饰的是谁,也就是*在const的左边还是右边。

  • int* const p : const修饰指针变量p。是指针常量。
  • int const *p : const修饰的是指针所指向的内容*p。是常量指针。
  • const int* const p : 指向常量的指针常量。

指针的指针

指针本身也是内存区的一个数据变量,自然也可以用其他的指针来指向它。

int x = 10;
int* p = &x;
int** p2 = &p;

printf("p = %p, *p = %dn", p, *p);
printf("p2 = %p, *p2 = %xn", p2, *p2);
printf("x = %d, %dn", *p, **p2);

输出为:

p=0x7fff2a16934c, *p=10
p2=0x7fff2a169350, *p2=2a16934c
x=10, 10

可以看出,p2存储的是指针p的地址,因此有指针的指针一说。


数组指针

数字指针是指“指向数组的指针”。这里需要注意,千万不要把“数组指针”和“数组名”混淆,他俩的区别是:

  • 数组名:指向数组地一个元素的指针常量。因为数组名是指针常量,因此不能进行自加或自减操作。
  • 数组指针:指向数组的指针,它是把整个数组当作一个对象,而不是其中的成员。
int x[] = {1, 2, 3, 4};

int* p1 = x; // 这个不是数组指针,因此p指向的是数组的第一个元素
int (*p2)[] = &x; // 数组指针

for (int i = 0; i < 4; i ++) {
    printf("%d, %dn", *(p1 + i), (*p2)[i]);
}

p1的类型为int*, 它被赋值为数组名x,也就是说它是指向数组第一个元素的指针常量。
p2是数组指针,它把数组当作一个整体,从类型角度来说,数组类型和数组元素类型是两个概念,因此,”p2=&x”当中,x代表的是数组本身而不是数组的第一个元素地址,&x取的是数组指针。

自己的理解:

  • 对于数组名x,x + 1指向的下一个元素。
  • 对于数组指针p,p + 1是直接加了整个数组的偏移,即越过了当前数组。

指针数组

元素类型为指针的数组称为指针数组。

int x[] = {1, 2, 3, 4};
int* ps[] = {x, x + 1, x + 2, x + 3}; // 指针数组

for (int i = 0; i < 4; i ++) {
    printf("%dn", *(ps[i]));
}

x默认就是指向数组第一个元素的指针常量,那么x+n自然获取后续元素的指针了。

指针数组通常用来处理交错数组(又称为数组的数组),最常见的就是字符串数组了。

void test(const char** x, int len)
{
    for (int i = 0; i < len; i ++) {
        printf("test : %d = %sn", i, *(x + i));
    }
}

int main(void)
{
    char* a = "aaa";
    char* b = "bbb";

    char* ss[] = {a, b};

    for (int i = 0; i < 2; i ++) {
        printf("%d = %sn", i, ss[i]);
    }

    test(ss, 2);
    return 0;
}

函数指针

默认情况下,函数名就是指向该函数的指针常量。

void inc(int* x)
{
    *x += 1;
}

int main(void)
{
    void (*f)(int *) = inc; // 将inc赋值给函数指针f
    int i = 100;
    f(&i);
    printf("%dn", i);

    return 0;
}

如果觉得函数指针的声明不好看,可以用typedef重写一下。注意:

  • 定义函数指针类型:typedef void ()(int) inc_t; 或者 typedef void (inc_t)(int)。后者用的更多,但是前者更好理解。
  • 定义函数类型:typedef void(inc_t)(int*);

最后

以上就是稳重日记本为你收集整理的C语言指针使用总结前言指针常量常量指针指针的指针数组指针指针数组函数指针的全部内容,希望文章能够帮你解决C语言指针使用总结前言指针常量常量指针指针的指针数组指针指针数组函数指针所遇到的程序开发问题。

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

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

评论列表共有 0 条评论

立即
投稿
返回
顶部