C语言指针操作

欢迎访问我的新博客:http://www.milkcu.com/blog/

原文地址:http://www.milkcu.com/blog/archives/pointer-manipulation.html

原创:C语言指针操作

作者:MilkCu

摘要:指针是C语言的核心,也是一个普通变量,存储的是内存中的地址。在存储空间的分配中,一种常遵循的理念是,由用户管理存储空间以及与存储空间相关的实际的数据结构,而数据结构自身只用于维护数据内部变量的存储空间的分配。C语言使用基于堆的内存分配,通常也称作动态存储分配。

指针基础

一个指针其实只是一个变量,它存储数据在内存中的地址,而不是存储数据本身。

可能产生悬空指针的一些编程错误事例包括:

  • 将任意的整型变量强制转换为指针变量;

  • 操作超出数组边界的指针;

  • 释放一个或多个仍被引用的指针。

存储空间分配

通常情况下,指针会占用一个机器字长的存储空间,但有些时候它们的大小也有所不同。

用malloc分配的存储空间会一直有效,知道调用函数free来释放它。

内存泄露问题的产生是由于动态分配了内存空间,但从未释放它造成的。特别是在重复执行代码时,这种泄露问题会表现得尤为重要。

一种统一的内存管理方法所遵循的理念是,由用户管理存储空间以及与存储空间相关的实际的数据结构,而数据结构自身只用于维护数据内部变量的存储空间的分配。所以,在数据结构中,只使用指针指向数据变量,而不是此数据的私有副本。

数据集合与指针的算术运算

指针在C语言中最长见的用途就是用来引用数据集合。C语言支持两种数据集合:结构和数组。

结构不允许包含自身的实例,但可以包含指向自身实例的指针。

当一个数组标识符在表达式中出现时,C语言会把数组转换为一个指向数组第一个元素的指针。

在C语言中,多为数组其实是以行主序的方式存储的,这也就说明多维数组右边下表变化速度要比左边下标变化来的更快。

二维数组第i行第j列的元素,用a[i][j]表示,等价于((a + i) + j)。

作为函数参数的指针

当把一个多维数组传递给函数时,除了第一维以外其他维的长度必须指定。

泛型指针与类型转换

泛型指针不指定具体的数据类型。可以使用泛型指针实现交换任何类型数据的通用交换函数。

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

int swap2(void *x, void *y, int size)
{
    void * tmp;
    if((tmp = malloc(size)) == NULL) {
        return -1;
    }
    memcpy(tmp, x, size);
    memcpy(x, y, size);
    memcpy(y, tmp, size);
    free(tmp);
    return 0;
}

int main(void)
{
    int a = 2;
    int b = 3;
    swap2(&a, &b, sizeof(int));
    printf("a = %d
b = %d
", a, b);
    return 0;
}

地址取到什么类型的值是由我们用什么类型的指针访问它所决定的。

函数指针

声明函数指针看起来与声明一个函数非常相似,只是在函数名前有一个表示指针的星号,并且函数名和星号会用圆括号括起来。

函数指针的一个重要用途是将函数封装到数据结构中,它可以使数据结构或函数变得更具通用性。

基于堆的内存​分配

C语言使用基于堆的内存分配,通常也称作动态存储分配。它允许一个程序在运行时请求更多所需要的内存,而不是在编译时就分配固定数额的内存。

(全文完)

本文地址:http://www.milkcu.com/blog/archives/pointer-manipulation.html

原文地址:https://www.cnblogs.com/milkcu/p/3808918.html