C语言指针总结

Posted yangdagaoge

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言指针总结相关的知识,希望对你有一定的参考价值。

概念

  指针是什么?指针就是地址,众所周知,内存中的每个存储单元都有自己的地址,根据存储地址可以准确的找到该内存单元,所有通常把这个内存地址称为指针。所有指针就是实际地址。在c语言中,使用一个变量来存储指针,那么这个就是指针变量。

  一个指针的值就是某个内存单元的地址(或者指针)。指针是指地址是一个常量;指针变量时指取值为地址的变量

 

指针的定义方式和初始化

  

 1 //单个的定义指针
 2 
 3 int *p;
 4 
 5 //一条语句定义多个指针
 6 
 7 int *p1,*p2;
 8 
 9 
10 //使用typedef来便捷定义
11 
12 typedef int *ZHE;
13 ZHE a,b,c;
14 
15 ////////////////////////////
16 //指针的初始化
17 //方式一
18 int a;
19 int *p=&a;
20 
21 //方式二
22 int a;
23 int *p;
24 p=&a;
25 
26 //方式三
27 
28 int *p,*q;
29 int a=90;
30 p=&a;
31 q=p;

赋值指针注意

  1. 不同类型的指针赋值需要强制转换
  2. 不允许将一个值直接给指针变量(0除外)
  3. 在c语言中,auto变量不能赋值给static指针变量。
    int a=90;
    static int *p=&a;
    
    //////////////////////////////
                     错误
    /////////////////////////////

实例

void main() {
    int a,*p;
    p = &a;
    *p = 11;
    a++;
    printf("a=%d,*p=%d", a, *p);
}

指针运算

  指针是地址,地址是一种无符号整数;指针只有加法和减法,没有乘除法,因为两个地址之间的没有任何意义。但是两个地址之间的加法也没有任何意义,而两个地址相减表示两个指针之间的内存单元数。

  指针的加减的结果=当前地址+/-n*sizeof(type);例如:int *pi;pi的值是2000的话,那么pi++,就是2000+1*sizeof(int)=2002;其他类型也是类似。

  如果两个指针p1,p2存在如下关系:

  p1==p2:p1,p2指向同一个内存单元;

    p1>p2;表示p1处于高地址位置;

    p1<p2:表示p1处于低地址位置。

指针数组之间的关系

  数组的指针其实就是数组再内存中的起始地址。

void main() {
    int a[10];
    int k;

    for (k = 0; k < 10; k++)
        a[k] = k;//  *(a+k)=k;
}

  数组元素的几种赋值方法

    

void main() {
    char str[10];
    int i;
    //常规方法 
    for (i = 0; i < 10; i++)
        str[i] = a + i;
    //指针方法
    char *array = str;
    for (i = 0; i < 10; i++)
        *(array + i) = a + i;
    //指针自增方法
    for (i = 0; i < 10; i++)
        *array++ = a + i;
}

  在上面3种方法中,第三种方法 array指向的是str[9]的下一个单元,显然超出了数组所占的内存区域,这是越界现象,因为C语言不会对数组越界检查,所以需要程序员自己控制。

在后面加一个array=str即可。

多维数组指针的定义方式

void main() {
    int a[2][3] = { { 1,2,3 },{ 4,5,6 } };
    int(*p)[3];
    int i,j;

    p = a;
    for (i = 0; i < 2; i++)
        for (j = 0; j < 3; j++)
            printf("%d", *(p + 3 * i + j));//  printf("%d",*(p[i]+j))

}

数组指针与指针数组的区别

  1. 定义的方式不一样,数组指针  int (*p)[5];  指针数组 int *p[5];
  2. 表示的东西不一样,数组指针 p是指针变量,不是数组名,可以对此赋值;指针数组p是数组名,不可赋值。
  3. 存储的对象不一样;数组指针存储的是普通值,指针数组存储的是指针。
void main() {
    int i, j, k;
    int a, b, c, d, e, f;

    int *p[6] = { &a,&b,&c,&d,&e,&f };

    for (i = 0; i < 6; i++) {
        scanf("%d", p[i]);
    }

    for (i = 0; i < 5; i++) {
        for (j = i+1; j < 6; j++) {
            if (*p[i] > *p[j]) {
                k = *p[i];
                *p[i] = *p[j];
                *p[j] = k;
            }
        }
    }

    for (i = 0; i < 6; i++)
        printf("%d ", *p[i]);
}

 

字符指针

void main() {
    char str[] = { "i am your father" };
    char ch;
    char *p, *q;
    p = str;
    q = p + strlen(str) - 1;

    while (p < q) {
        ch = *q;
        *q-- = *p;
        *p++ = ch;
    }
    printf("%s", str);
}

指针与动态内存分配

我们以往的定义如  int a[10]; int b;等等都是静态内存分配,这些内存在程序运行前就分配好了,不可改变。

假如我们需要记录一个班级的学生成绩,那么我们要定义一个数组,但是我们常规定义数组要确定数组的大小。如果我们开辟一个1000的大小的数组,如果人数多,不够用,人数少造成浪费。然而动态内存分配就解决了这个问题。

动态内存分配的方式

  1. malloc:void * malloc(unsiged int size);
    int n ,*p;
    
    scanf("%d",&n);
    
    p=(int *)malloc(n*sizeof(int));
  2. calloc:void *calloc (unsigned int n,unsigned size);功能和malloc一样,但是他将赋初始值。
  3. realloc:void *realloc(void *p,unsigned int size):在原来的空间不够用的时候重新开辟更大的空间,优点是,原来的数据时保存的。

内存的释放

使用free(void * p)释放无用的内存,避免浪费内存。

二级指针

int a=20;
int *p;
int **k;

p=&a;
**k=&p;

函数指针

  使用背景,假如有多个函数,他们的参数和返回值都完全相同,那么我们使用一个函数指针对这些函数统一调用。

#include<stdio.h>
#include<conio.h>
#include<string.h>

int max(int a, int b);
int min(int a, int b);
int sum(int a, int b);

int func(int a, int b, int(*fun)(int, int));

void main() {
    int a = 2;
    int b = 3;
    int res;
    res=func(a, b, max);
    res=func(a, b, min);
    res=func(a, b, sum);
}

int func(int a, int b, int(*fun)(int, int)) {
    return (*fun)(a, b);
}

int max(int a, int b) {
    return a > b ? a : b;
}

int min(int a, int b) {
    return a < b ? a : b;
}

int sum(int a, int b) {
    return a + b;
}

 

ps:一个函数的返回值是指针时应该注意:在返回之前一定要保证返回的指针时有效的,不是野的,因为auto在使用完后会被立即销毁,所有函数内部需要用static修饰

int *get(int num) {
    static int a[100];
    ////
    ////
    ////
    ////
    return (a);
}

 




以上是关于C语言指针总结的主要内容,如果未能解决你的问题,请参考以下文章

c语言指针知识点总结

C语言总结1(指针)

C语言指针学习总结

java语言总结

C 语言数组 ( 数组指针 | 数组指针定义 | 使用 数组指针类型 定义数组指针 )

C语言指针总结