【C语言笔记2】指针、数组

文章详细介绍了C语言中的指针与数组的关系,包括变长数组(VLA)的概念及其限制,行指针与高维数组的交互,以及如何通过指针进行函数调用和内存管理。同时,文章提供了创建和管理动态数组的示例代码,强调了在处理数组时考虑内存效率的重要性。
摘要由CSDN通过智能技术生成

指针与数组

千万不要解引用未初始化的指针

指针常量

在这里插入图片描述
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.由此,我们一般使用链表去做相关的处理



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值