1、指针数组与数组指针
***********************************************************
我想先说明一下 指针类型 和 地址指向的类型
指针类型,假设是*p的话,就是p的类型,去掉p就是这个指针的类型
当然,有特殊的看法,请见指针数组~↓↓
地址指向的类型,去掉最右边*(),如:char *p,指向char
指针类型和p自身自加自减有关系!!
地址指向类型,就是知道该地址及接下来内存范围的意思,如:int,当时开辟的就是4个字节的内存,首地址及接下来地址里共同放了一个数据。(数据类型,存储类型是一个相当关键的存在,关系到开辟内存的大小以及在内存的区域,栈区?bss?之类的)
当然,*p之类的自加自减和指向类型有关系(二维数组的指针~),char就是加1,int就是加4字节。这个很关键,对于分析问题很有帮助。
*************************************************************
>>>指针数组 char a[] = "hello world"; //定义字符数组,存放在栈区,*a = 'a',ok char *p = "hello world"; //定义一个指针变量p,存放的是字符串常量的首地址,*p = 'a'; error,常量区的内容不能被修改 指针数组是元素类型为指针的数组 数据类型 数组名[元素个数]; int *p[3]; //p先和[]结合,因为[]的优先级比*优先级高 p的类型:int **(这里就有特殊的识别指针类型)
int *p[3];
去掉p[3]留下int *,那为什么p的类型就是int **?
其实是研究的是p的类型,就如a[]一样,a是指针地址常量,p同理,是p[3]的地址
当然p[3] 的类型是int *的话,那么p就为int *(*)即int **
指针数组,首先~它是一个数组,里面装了指针,也就是地址
当然我们要记的是地址永远是4个字节的(32位系统),p[i]占有4个字节的内存,再有就是 int *p[3],p[3]里的地址指向的是int类型(把*号右边的结合体*p[]去掉)我个人到现在,当然还没有学深,放字符串是最棒的。
由于里面放的是地址,那么也可放二维数组的行首地址。抽象出来的模型和二维数组非常契合。
我们可以看到指针数组里放的地址已经发生变化,从原来的4个变为16个,又因为之前定义了int a[][],可以知道每个地址
之间还有4个int数据。
可以看出,用指针数组的时候只用像一般数组一样就行了只不过里面放的是地址,加减值时,是按本指针类型计算~
>>>数组指针指向数组的指针
int a[3]; 数据类型 *指针变量名; int (*p)[3]; --->指针p指向一个有三个int类型元素的数组
它是数组的指针。和上面说的指针数组不一样的,这个可以更好的做自加自减。
我们可以看到每次p++加了12个字节,一个int4个,说明每次就走3个int数据,p++一次,就把a[3]给直接忽略了!
p存放的是数组地址的指针,p里面的地址看作一个3X4字节的连续地址。
自加一次12个字节~我想应该有大致的感觉对付指针了。
给p加1时编译时加了16个字节,数据时4字节的,p加1时过了四个数字1,5,9。
数组的指针是放数组的地址的,二维数组a[0]a[1]a[2](假如是a[3][4]),符合数组地址,而且每个行地址有4个int类型的数据与
int (*)[4]---->每个地址四个int符合。那么有图:
p=&a[0];
或者是p=a;
2、函数 概念:独立的功能模块 作用:提高代码的可读性以及可重用性 定义:存储类型 数据类型 函数名(数据类型 形参名1, 数据类型 形参名2,。。。。。) //函数头 { 函数体; 返回值;(return) } 存储类型:函数的入口地址(函数名) 数据类型:函数的返回值 函数名:遵循标识符的命名规则 形参:是局部变量,调用时分配内存空间,调用完释放 注意:函数之间不能嵌套定义 函数调用:函数名(实参1,实参2,。。。。); 函数声明:如果函数定义在main函数之前,不用声明,否则,就需要声明 声明:存储类型 数据类型 函数名(数据类型 形参名1, 数据类型 形参名2,。。。。。); 存储类型 数据类型 函数名(数据类型, 数据类型,。。。。。); 声明的作用:帮助编译器进行语法检查(函数的实参与形参是否匹配,返回值的类型是否匹配) 函数的传参:1、实参的类型及个数必须与形参的匹配 2、实参可以是常量、可以是变量,还可以是表达式 3、传参实质只是将实参的值拷贝了一份给形参,形参和实参分别占用不同的内存空间 4、形参可以和实参重名 注意:全局变量可以和局部变量重名,并且局部变量会覆盖全局变量 函数的返回值:通过return返回 (return 表达式;) 一维数组传参:首地址、元素个数 int ArrSum(int *Arr, int ArrSize); int ArrSum(int Arr[], int ArrSize); 注意:当数组作为形参时,会退化为指针 参考:要通过指针操作一块连续的内存空间,需要知道从哪里开始(首地址),到哪里结束(元素个数) 二维数组的传参:首地址、行数、列数 int arr2_sum(int m, int n, int (*arr)[n]); int arr2_sum(int m, int n, int arr[][n]);