C语言基础之指针

1,指针的基本概念与定义

指针(Pointer)利用地址,它的值直接指向存在电脑存储器中另一个地方的值
例如:
int * p;
这句代码的意思是:1、定义一个指针变量p,类型是int*。2、p指向一个int型的数据
p = &a;
指针的绑定
*p;
指针的解引用,*p得到了变量值
int *p1 = &a
定义指针的同时并且初始化
p1++;
指针的运算,就是指针所指向的变量类型所占字节大小(sizeof(int)) * 偏移量

2,const关键字

修饰的变量是常数,不可更改,只能初始化一次。

例如:const int a = 23;
则a就被规定好是常量23,不可更改。

3,数组中指针的应用

int arr[5] = {1, 3, 5, 7, 9};

    //arr作右值
    int *p = arr;
    printf("*(p++) = %d.\n", *(p++));   //打印出1,因为++在后面,遇到“;”结尾才+1运算
    printf("*++p = %d.\n", *++p);   //打印出3
    int *q = arr + 5;   
    // 同一数组,指针相减是个数
    int ret = q - p;
    printf("ret = %d.\n", ret);   //打印出5

4,指针的调用

传址调用

#include <stdio.h>
void func2(int *p)
{
    printf("p = %p.\n", p);
    *p = 23;
}
int main(void)
{
    int a = 11;
    printf("&a = %p.\n", &a);
    //传址调用
    func2(&a);
    printf("a = %d.\n", a);
    return 0;
}

上例可以看到,主函数中a的地址与子函数中指针p的地址相同,且a的值变为23;这就是传址调用

指针函数

带指针的函数,即函数返回类型是某一类型的指针

#include <stdio.h>
int * func1(int a)
{   
    //int a相当于局部变量,函数调用结束就销毁
    printf("&a = %p.\n", &a);
    a = 23;
    //不要返回局部变量的地址
    return &a;
}

int main(void)
{
    int val = 0;
    printf("&val = %p.\n", &val);
    int *p = func1(val);

    printf("val = %d.\n", val); 
    printf("p = %p.\n", p);
}

val的值并未改变

数组中的调用

#include <stdio.h>
//1、数组名作为函数参数退化为一个指针 2、子函数内部改变了原数组里面的内容
void func_arr(int *arr, int lenth)  // 
{
    printf("arr = %p. sizeof(arr) = %d.\n", arr, sizeof(arr));

    *arr = 11; // == arr[0] = 11
    arr[1] = 22;        
}

int main(void)
{
    int arr[3] = {2, 5, 8};

    func_arr(arr, 3);

    printf("arr[1] = %d. arr[0] = %d.  \n", arr[1],arr[0]);
    printf("in main arr = %p.\n", arr);
}

malloc函数

动态内存分配,当无法知道内存具体位置的时候,想要绑定真正的内存空间,就需要用到动态的分配内存
需要程序员自己手动申请malloc(写代码),自己手动释放
下面的程序就是一个申请动态数组,并冒泡排序的例子

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

int * shenqing_memory(int num)
{
    int *p = (int *)malloc(num*sizeof(int));

    if (NULL == p)
    {
        return p;
    }
    //初始化清零 
    memset(p, 0, num*sizeof(int));

    return p;
}

void set_value(int p[], int num)
{
    int i = 0;
    //一共赋值num次
    printf("输入%d个元素数值:\n",num);
    for (i=0; i<num; i++)
        scanf("%d", p++);
}
//交换两个数值 
void swap(int *p1, int *p2)
{
    int temp;

    temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

void func_arr(int *p, int lenth)
{
    int i = 0, j = 0;

    for (i=0; i<lenth-1; i++)
    {
        for (j=0; j<lenth-1-i; j++)
        {
            if (*(p+j) > *(p+j+1))
            {
                swap(p+j, p+j+1);
            }
        }
    }   
}

void arr_show(int *arr, int num)
{
    int i = 0;

    while (num--)
    {
        printf("%d ", *arr++);
    }

    printf("\n");
}

int main(void)
{
    int num = 0;

    printf("输入数组个数:");
    scanf("%d", &num);

    int *p = shenqing_memory(num);
    //就可以使用这个内存了
    //赋值这个数组
    set_value(p, num);

    //排序
    func_arr(p, num);

    //遍历函数
    arr_show(p, num);   
    if (NULL != p)
    {
        free(p);
        //p就是一个野指针
        p = NULL;
    }

    return 0;
}

其中,memset是设置内存,要包含#include string头文件;默认的是void* 型,所以要强制类型转换为int*;参数第一个为要设置的内存的首地址,第二个为要设置的内容,第三个为内存整体大小

malloc要包含#include stdlib.h头文件,参数是要申请内存空间的大小,默认也为void*所以要强制类型转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值