指向数组的指针
Int a[10] = {1,2,3,4,5,6,7,8,9,0}; &a是对a 这个一维整形数组取地址,就是a数组首元素a[0]的地址, 即 数组指针。
int * 型指针 p 不能存放 一维数组的地址,左右两边类型不匹配
如果要存放一维数组a的地址 应该 这样定义p
Int (*p)[10]; 这个指针的基类型是长度为10的一维整形数组。
注意区分 int *p[10]; 这是定义了一个长度为10的 int *型的数组
当 初始化 int (*p)[10];时 p 与 p +1 ;地址相差 基类型 int [10]个字节即40个字节
如上图:要创造一个指针来装a[0]的地址则需要 使用 int (*p)[4]; 来初始化指针p
p = a 即 p指针里存放的是一个长度为四的整形一维数组a[0]。
当 p + 1 时 指针变量p将会加 int [4] 个字节 指向 a[1]的地址即a[1]的首地址。
// *( p + 1) == p [1] == a[1]。
*(p + 1)的类型是 int * , 即指的是a[1]里首元素的地址。
*(p + 1) + 2, + 2 即向后偏移八个字节。在 *(p + 1 )的基础上
*(*(p + 1) +2) 是int型,打印出来指针指向的a[1][2]的值是7
// a[i][j] <=> *(*(a+i)+j) 二维数组 用指针表示。
a[i] = *(a+i) a[i][j] = *(*(a + i) + j)
第一个括号( a + 3 ) a 的类型为 与int (*p)[4] 相同的类型 即int * [4] +3即是向后偏移 3 * 4 * 4 个字节, 第二个括号 (int *) 将(a + 3 )类型强转为 int * 型,整体 – 3 即向前偏移 3 * 4 个字节。指向a[2][1] = 10。
二维数组的函数作为参数,形参为指向数组的指针本身。
值是一个指针的为 指针函数
动态内存分配
Void *malloc(size_t size); 函数
是 指针函数 需要包含头文件 <stdlib.h>
作用是分配一个连续的空间。 分配的空间 在 堆区. Malloc( )括号内空间的单位是字节数。
指针P 指向malloc分配的连续内存的首地址。分配的内存没有初始化全是随机数
Malloc 函数使用后 需要使用 free(p); 释放空间,p的地址必须是使用malloc时的地址,不能被修改,如必须修改,则先备份。
连续使用两次malloc 函数时,这两个空间一定不连续。
int * p = realloc(p, m * sizeof(int));
Static
修饰 变量 I 使i从动态生存期变为静态生存期,出了子函数不会被销毁。
可以使其出了函数可以被调用。
返回值为指针的函数 不能返回 在函数内部定义的局部变量地址,因为在函数结束时会被销毁。
指针的指针
也称为二级指针
程序在第14-15行崩溃,S为野指针
指针 s 在调用 getMemory函数时 是进行的值传递,指针S没有初始化,在调用函数时,只是将s所指向的地址传给指针变量p, p是s的复制品。值传递不能在被调修改主调。
要在被调函数修改指针s:
被调函数 形参要修改为 char **p 函数中 p 修改为 *p
调用函数时要传递s的地址, &s。
例:
指针的数组
定义了一个指针数组,
数组中有十个指针, sizeof(a) 的 大小为80个字节。
指针数组作为函数参数传递,形参是指针的指针。
函数名 s <<==>>&s[0] 即数组名 就代表该数组的首元素地址
代码练习:
e1.实现二维数组的打印,累加,反转,通过传参数组指针实现。
void printArray2D(int (*a)[4], int rows)
{
int i, j;
for(i = 0; i < rows; ++i)
{
for(j = 0; j < 4; ++j)
{
printf("%d\n",*(*(a+i)+j));
}
printf("\n");
}
}
int sumOfArray2D(int (*a)[4], int rows)
{
int cols = sizeof(*a) / sizeof(**a);
int sum = 0, i = 0 , j = 0;
for(i = 0; i < rows; ++i)
{
for(j = 0; j < cols; ++j)
{
if(0 == i || rows - 1 == i || 0 == j || cols - 1 == j)
{
sum += *((*a + i) + j);
}
}
}
return sum;
}
void swap(int *a, int *b)
{
int t = *a;
*a = *b;
*b = t;
}
void reverse(int *begin, int *end)
{
while(begin < end)
{
swap(begin,end);
++begin;
--end;
}
}
void reverseArray2D(int (*a)[4], int rows)
{
int cols = sizeof(*a) / sizeof(**a);
int i = 0;
while(i < rows)
{
reverse(*(a + i) ,*(a + i) + cols -1);
++i;
}
}
int main(int argc, const char *argv[])
{
int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
int rows = sizeof(a) / sizeof(*a);
int cols = sizeof(*a) / sizeof(**a);
// reverseArray2D(a,rows);
reverse(*(a+1),*(a + 1) + cols -1);
printArray2D(a,rows);
// int sum = sumOfArray2D(a,rows);
// printf("%d\n",sum);
return 0;
}