C语言指针
一、C语言中的指针
C语言之所以强大就是因为其太灵活了,权限太高了,用的好很厉害,用不好危害性极大。这也是大多数语言放弃指针,真的能放弃吗???答案肯定不行。现在流行高级语言基本上都是从C语言出发的,要想抛弃指针只能从其来源重新设计。但是他们都没有这样做(可能是对UNIX依赖太深了),那么既然危害性(权限)太大了,又没办法重新设计,那么怎么办?穷则变,变则通。那么可以对其进行封装不让人用(面向对象思想),提供接口,你要想用指针,那么就必须通过接口,在接口内对其进行处理,那么不就可以了吗?但是这也是其他语言的局限性。没有两全其美的方法,都是相对的,将其调节到一个平衡点就可以了(计算机中的时空思想,这应该也是算法研究的方向)。
C语言特点:
-
更底层:看来源,C语言是在开发UNIX系统时设计的,由B语言基础上设计的,越到底层越考验对开发者对计算机的组成原理的理解。现在基本上所有计算机系统都是基于UNIX的雏形进行开发,这也是C语言对计算机的重要性。
C语言产生于UNIX操作系统的需求。(有需求就有解决需求的办法)
-
从计算机数据存储看指针:计算机其存储是以bit为单位的,将数据存储在存储单元(存储器)中,现代计算机由冯诺依曼的运算为中心改变为以存储为中心,运算只是方法,将其他知识作为工具(类似物理和数学的关系),运算只是其需求思想的转变。所以现在以大数据为基础进行数据研究。计算机每个存储单元都有其地址,C语言中指针就是对地址的操控(具体是怎样操控的如果有了解的麻烦赐教)。
-
灵活性(危害性): C语言指针对地址进行操控,可以说只要对存储器了解更深,想指哪就可以指哪!简单来说地址就是你们家门牌号,或者是经纬度直接可以找到你。
二、C语言指针,地址关系
-
数据:计算机以 数据 为中心,提供服务。可以这样说计算机就是数据。数据在计算机中存储在内存空间中,内存空间有其地址, 指针指向地址 。
-
C语言中内存申请和释放:(具体操作看操作系统,个人看法,操作系统才是真正的数据结构,算法)
内存申请:当一个程序要运行首先要加载其到内存中,由CPU对其进行操作,得出结果,那么变量层次的内存会随着程序的加载而加载,变量内存申请分为自动和手动,例:
//自动申请 int i; //然后进行操作 //手动申请 //1. #include<malloc.h> //导库函数(具体实现方法看不懂源码) int *r_c = (int*)malloc(8); //申请8Byte空间强转为int指针,用r_c指针指向它的首地址(数组的原理,具体看我的另一篇Blog深入了解数据结构) //2. kmalloc //Linux源码 读源码的重要性 #include <linux/slab.h> void *kmalloc(size_t size, int flags); //3. calloc ANSI规定 size_t void* __cdecl calloc( _In_ _CRT_GUARDOVERFLOW size_t _Count, _In_ _CRT_GUARDOVERFLOW size_t _Size );
内存释放:自动的,当所在函数运行完进行释放(空间清除,存储在里面的找不到了)。手动的,用free()(delete是c++中的)进行释放,不释放内存泄漏,导致致命性错误(慎用)。
C语言中还有一个东西static
关键字,全局静态,特点隐藏数据。函数中使用,函数运行完不释放内存,即下次使用时值还是原来的值,等到程序运行完释放。
-
地址操作案例:
需求:对二维数组遍历查找,返回其目标行列值。
#include<stdio.h> #include<malloc.h> //申请内存空间包 int* find(int *arr, int row, int column, int item); //函数声明 //测试函数 int main() { int row = 3; //二维数组行 int column = 3; //二维数组列 int arr[3][3] = { //初始化 {1,2,3}, {4,5,6,}, {7,8,9} }; int item = 2; //查找的数据 int *row_column; //接收行列位置 row_column = find(*arr,row,column,item); //调用查找函数 printf("item=%d row=%d column=%d \n",item,*row_column,*(row_column +1)); //打印 int *p=row_column+1; free(row_column); //c语言释放内存 //delete [2]row_column; //c++释放空间 return 0; } /* 查找3*3数组 row行column列 目标为 item 返回 保存row column 信息的地址 */ int* find(int *arr, int row, int column, int item) { int *r_c = (int*)malloc(8); //为行列申请空间,int型4Byte,r w 总共为8Byte int *a = arr; //单层遍历 简单方便 for (int i = 0; i < row*column; i++,a++){ if (*a==item){ r_c[0] = i/ row; r_c[1] = i% column; return r_c; } } /* //双循环遍历二维数组 //将形参列表换为int* find(int *arr[3], int row, int column, int item) for (int i = 0; i < row; i++) { //行遍历 for (int j = 0; j < column; j++) { //列遍历 if (item == arr[i][j]) { //找到目标,返回行列信息 r_c[0] = i; r_c[1] = j; return r_c; } } } */ //未找到返回-1,-1 printf("Not find item num!!!\n"); r_c[0] = -1; r_c[1] = -1; return r_c; }
断点调试:
地址申请断点查看:
地址返回查看:
地址释放查看(C语言):
地址释放(C++):