首頁>技術>

ANSI C把typedef也作為一種儲存型別,合理嗎?

看下面的例項:

#include<stdio.h>#define SIZE 10typedef int ARRAY [10];         //自定義一個int [10]的整型陣列型別void reverseInt(int a[],int n) //整型陣列的反轉{    int i,t;    for(i=0; i<n/2; i++)    {        t=a[i];        a[i]=a[n-1-i];        a[n-1-i]=t;    }}void reverseInt(ARRAY a)	        // a這裡還會退化為一個指標{    int n=sizeof(ARRAY)/sizeof(int); // sizeof a 只是一個指標的長度    for(int i=0; i<n/2; i++)    {        int t=a[i];        a[i]=a[n-1-i];        a[n-1-i]=t;    }}void outputArray(int a[],int n){    for(int i=0; i<SIZE; i++)         printf("%3d",a[i]);    printf("\n");}int main(){    int a[] ={1,2,3,4,5,6,7,8,9,10};            int size = sizeof a / sizeof *a;    outputArray(a,size);    reverseInt(a,size);						    outputArray(a,size);    ARRAY b={11,12,13,14,15,16,17,18,19,20};//用ARRAY型別定義陣列a    size = sizeof b / sizeof *b;    outputArray(b,size);    reverseInt(b);						    outputArray(b,size);        while(1);    return 0;}/*  1  2  3  4  5  6  7  8  9 10 10  9  8  7  6  5  4  3  2  1 11 12 13 14 15 16 17 18 19 20 20 19 18 17 16 15 14 13 12 11 */

作為資料型別資訊,重要的是能夠確定其對應記憶體塊的長度,及其之上能夠執行的操作。由上例可見,typedef不同於#define的值替換,是有型別資訊的。

理解變數,理解對應的記憶體塊的長度很重要,在C中,有專門的運算子sizeof。

對於內建(built-in)型別,其長度資訊由型別關鍵字來定義。

對於結構體,其長度資訊由各成員分量及其對齊來定義。

對於列舉,是一種特殊的int型別。

對於共用體,佔用空間最大的型別的長度就是共用體整體的長度。

其實比較複雜的是多維陣列。

因為陣列名在不同的上下文中有不同的含義。在宣告和使用sizeof時可以代表陣列整體,其長度是陣列全體成員累加的長度。當陣列名用做函式引數時,其退化為指標,表示的是陣列首元素的地址,其指標指向的長度資訊是元素的長度(第一維的長度,如果是一個n維陣列,其第一維的長度就是n-1維的整體長度),至於整體的長度資訊(每一維的元素個數)則丟失了,所以一般在陣列名作引數時,另需一個int型別引數來指定陣列第一維的元素個數:

#include <iostream>using namespace std;int arr[3][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};void func(int arr[][5],int rows){    cout<<sizeof arr <<endl;    // 4    cout<<sizeof *arr <<endl;   // 20    for(int i=0;i<rows;i++)    {        for(int j=0;j<5;j++)            cout<<*(*(arr+i)+j)<<" ";        cout<<endl;    }}int main(){    cout<< sizeof arr<<endl;                    // 60,                    // 此時的陣列名錶示整個陣列,其長度資訊是整個陣列的長度    cout<< sizeof *arr<<endl;                   // 20    int rows = sizeof arr / sizeof *arr;    cout<< rows <<endl;     // 3    cout<< sizeof arr / sizeof **arr <<endl;    // 15    func(arr,rows);    int (*p)[5] = arr;   // 此時的陣列名是陣列首元素,其長度資訊是陣列元素的長度    cout << sizeof *p <<endl;  // 20    while(1);    return 0;}

對於函式指標,這個指標也是指向一塊記憶體,是函式的儲存區域,其型別資訊自然是函式,同樣也標識出了這一塊記憶體的起始和結束地址。毫無疑問,起始地址是函式名,結束地址由return或符號“}”來標識。

-End-

12
最新評論
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • Python實現按日期歸檔檔案