指针与数组
千万不要解引用未初始化的指针
指针常量
C99标准允许这样声明,创建了一种新型数组,称为变长数组(variable-length array)或简称** VLA**(C11放弃了这一创新的举措把 VLA设定为可选,而不是语言必备的特性)。
C99 引入变长数组主要是为了让C成为更好的数值计算语言.
VLA有一些限制,例如,声明 VLA 时不能进行初始化。
int a[10];
a和和&a[0]是等价的
行指针与高维数组
review
一般的定义:
int (*p)[8]; //行指针
p=a;
int *p[8]; //指针数组
int a[10][10];
a[5][6]=7;
int (*p) pa=a;
if(*(*(p+5)+6)==7) printf("OK!");
// *(p+1),*p都是列指针,行指针寻址即为一个列指针
// 反过来,&(p2)把一个列指针转化为行指针
本质上是&a[0]
and a
所代表的不是同一个东西,但是他们的值相同。a[0]
实际上等于&a[0][0]
内含1个int,而 a 等于 &a[0]
含有两个int
a是地址的地址,必须解引用两次才能获得原始值。
指针与函数
返回值为指针的函数
int *function() 返回一个地址
编写一个处理基本类型
(如,int)的函数时,要选择是传递int类型的值还是传递指向int 的指针。通常都是直接传递数值,只有程序需要在函数中改变该数值时,才会传递指针。
对于数组而言,传递指针是更节约内存的选择.传递地址可能造成的问题是直接操作原始数据(而非处理值那样,函数会先copy一份原始数据的副本),而我们有时候希望在函数内部做一些对原始数据的操作.
问题:有时候不需要对原始数据进行修改. 如上运用const解决这一问题.
int sum(const int ar[],int n){
int i;
int total=0;
for(i=0;i<n;i++)
total+=ar[i];
return total;
}
//此处若是ar[i]++会报错
调用时可使用指针变量pa
或数组常量a
def时形参可以使用数组int a[20]
和指针int *m
函数指针
定义函数指针的一般形式如下:
*类型说明符 (指针变量名)(参数列表)
函数指针在调用时要采用如下的形式:
(*指针变量名)(实参列表);
int add(int a,int b);
int (*p) (int,int);
p=add;
int j;
j=(*p)(a,b);
怎么实现可变数组?
array.h
#ifndef _ARRAY_H_
#define _ARRAY_H_
typedef struct
{
int *array;
int size;
} Array;
Array array_create(int init_size);
void array_free(Array *a);
int array_size(const Array *a);
int *array_at(Array *a, int index);
void array_inflate(Array *a, int more_size);
#endif
array.c
#include "array.h"
#include <stdlib.h>
const BLOCK_SIZE = 20;
// typedef struct
// {
// int *array;
// int size;
// }Array;
Array array_create(int init_size)
{
Array a;
a.size = init_size;
a.array = (int *)malloc(sizeof(int) * init_size);
return a;
} //创建数组
void array_free(Array *a)
{
free(a->array);
a->array = NULL;
a->size = 0;
} //回收内存
int array_size(const Array *a)
{
return a->size;
} //返回数组大小 //why do this?-->封装
int *array_at(Array *a, int index)
{
if (index >= a->size)
{
array_inflate(a, (index / BLOCK_SIZE + 1) * BLOCK_SIZE - a->size);
}
return &(a->array[index]);
} // a[index]
void array_inflate(Array *a, int more_size)
{
int *p = (int *)malloc(sizeof(int) * (a->size + more_size));
// for (int i = 0; i < a->size; i++)
// {
// *(p+i)=*((a->array)+i);
// }
memcpy((void *)p, (void *)a->array, a->size * sizeof(int));
// The operation of library functions must be more efficient than our own loops
free(a->array);
a->array = p;
a->size += more_size;
} // key,bigger the array
// create one space new to copy the old's, then delete the old and modify the new
int main(int argc, char const *argv[])
{
//引例
int number;
int cnt = 0;
Array a = array_create(100); // create one array with 100 index
printf("%d\n", array_size(&a)); // print the size of a with the function in the pointer
*array_at(&a, 0) = 10; // a[0]=10
while (1)
{
scanf("%d", &number);
// scanf("%d",array_at(&a,cnt++));
if (number != -1)
*array_at(&a, cnt++) = number;
}
array_free(&a); // free the space
return 0;
}
// Q:内存运用效率低,永远小于1/2.由此,我们一般使用链表去做相关的处理