【C语言】07-指针

此笔记由个人整理

塞上苍鹰_fly

课程来自:尚观C语言

一、指针基础知识

变量与地址的关系

  • 变量名:是用户对某一个内存空间的抽象表示
  • 地址:固定不变的值,不会因为变量名的改变而改变。等价于指针

指针与指针变量

  • 指针:具有指向作用的地址就是指针,地址是常量
  • 指针变量:能够保存地址的变量就是指针变量,指针变量是可以被改变的

直接访问与间接访问

  • 直接访问:直接通过地址值访问得到此地址存放的内容

  • 间接访问:通过指针变量所存放的地址值访问的到此地址存放的内容

  • 不管你的指针是什么类型,是几级指针,在相同的编译环境中,所占的内存空间都是一致的。

  • 案例

#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 1;
    int *p = &i;
    
    printf("i = %d\n",i);
    printf("&i = %p\n",&i);
    printf("p = %p\n",p);
    printf("&p = %p\n",&p);
    printf("*p = %d\n",*p);
    exit(0);
}
  • 结果

【C语言】07-指针_第1张图片

空指针与野指针

  • 空指针:一开始不知道这个指针要具体存放啥时,就先将其设为空指针
  • 野指针:当前这个指针所指向的空间是不确定的,但还要直接使用
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int *p = NULL;//空指针
    int *q;//野指针
    
    exit(0);
}

空类型

  • 在不确定类型时使用

  • 任何类型的值都可以把值赋给空类型指针,空类型指针也可以将内容赋给任何类型的指针

void *q;

二、定义与初始化的书写

一级指针

定义

  • 类型 *变量名
int *p;

初始化

  • 类型 *变量名 = 值
int *p = 123;

二级指针

定义

  • 类型 **变量名
int **q;

初始化

  • 类型 **变量名 = 一级指针取地址
int *p = &i;
int **q = &p;//二级指针

指针运算

  • &(取地址)
  • *(取值)
  • 关系运算(地址值大小相比较)
  • 案例
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int a[6] = {5,1,7,3,8,3};
    int y;
    int *p = &a[1];
    
    y = (*--p)++;//在p地址的基础上地址自减一个元素,所以y的值为a[0]=5
    			 //在执行完取值的操作后,a[0]所存放的值自增1
    
    printf("y = %d\n",y);
    printf("a[0] = %d\n",a[0]);
    exit(0);
}
  • 结果

【C语言】07-指针_第2张图片

三、指针与数组的关系

指针与一维数组

a[i]:a[i] = *(a+i) = *(p+i) = p[i]
&a[i]&a[i] = a+i = p+i = &p[i]
  • 案例1
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int a[3] = {1,2,3};
    int i;
    int *p = a;
    
    for(i = 0;i < 3;i++)
    {
    	printf("%p-->%d\n",a+i,a[i]);
    	printf("%p-->%d\n",p+i,a[i]);
    	printf("%p-->%d\n",p+i,*(p+i));
    }
    printf("/n");
    exit(0);
}
  • 结果

【C语言】07-指针_第3张图片

  • 案例2
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int a[3];
    int i;
    int *p = a;
    for(i = 0;i < sizeof(a)/sizeof(*a);i++)
    	printf("%p-->%d\n",&a[i],a[i]);
    
    for(i = 0;i < sizeof(a)/sizeof(*a);i++)
    	scanf("%d",p++);
    	//scanf("%d",&a[i]);
    	//scanf("%d",&p[i]);
    
    p = a;//将自增完的地址重新赋值
    
    for(i = 0;i < sizeof(a)/sizeof(*a);i++,p++)
    	printf("%p-->%d\n",p,*p);
    printf("/n");
    exit(0);
}
  • 结果

【C语言】07-指针_第4张图片

指针与二维数组

  • 案例1
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int a[2][3] = {1,2,3,4,5,6}; 
    int i,j;
    int *p;
	    
    p = &a[0][0];
    
    printf("a	-->	%p\n",a);   
    printf("a+1	-->	%p\n",a+1);//a+1:地址增加一个行元素
	printf("p	-->	%p\n",p);   
    printf("p+1	-->	%p\n",p+1);//p+1:地址增加一个元素
    printf("\n");


    for(i = 0;i < 6;i++)
        printf("%d ",p[i]);
    printf("\n");
    
    for(i = 0;i < 2;i++)
    {
        for(j = 0;j < 3;j++)
        {
            printf("%p	-->	%d\n",*(a+i)+j,*(*(a+i)+j)); 
            //printf("%p	-->	%d\n",&a[i][j],a[i][j]);            
        }
		printf("\n");
    }
    exit(0);
}
  • 结果

【C语言】07-指针_第5张图片

指针与字符数组

  • 案例1
#include "stdio.h"
#include "stdlib.h"

int main()
{
    char str[] = "I love china!";
    char *p = str+7;
    
    puts(str);
    puts(p);
    
    exit(0);
}
  • 结果

【C语言】07-指针_第6张图片

  • 案例2
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int main()
{
    char str1[] = "hello";
    char *str2  = "hello";
    
    printf("str1:%d %d\n",sizeof(str1),strlen(str1));
    printf("str2:%d %d\n",sizeof(str2),strlen(str2));
    
    strcpy(str1,"world");
    str2 = "world";
    
    puts(str1);
    printf("\n");
    puts(str2);
    printf("\n");
    exit(0);
}
  • 结果

【C语言】07-指针_第7张图片

四、const与指针

  • 可以将变量转换为常量,不会因为后面的运算而改变(用指针间接访问的方法可以改变,但丢失限制)
  • 先看到const则为常量指针,先看到*则为指针常量
  • const后加*p(p地址存放的具体值)–>用来保护这个值不被改变
  • *const后加p(p为存放值的地址) -->用来保护这个地址不被改变
#include "stdio.h"
#include "stdlib.h"

int main()
{
	const float pi = 3.14;
    
    float *p = &pi;
    
    *p = 3.14159;
    
    printf("%f",pi);
    exit(0);
}
  • 结果

【C语言】07-指针_第8张图片

  • 案例1
const int a;
int const a;

const int *p;
int const *p;//常量指针

int *const p;//指针常量

const int *const p;//即是常量指针又是指针常量

#define PI	3.14
	2 * PI * r;
     
const float pi = 3.14;
	2 * pi * r;

常量指针

  • 指针的指向可以发生变化,但指向的值不能变化
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 1;
    int j = 100;
    const int *p = &i;
	printf("before-->%d\n",*p);
	//i = 10;//可以修改
    //*p = 10;//报错:向只读位置“*p”赋值
    p = &j;
    printf("after-->%d\n",*p);
}//值不能变但指向可以变
  • 报错
image-20200621192141948
  • 结果

【C语言】07-指针_第9张图片

指针常量

  • 指针的指向不能变化,但指向的值可以变化
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 1;
    int j = 100;
    
    int *const p = &i;
    
    printf("defore-->%d\n",*p);
    i = 100;
    printf("after-->%d\n",*p);
   
    //p = &j;//报错:向只读位置“p”赋值
}
  • 报错
image-20200621192141948
  • 结果

【C语言】07-指针_第10张图片

即是常量指针又是指针常量

  • 指针的指向不能被改变,指向地址存放的值也不能被改变
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int i = 1;
    int j = 100;
    const int *const p = &i;
    printf("before-->%d\n",*p);
    *p = 10;//报错:向只读位置“*p”赋值
    p = &j;//报错:向只读位置“p”赋值
}
  • 报错
image-20200621192141948

五、指针数组与数组指针

数组指针

定义

  • 指向数组的指针

格式

  • [存储类型] 数据类型 (*指针名) [下标] = 值
int (*p)[3];	-->		int[3] *p;
  • 案例
#include "stdio.h"
#include "stdlib.h"

int main()
{
    int a[2][3] = {1,2,3,4,5,6}; 
    int i,j;
    int *p = *a;
    int (*q)[3] = a;
    
    for(i = 0;i < 2;i++)
    {
        for(j = 0;j < 3;j++)
        {
            printf("%p	-->	%d\n",*(a+i)+j,*(*(a+i)+j)); 
            //printf("%p	-->	%d\n",*(q+i)+j,*(*(q+i)+j)); 
            //printf("%p	-->	%d\n",&a[i][j],a[i][j]);            
        }
		printf("\n");
    }
    printf("%p  %p\n",a,a+1);
    printf("%p  %p\n",q,q+1);
    exit(0);
}
  • 结果

【C语言】07-指针_第11张图片

指针数组

定义

  • 存放指针的数组

格式

  • [存储类型] 数据类型 * 数组名 [长度]
int *arr[3];	-->		int *[3] arr;
  • 案例
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int main()
{
    int i,j,k;
    char *tmp;
    char *name[5] = {"Fllow me","Basic","Great","Fortran","Computer"};
    
    for(i = 0;i < 4;i++)
    {
        k = i;
        for(j = i+1;j < 5;j++)
        {
            if(strcmp(name[k],name[j]) > 0)
                k = j;
        }
        if(k != i)
        {
            tmp = name[i];
            name[i] = name[k];
            name[k] = tmp;
        }
    }
    
    for(i = 0;i < 5;i++)
    	puts(name[i]);
    
    exit(0);
}
  • 结果

【C语言】07-指针_第12张图片

你可能感兴趣的:(c语言,指针,c语言,数据结构)