C语言 指标、阵列与结构

相较于基本型別int, double,C语言还有衍伸資料型別(Derived datatype)。
 留言

其中很常被应用的,就是指標(pointer)、陣列(Array)、結構(struct)

指标(Pointer)
指标的设计,是为了让CPU可以间接取得资料,有以下优点:

可动态配置/释放记忆体
不同的函式可共享大量的储存空间
改善程式存取资料的效率
指标的特性
指标本身是一个物件,指向任何一个已存在物件,可以被指定或拷贝

指标宣告时,就要定义是指向哪种资料型态的物件
指标本身储存的值,有三种情况
指向一个物件,值里面存放另一个物件的位址
指向另一个物件尾端后的位置
没有指向任何物件,值即为null

int i = 42;
  int *p = &i;            //p指向i
#include <stdio.h>
int main() {
  int i = 42;     
  int *p;       //* 跟在一个型别,且是宣告的一部份,所以p是一个pointer
  p = &i;       //p指向i

  printf("i: %d\n", i);
  printf("*p: %d\n", *p);
  printf("p: %p\n", p);
  printf("&i: %p\n", &i);
  return 0;
}

阵列(Array)
 留言
阵列的定义
是一个复合资料型别,放置单一型别物件的容器,并且以位置来存取它们,有固定的尺寸。

通常是存放char,int型别的资料

字元阵列的特性
在C语言,一个字串本身会在结尾自带\0结束字元,所以当我们把一个字串用阵列储存时,实际结尾会有一个\0也被储存。

例如:char str[20] = "Hello"
在阵列的存放,是一个长度为6的阵列,最后摆放\0

宣告与初始化阵列

靜態宣告
 

int a[10];   //宣告一个10个int物件的阵列
int *p[10];  //宣告一个10个int指标的阵列

因为阵列的长度要在编译期就决定好。如果想要在执行期动态生成阵列,要用动态配置记忆体的方式。

动态宣告
我们同样用malloc() 函式来配置记忆体。参考以下叙述:

int *arr = (int *) malloc(sz * sizeof(int));

我们以sizeof 求得单一元素的大小后,乘上阵列的长度sz 即可配置一块足够大小的记忆体,用来储存阵列arr 的元素。由此可知,阵列在电脑中以是一整块连续的记忆体来储存,所以可以用索引值快速存取。
 留言

如果想要在配置记忆体时一并将元素初始化为0,改用calloc() 函式即可。但calloc() 函式的参数略有不同:

int *arr = (int *) calloc(sz, sizeof(int));

由于多了初始化的动作,calloc() 函式会比malloc() 函式慢一点点。
 留言

使用完后同样要释放记忆体:

free(arr);

由于阵列内部是单一且连续的记忆体区块,所以可在单一free() 函式呼叫中释放掉。不论使用malloc() 或calloc(),皆使用free() 来释放记忆体。

我们来看一个动态配置记忆体阵列的范例:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int size = 0;

    printf("输入长度:");
    scanf("%d", &size);

    int *arr = malloc(size * sizeof(int));

    printf("指定元素:\n");
    for(int i = 0; i < size; i++) {
        printf("arr[%d] = ", i);
        scanf("%d" , arr + i);
    }

    printf("显示元素:\n");
    for(int i = 0; i < size; i++) {
        printf("arr[%d] = %d\n", i, *(arr+i));
    }

    free(arr);

    return 0;
}

存取阵列元素
阵列使用零或正整数存取阵列元素。参考以下范例:

#include <stdio.h>        

int main(void)             
{                        
    int arr[] = {3, 4, 5};  

    printf("%d", arr[0]);   
    printf("%d", arr[1]);   
    printf("%d", arr[2]);   

    return 0;            
}                       

指标算术
对一个指标做加减,会移动指向阵列中的位置

#include <stdio.h>

int main(void)
{
    int arr[] = {3, 4, 5, 6, 7};
    
    for (int i = 0; i < 5; i++) {
        printf("%d\n", arr[i]);   
    }

    return 0;
}

计算阵列大小
C 阵列本身没有储存阵列大小的资讯。如果想要知道阵列的大小,得自行计算。参考下例:

#include <stdio.h>                                          
int main(void)                              
{                                           
    int arr[] = {3, 4, 5, 6, 7};            

    int sz = sizeof(arr) / sizeof(int);  

    printf("%d", sz);                       

    return 0;                           
} 

在此范例程式中,我们在第6 行分别计算阵列大小和阵列元素大小,将其相除后即可得阵列长度。在本例中其值为5。
 留言

但这个方式只对自动配置记忆体的阵列有效,若阵列使用动态配置记忆体,则无法使用这个方法。

多维阵列
先前的范例皆为一维阵列,但C 语言允许多维阵列。参考以下宣告多维阵列的叙述:

int mtx[3][2] = {
    {1, 2},
    {3, 4},
    {5, 6}
};

我們同樣可以對多維陣列存取索引值:

#include <stdio.h>

int main(void)
{
    int mtx[3][2] = {
        {1, 2},
        {3, 4},
        {5, 6}
    };

    printf("%d\n", mtx[1][1]);

    return 0;
}

结构(struct)
宣告struct
结构(struct)可以让使用者创造自己定义的资料型别

例如一本书的销售资讯包含多种资料:

struct Sales_data {
  char* book_no;
  int units_sold;
  int price;
  double revenue;
};

其中book_no, units_sold , price,revenue是这个struct的data members,简称members

呼叫struct

#include <stdio.h>

struct Sales_data {
  char* book_no;
  int units_sold;
  int price;
  double revenue;
};

int main() {
    struct Sales_data book1;
    book1.book_no = "AAA";
    book1.units_sold = 1000;
    book1.price = 200;
    book1.revenue = book1.units_sold * book1.price;
    
    printf("Revenue: %.2f\n", book1.revenue);
    
    return 0;
}

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值