C语言基础——指针

目录

sizeof ( 指针 )

指针的作用

指针变量

数组指针&指针数组

函数指针

二级指针

面试题

指针常量&常量指针

内存申请与释放

(1)malloc()

(2)calloc()

(3)realloc()

(4)free()


sizeof ( 指针 )

// 指针是地址, 指向某数据空间, 地址常是4字节.

char *p="老师,早上好!";

printf("%ld", sizeof(p);

// 结果:4, 返回指针大小,指针本身就是一个无符号整型数. 不是所指向的内存空间的大小

// char *a[8], 在数组内存放8个地址, 8个*4字节=32字节, 而不是8个*1字节=8字节

*

有地址,跳转地址对应内容

无地址,获取地址

指针的作用

(1)为函数修改实参提供支持

(2)为动态内存分配提供支持

(3)为动态数据结构提供支持

(4)为内存访问提供了另外一种途径

指针变量

内存地址:系统为了内存管理的方便,将内存划分为一个个内存单元,并进行内存单元编码,内存单元的编号就是该内存单元的地址。

变量指针:变量的地址称为该变量的指针。变量的地址往往是内存单元的编号(首地址)。

指针变量:存放变量指针的变量。

指向:指针变量中存放"a"的地址,该指针变量就指向"a"

指针变量的定义

语法格式:类型 * 变量列表;

eg:

   int p ; //p为普通变量

   int * p ; //p为指针变量

   int * a , * b ; //定义了指针变量a和b

注意事项:

(1)虽然定义了指针变量,但是变量名仍为:a,b,p;

(2)使用指针变量访问数据时,指针变量必须要有明确的指向;

(3)int a = 3 ; int * p = & a ;

(4)指针变量只能访问同类型的变量,借助指针访问内存,一次访问内存的大小取决于指针变量类型

(5)指针变量的初始化类似于普通变量的初始化

指针变量的使用

赋值:

(1)

int a = 3 ;

int * p ;

p = & a ;

(2)

int a , * p , * q ;

p = & a ;

q = p ;

操作指针变量的值:       

 int a = 3 ;

 int * q;     q = & a ;

 * q = 6 ;

演示内存数据访问:       

 int a = 9 ;

 int * p = & a ;

     直接访问:a a=999;

     间接访问:* p * p = 888 ;

指针变量做函数参数:指针变量做函数的参数往往传递的是变量地址。

   由于传递的是地址,所以修改实参数据。

数组指针&指针数组

指针变量访问数组元素:

数组指针:指向数组中第一个元素的地址(指针)。   

 int a[]={1,4,9};    

 int * p = &a[0];

 int * q = a;

指针的运算:

指针变量必须要有明确的指向,指向数组中的元素。

   自增 ++p p++ p=p+1 让指针变量指向下一个元素     自减 --p p-- p=p-1 让指针变量指向上一个元素

       加一个数 p+3 向后偏移3个类型的宽度

       减一个数 p-2 向前偏移2个类型的宽度

       指针的比较 p<q 在同一个数组中可以比较

数组指针:指向一维数组的指针变量。

   定义:假设该指针变量指向有N个元素的一维数组。

    数据类型 (* 数组指针变量名)[N];

    e.g.(1)

 int a[N]={1,4,3};

 int (*p)[N];

 p=&a;

(2)

int(*p)[N]=&a;

e.g.(1)

int a[][N]={{1,3},{5,7}};

int (*p)[N]=a;

a[i][j]<---->*(*(p+i)+j)<---->p[i][j]<---->*(p[i]+j)

指针数组:元素是指针变量的数组

指针数组的定义:类型* 数组名[N];

   int* p[6];

字符指针:char* str="I love China";

函数指针

函数指针:指向函数的指针变量(地址入口)

   应用场景之一:传递动作、方法、流程

   定义:类型 (*p)(形参列表);

int max(int a,int b)

{

return a>b?a:b;

}

int (*p)(int,int);

p=max;

利用函数指针调用函数: 

  (*p)(3,6);

   p(3,6);

二级指针

指向指针变量的指针变量(二级指针):

定义格式:类型** p;  

 int a;

 int* p =&a ;

 int**q=&p;

二级指针访问元素需要一级一级的解引用;

二级指针往往用来引用指针数组;

char* name[4]={"zhangsan","lisi","wangwu",NULL};

面试题

在不改变数组的数组元素顺序的情况下,将数组升序输出

#include <stdio.h>

int main() 
{
    // 原数组
    int arr[] = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
    int n = sizeof(arr) / sizeof(arr[0]);

    // 复制原数组到新数组
    int sortedArr[n];
    for (int i = 0; i < n; i++) 
    {
        sortedArr[i] = arr[i];
    }

    // 使用冒泡排序对复制后的数组进行升序排序
    for (int i = 0; i < n - 1; i++) 
    
    {
        for (int j = 0; j < n - i - 1; j++)    
        {
            if (sortedArr[j] > sortedArr[j + 1]) 
            {
                // 交换元素
                int temp = sortedArr[j];
                sortedArr[j] = sortedArr[j + 1];
                sortedArr[j + 1] = temp;
            }
        }
    }

    // 输出排序后的数组
    printf("升序排序后的数组: ");
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", sortedArr[i]);
    }
    printf("\n");

    // 验证原数组未改变
    printf("原数组: ");
    for (int i = 0; i < n; i++) 
    {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

指针常量&常量指针

指针常量:类型* const 指针变量名

   int * const p ;

常量指针:const 类型* 指针类型名

   const int * p ;

区分:

     (1)先读常量,先写const ; 后读常量,后写const

   constant : 常量

     * : 指针

     (2)*是指针,const是常量

       名字在前,对应参数不可修改     

 int a = 9 ;

 int b = 3 ;

 const int * p = & a ;

 p = & b ; //right

*p=999; //error

   *p可以访问,但是不能修改常量(*p);

 int * const p = & a ;

 p = & a ; //error

 * p = 999 ;//right

 p = & b ; //error

内存申请与释放

动态内存管理:在堆段进行内存的申请与释放。

(1)malloc()

头文件:#include<stdlib.h>

函数原型:void* malloc(size_t size);

函数功能:在堆上申请size大小(单位是字节)

函数参数:size:字节大小

返回值:成功:返回申请内存的首地址

   失败:返回NULL

     int * p =(int*)malloc(100);

(2)calloc()

头文件:#include<stdlib.h>

函数原型:void* calloc(unsigned n,unsigned size);

函数功能:在堆上申请n个长度为size大小的连续空间(单位是字节)

函数参数:size:字节大小

返回值:成功:返回申请内存的首地址

   失败:返回NULL

     int * p =(int*)calloc(50,4);

(3)realloc()

头文件:#include<stdlib.h>

函数原型:void* realloc(void *p,unsigned int size);

函数功能:在堆上将p指向的临时分配域的大小改变为size大小(单位是字节)

函数参数:size:字节大小

返回值:成功:返回申请内存的首地址

   失败:返回NULL

     realloc(p,100);

(4)free()

头文件:#include<stdlib.h>

函数原型:void free(void *p);

函数功能:释放由指针变量p指向的动态空间,使这部分空间能被其它变量使用。

函数参数:p:是最近一次调用callo或malloc函数时的返回值。

返回值:该函数无返回值。

   free(p);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值