วิธีค้นหา 'sizeof' (ตัวชี้ที่ชี้ไปยังอาร์เรย์)


309

ก่อนอื่นนี่คือรหัสบางส่วน:

int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

มีวิธีการหาขนาดของอาเรย์ที่ptrชี้ไป (แทนที่จะแค่ให้ขนาดของมันซึ่งเป็นสี่ไบต์บนระบบ 32 บิต)?


84
ฉันเคยใช้ parens กับ sizeof เสมอ - แน่ใจว่ามันทำให้ดูเหมือนการเรียกใช้ฟังก์ชัน แต่ฉันคิดว่ามันชัดเจนกว่า
Paul Tomblin

20
ทำไมจะไม่ล่ะ? คุณมีบางอย่างกับวงเล็บที่ฟุ่มเฟือยหรือไม่? ฉันคิดว่ามันอ่านง่ายขึ้นกับพวกเขาด้วยตัวเอง
David Thornley

6
@Paul: ดี .. สมมติว่าด้านซ้ายมือของการโทรนั้นเป็นตัวชี้ไปยัง int ฉันจะเขียนมันเป็น int * ptr = malloc (4 * sizeof * ptr); ซึ่งสำหรับฉันนั้นชัดเจนยิ่งกว่า น้อย parens ที่จะอ่านและนำค่าคงที่ตัวอักษรไปข้างหน้าเช่นเดียวกับในคณิตศาสตร์
คลาย

4
@unwind - อย่าจัดสรร array ของพอยน์เตอร์เมื่อคุณหมายถึงอาร์เรย์ของ ints!
Paul Tomblin

6
ไม่มี "ตัวชี้ชี้ไปที่อาร์เรย์" ที่นี่ เพียงแค่ตัวชี้ชี้ไปที่ int
newacct

คำตอบ:


269

ไม่คุณไม่สามารถ คอมไพเลอร์ไม่ทราบว่าตัวชี้นั้นชี้ไปที่อะไร มีเทคนิคเป็นเช่นสิ้นสุดอาร์เรย์ที่มีค่าที่รู้จักกันออกจากวงแล้วนับขนาดจนถึงค่าที่ sizeof()แต่ที่ไม่ได้ใช้

เคล็ดลับอีกอย่างหนึ่งคือZan ที่กล่าวถึงซึ่งจะซ่อนขนาดไว้ที่ใดที่หนึ่ง ตัวอย่างเช่นหากคุณจัดสรรอาร์เรย์แบบไดนามิกให้จัดสรรหนึ่งบล็อกที่ใหญ่กว่าอันที่คุณต้องการซ่อนขนาดใน int แรกและกลับptr+1เป็นตัวชี้ไปยังอาร์เรย์ เมื่อคุณต้องการขนาดให้ลดจำนวนตัวชี้และมองตามค่าที่ถูกจัดเก็บ เพียงจำไว้ว่าให้เพิ่มทั้งบล็อกเริ่มต้นจากจุดเริ่มต้นไม่ใช่เฉพาะอาร์เรย์


12
ฉันขอโทษสำหรับการโพสต์ความคิดเห็นนี้ช้า แต่ถ้าคอมไพเลอร์ไม่ทราบว่าตัวชี้จะชี้ไปที่วิธีฟรีรู้จำนวนหน่วยความจำเพื่อล้าง? ฉันรู้ว่าข้อมูลนี้ถูกเก็บไว้ภายในสำหรับฟังก์ชั่นที่ชอบใช้งานฟรี ดังนั้นคำถามของฉันคือทำไม 'ผู้รวบรวมสามารถทำได้เช่นกัน?
viki.omega9

11
@ viki.omega9 เพราะฟรีขนาดที่ค้นพบรันไทม์ คอมไพเลอร์ไม่สามารถรู้ขนาดได้เนื่องจากคุณสามารถทำให้อาร์เรย์มีขนาดแตกต่างกันขึ้นอยู่กับปัจจัยของรันไทม์ (อาร์กิวเมนต์บรรทัดคำสั่งเนื้อหาของไฟล์เฟสของดวงจันทร์ ฯลฯ )
พอลทอมบลิน

15
การติดตามอย่างรวดเร็วทำไมไม่มีฟังก์ชั่นที่สามารถคืนขนาดได้อย่างอิสระ?
viki.omega9

5
ถ้าคุณสามารถรับประกันได้ว่าฟังก์ชั่นนั้นถูกเรียกด้วยหน่วยความจำ malloced เท่านั้นและไลบรารีจะติดตามหน่วยความจำ malloced ตามที่ฉันเห็น (โดยใช้ int ก่อนตัวชี้ที่ส่งคืน) จากนั้นคุณก็สามารถเขียนได้ แต่ถ้าตัวชี้ไปยังอาร์เรย์แบบคงที่หรือคล้ายกันก็จะล้มเหลว ในทำนองเดียวกันไม่มีการรับประกันว่าขนาดของหน่วยความจำ malloced สามารถเข้าถึงได้ในโปรแกรมของคุณ
Paul Tomblin

9
@ viki.omega9: อีกสิ่งที่ควรคำนึงคือขนาดที่บันทึกโดยระบบ malloc / free อาจไม่ใช่ขนาดที่คุณต้องการ คุณ malloc 9 ไบต์และรับ 16. Malloc 3K ไบต์และรับ 4K หรือสถานการณ์ที่คล้ายกัน
Zan Lynx

85

คำตอบคือ "ไม่"

สิ่งที่โปรแกรมเมอร์ C ทำคือเก็บขนาดของอาเรย์ไว้ที่ใดที่หนึ่ง มันอาจเป็นส่วนหนึ่งของโครงสร้างหรือโปรแกรมเมอร์สามารถโกงmalloc()หน่วยความจำได้มากกว่าที่ร้องขอเพื่อเก็บค่าความยาวก่อนที่จะเริ่มอาร์เรย์


3
นั่นเป็นวิธีที่สตริงปาสกาลถูกนำไปใช้
dsm

6
และเห็นได้ชัดว่าสตริงปาสกาลเป็นสาเหตุที่ทำให้ excel ทำงานเร็วมาก!
Adam Naylor

8
@ อดัม: มันเร็วมาก ฉันใช้มันในรายการของการใช้สตริงของฉัน มันเร็วมากในการค้นหาแบบเชิงเส้นเนื่องจากขนาดโหลดโหลดล่วงหน้า pos + ขนาดเปรียบเทียบขนาดกับขนาดการค้นหาถ้าเท่ากับ strncmp เลื่อนไปที่สตริงถัดไปทำซ้ำ มันเร็วกว่าการค้นหาแบบไบนารี่ถึง 500 สตริง
Zan Lynx

47

สำหรับอาร์เรย์แบบไดนามิก ( mallocหรือ C ++ ใหม่ ) คุณต้องจัดเก็บขนาดของอาร์เรย์ตามที่ผู้อื่นกล่าวถึงหรืออาจสร้างโครงสร้างตัวจัดการอาร์เรย์ที่จัดการเพิ่มลบเอาออกนับ แต่น่าเสียดายที่ C ไม่สามารถทำเช่นนี้ได้ C ++ โดยทั่วไปคุณจะต้องสร้างมันขึ้นมาสำหรับอาเรย์แต่ละประเภทที่คุณจัดเก็บซึ่งยุ่งยากถ้าคุณมีอาเรย์หลายประเภทที่คุณต้องจัดการ

สำหรับอาร์เรย์แบบสแตติกเช่นในตัวอย่างของคุณมีแมโครทั่วไปที่ใช้เพื่อรับขนาด แต่ไม่แนะนำเนื่องจากไม่ตรวจสอบว่าพารามิเตอร์เป็นอาร์เรย์แบบสแตติกจริงๆหรือไม่ แม้ว่าจะใช้มาโครในรหัสจริงเช่นในส่วนหัวเคอร์เนลของ Linux แม้ว่าอาจแตกต่างจากด้านล่างเล็กน้อย:

#if !defined(ARRAY_SIZE)
    #define ARRAY_SIZE(x) (sizeof((x)) / sizeof((x)[0]))
#endif

int main()
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", ARRAY_SIZE(days));
    printf("%u\n", sizeof(ptr));
    return 0;
}

คุณสามารถ google ด้วยเหตุผลที่ต้องระวังมาโครเช่นนี้ ระวัง.

ถ้าเป็นไปได้ c ++ stdlib เช่น vector ซึ่งปลอดภัยกว่าและใช้งานง่ายกว่ามาก


11
ARRAY_SIZE เป็นกระบวนทัศน์ทั่วไปที่ใช้โดยโปรแกรมเมอร์ทั่วไปทุกที่
Sanjaya R

5
ใช่มันเป็นกระบวนทัศน์ทั่วไป คุณยังคงต้องใช้มันอย่างระมัดระวังแม้ว่ามันจะง่ายต่อการลืมและใช้ในอาเรย์แบบไดนามิก
ไรอัน

2
ใช่ประเด็นที่ดี แต่คำถามที่ถูกถามนั้นเกี่ยวกับตัวชี้หนึ่งไม่ใช่อาร์เรย์คงที่
Paul Tomblin

2
ARRAY_SIZEมาโครนั้นจะทำงานได้ถ้าอาร์กิวเมนต์ของมันคืออาร์เรย์ (เช่นการแสดงออกของประเภทอาร์เรย์) สำหรับสิ่งที่เรียกว่า "ไดนามิกอาเรย์" คุณจะไม่ได้รับ "อาเรย์" ที่แท้จริง (นิพจน์ประเภทอาเรย์) (แน่นอนคุณทำไม่ได้เนื่องจากประเภทอาร์เรย์รวมขนาดของมันไว้ในเวลารวบรวม) คุณเพิ่งเห็นพอยน์เตอร์ไปที่องค์ประกอบแรก ข้อคัดค้านของคุณ "ไม่ได้ตรวจสอบว่าพารามิเตอร์เป็นอาร์เรย์แบบสแตติก" ไม่ถูกต้องจริง ๆ หรือไม่เนื่องจากมันต่างกันเนื่องจากหนึ่งเป็นอาร์เรย์และอีกอันไม่ใช่
newacct

2
มีฟังก์ชันเทมเพลตที่ลอยอยู่รอบ ๆ ซึ่งทำสิ่งเดียวกัน แต่จะป้องกันการใช้พอยน์เตอร์
Natalie Adams

18

มีวิธีทำความสะอาดด้วยภาษา C ++ แม่แบบโดยไม่ต้องใช้sizeof () ฟังก์ชันgetSize ()ต่อไปนี้คืนค่าขนาดของอาเรย์แบบคงที่:

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

นี่คือตัวอย่างที่มีโครงสร้างfoo_t :

#include <cstddef>

template<typename T, size_t SIZE>
size_t getSize(T (&)[SIZE]) {
    return SIZE;
}

struct foo_t {
    int ball;
};

int main()
{
    foo_t foos3[] = {{1},{2},{3}};
    foo_t foos5[] = {{1},{2},{3},{4},{5}};
    printf("%u\n", getSize(foos3));
    printf("%u\n", getSize(foos5));

    return 0;
}

เอาท์พุท:

3
5

T (&)[SIZE]ฉันไม่เคยเห็นสัญกรณ์ คุณช่วยอธิบายสิ่งนี้ได้อย่างไร? นอกจากนี้คุณสามารถพูดถึง constexpr ในบริบทนี้
WorldSEnder

2
มันดีถ้าคุณใช้ c ++ และคุณมีตัวแปรประเภทอาร์เรย์ ไม่มีในกรณีนี้คำถาม: ภาษาคือ C และสิ่งที่ OP ต้องการรับขนาดอาร์เรย์เป็นตัวชี้อย่างง่าย
Oguk

รหัสนี้จะนำไปสู่การขยายตัวของรหัสโดยการสร้างรหัสเดียวกันใหม่สำหรับชุดค่าผสม / ขนาดที่แตกต่างกันทุกครั้ง
user2796283

@WorldSEnder: นั่นคือไวยากรณ์ C ++ สำหรับการอ้างอิงประเภทอาร์เรย์ (โดยไม่มีชื่อตัวแปรเพียงขนาดและองค์ประกอบประเภท)
ปีเตอร์กอร์เดส

@ user2796283: ฟังก์ชั่นนี้ได้รับการปรับให้เหมาะสมที่สุดในเวลารวบรวม; ไม่จำเป็นต้องใช้เวทย์มนตร์ มันไม่ได้รวมอะไรเข้ากับคำจำกัดความเพียงอย่างเดียว แต่มันรวมเข้ากับค่าคงที่เวลาการคอมไพล์ (แต่ใน debug บิลด์คุณจะมีฟังก์ชั่นแยกต่างหากที่คืนค่าคงที่ต่างกัน) Linker เวทย์มนตร์อาจรวมกลุ่มที่ใช้ค่าคงที่เท่าเดิมผู้โทรไม่ผ่านSIZEเป็น arg มันเป็นเทมเพลตพารามิเตอร์ที่มี เพื่อให้เป็นที่รู้จักกันแล้วในนิยามฟังก์ชัน)
Peter Cordes

5

สำหรับตัวอย่างเฉพาะนี้ใช่มีถ้าคุณใช้ typedefs (ดูด้านล่าง) แน่นอนถ้าคุณทำเช่นนี้คุณก็สามารถใช้ SIZEOF_DAYS ได้เช่นกันเนื่องจากคุณรู้ว่าตัวชี้ชี้ไปที่อะไร

หากคุณมีตัวชี้ (เป็นโมฆะ *) ตามที่ส่งคืนโดย malloc () หรือสิ่งที่คล้ายกันดังนั้นจะไม่มีวิธีกำหนดโครงสร้างข้อมูลที่ตัวชี้ชี้ไปดังนั้นจึงไม่มีวิธีกำหนดขนาดของมัน

#include <stdio.h>

#define NUM_DAYS 5
typedef int days_t[ NUM_DAYS ];
#define SIZEOF_DAYS ( sizeof( days_t ) )

int main() {
    days_t  days;
    days_t *ptr = &days; 

    printf( "SIZEOF_DAYS:  %u\n", SIZEOF_DAYS  );
    printf( "sizeof(days): %u\n", sizeof(days) );
    printf( "sizeof(*ptr): %u\n", sizeof(*ptr) );
    printf( "sizeof(ptr):  %u\n", sizeof(ptr)  );

    return 0;
} 

เอาท์พุท:

SIZEOF_DAYS:  20
sizeof(days): 20
sizeof(*ptr): 20
sizeof(ptr):  4

5

ตามที่ระบุไว้ทั้งหมดคำตอบที่ถูกต้องคุณไม่สามารถรับข้อมูลนี้จากค่าตัวชี้ที่ลดลงของอาร์เรย์เพียงอย่างเดียว หากตัวชี้การสลายตัวเป็นอาร์กิวเมนต์ที่ได้รับจากฟังก์ชั่นดังนั้นขนาดของอาร์เรย์เริ่มต้นจะต้องมีการจัดเตรียมด้วยวิธีอื่นเพื่อให้ฟังก์ชั่นรู้ขนาดนั้น

ต่อไปนี้เป็นข้อเสนอแนะที่แตกต่างจากที่ให้ไว้จนถึงตอนนี้ซึ่งจะใช้งานได้: ส่งตัวชี้ไปยังอาร์เรย์แทน คำแนะนำนี้คล้ายกับคำแนะนำในสไตล์ C ++ ยกเว้นว่า C ไม่รองรับเทมเพลตหรือการอ้างอิง:

#define ARRAY_SZ 10

void foo (int (*arr)[ARRAY_SZ]) {
    printf("%u\n", (unsigned)sizeof(*arr)/sizeof(**arr));
}

แต่ข้อเสนอแนะนี้เป็นสิ่งที่โง่สำหรับปัญหาของคุณเนื่องจากฟังก์ชั่นถูกกำหนดให้รู้ขนาดของอาเรย์ที่ถูกส่งผ่าน (ดังนั้นจึงไม่จำเป็นต้องใช้ขนาดของอาเรย์ทั้งหมดในอาเรย์) แต่มันทำอะไรได้บ้างคือให้ความปลอดภัยบางประเภท มันจะห้ามไม่ให้คุณผ่านขนาดที่ไม่ต้องการ

int x[20];
int y[10];
foo(&x); /* error */
foo(&y); /* ok */

หากฟังก์ชั่นนี้ควรจะสามารถทำงานกับขนาดของอาเรย์ใด ๆ คุณจะต้องระบุขนาดให้กับฟังก์ชั่นเป็นข้อมูลเพิ่มเติม


1
+1 สำหรับ "คุณไม่สามารถรับข้อมูลนี้จากค่าตัวชี้ที่ลดลงของอาร์เรย์เพียงอย่างเดียว" และระบุวิธีแก้ปัญหา
สูงสุด

4

ไม่มีการแก้ปัญหาเวทย์มนตร์ C ไม่ใช่ภาษาที่สะท้อนแสง วัตถุไม่ทราบว่ามันคืออะไรโดยอัตโนมัติ

แต่คุณมีทางเลือกมากมาย:

  1. เห็นได้ชัดว่าเพิ่มพารามิเตอร์
  2. ล้อมสายในแมโครและเพิ่มพารามิเตอร์โดยอัตโนมัติ
  3. ใช้วัตถุที่ซับซ้อนมากขึ้น กำหนดโครงสร้างที่มีอาร์เรย์แบบไดนามิกและขนาดของอาร์เรย์ จากนั้นผ่านที่อยู่ของโครงสร้าง

วัตถุรู้ว่าพวกเขาคืออะไร แต่ถ้าคุณชี้ไปที่ subobject ไม่มีวิธีรับข้อมูลเกี่ยวกับวัตถุที่สมบูรณ์หรือ subobject ที่มีขนาดใหญ่ขึ้น
MM

2

วิธีแก้ไขปัญหานี้ของฉันคือการบันทึกความยาวของอาเรย์ลงในโครงสร้างอาเรย์เป็นข้อมูลเมตาเกี่ยวกับอาเรย์

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

struct Array
{
    int length;

    double *array;
};

typedef struct Array Array;

Array* NewArray(int length)
{
    /* Allocate the memory for the struct Array */
    Array *newArray = (Array*) malloc(sizeof(Array));

    /* Insert only non-negative length's*/
    newArray->length = (length > 0) ? length : 0;

    newArray->array = (double*) malloc(length*sizeof(double));

    return newArray;
}

void SetArray(Array *structure,int length,double* array)
{
    structure->length = length;
    structure->array = array;
}

void PrintArray(Array *structure)
{       
    if(structure->length > 0)
    {
        int i;
        printf("length: %d\n", structure->length);
        for (i = 0; i < structure->length; i++)
            printf("%g\n", structure->array[i]);
    }
    else
        printf("Empty Array. Length 0\n");
}

int main()
{
    int i;
    Array *negativeTest, *days = NewArray(5);

    double moreDays[] = {1,2,3,4,5,6,7,8,9,10};

    for (i = 0; i < days->length; i++)
        days->array[i] = i+1;

    PrintArray(days);

    SetArray(days,10,moreDays);

    PrintArray(days);

    negativeTest = NewArray(-5);

    PrintArray(negativeTest);

    return 0;
}

แต่คุณต้องระวังเกี่ยวกับการตั้งค่าความยาวที่เหมาะสมของอาเรย์ที่คุณต้องการจัดเก็บเพราะไม่มีวิธีการตรวจสอบความยาวนี้เหมือนที่เพื่อนของเราอธิบายไว้อย่างหนาแน่น



1

ไม่คุณไม่สามารถใช้sizeof(ptr)หาขนาดของอาเรย์ที่ptrชี้ไปได้

แม้ว่าการจัดสรรหน่วยความจำเพิ่มเติม (มากกว่าขนาดของอาร์เรย์) จะเป็นประโยชน์หากคุณต้องการเก็บความยาวในพื้นที่พิเศษ


1
int main() 
{
    int days[] = {1,2,3,4,5};
    int *ptr = days;
    printf("%u\n", sizeof(days));
    printf("%u\n", sizeof(ptr));

    return 0;
}

ขนาดของวัน [] คือ 20 ซึ่งไม่มีองค์ประกอบ * ขนาดของชนิดข้อมูล ในขณะที่ขนาดของตัวชี้คือ 4 ไม่ว่าจะชี้ไปที่ใด เพราะตัวชี้ชี้ไปที่องค์ประกอบอื่นโดยการจัดเก็บที่อยู่


1
sizeof (ptr) คือขนาดของตัวชี้และ sizeof (* ptr) คือขนาดของตัวชี้ที่
Amitābha

0
 #define array_size 10

 struct {
     int16 size;
     int16 array[array_size];
     int16 property1[(array_size/16)+1]
     int16 property2[(array_size/16)+1]
 } array1 = {array_size, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

 #undef array_size

array_size ส่งผ่านไปยังตัวแปรขนาด :

#define array_size 30

struct {
    int16 size;
    int16 array[array_size];
    int16 property1[(array_size/16)+1]
    int16 property2[(array_size/16)+1]
} array2 = {array_size};

#undef array_size

การใช้งานคือ:

void main() {

    int16 size = array1.size;
    for (int i=0; i!=size; i++) {

        array1.array[i] *= 2;
    }
}

0

ในสายมีความเป็นตัวละครในตอนท้ายเพื่อให้ความยาวของสตริงที่สามารถอากาศโดยใช้ฟังก์ชั่นเช่น'\0' strlenยกตัวอย่างเช่นปัญหาเกี่ยวกับอาร์เรย์จำนวนเต็มคือคุณไม่สามารถใช้ค่าใด ๆ เป็นค่าสิ้นสุดดังนั้นวิธีแก้ปัญหาหนึ่งที่เป็นไปได้คือการกำหนดอาร์เรย์และใช้เป็นค่าสิ้นสุดของNULLตัวชี้

#include <stdio.h>
/* the following function will produce the warning:
 * ‘sizeof’ on array function parameter ‘a’ will
 * return size of ‘int *’ [-Wsizeof-array-argument]
 */
void foo( int a[] )
{
    printf( "%lu\n", sizeof a );
}
/* so we have to implement something else one possible
 * idea is to use the NULL pointer as a control value
 * the same way '\0' is used in strings but this way
 * the pointer passed to a function should address pointers
 * so the actual implementation of an array type will
 * be a pointer to pointer
 */
typedef char * type_t; /* line 18 */
typedef type_t ** array_t;
int main( void )
{
    array_t initialize( int, ... );
    /* initialize an array with four values "foo", "bar", "baz", "foobar"
     * if one wants to use integers rather than strings than in the typedef
     * declaration at line 18 the char * type should be changed with int
     * and in the format used for printing the array values 
     * at line 45 and 51 "%s" should be changed with "%i"
     */
    array_t array = initialize( 4, "foo", "bar", "baz", "foobar" );

    int size( array_t );
    /* print array size */
    printf( "size %i:\n", size( array ));

    void aprint( char *, array_t );
    /* print array values */
    aprint( "%s\n", array ); /* line 45 */

    type_t getval( array_t, int );
    /* print an indexed value */
    int i = 2;
    type_t val = getval( array, i );
    printf( "%i: %s\n", i, val ); /* line 51 */

    void delete( array_t );
    /* free some space */
    delete( array );

    return 0;
}
/* the output of the program should be:
 * size 4:
 * foo
 * bar
 * baz
 * foobar
 * 2: baz
 */
#include <stdarg.h>
#include <stdlib.h>
array_t initialize( int n, ... )
{
    /* here we store the array values */
    type_t *v = (type_t *) malloc( sizeof( type_t ) * n );
    va_list ap;
    va_start( ap, n );
    int j;
    for ( j = 0; j < n; j++ )
        v[j] = va_arg( ap, type_t );
    va_end( ap );
    /* the actual array will hold the addresses of those
     * values plus a NULL pointer
     */
    array_t a = (array_t) malloc( sizeof( type_t *) * ( n + 1 ));
    a[n] = NULL;
    for ( j = 0; j < n; j++ )
        a[j] = v + j;
    return a;
}
int size( array_t a )
{
    int n = 0;
    while ( *a++ != NULL )
        n++;
    return n;
}
void aprint( char *fmt, array_t a )
{
    while ( *a != NULL )
        printf( fmt, **a++ );   
}
type_t getval( array_t a, int i )
{
    return *a[i];
}
void delete( array_t a )
{
    free( *a );
    free( a );
}

รหัสของคุณเต็มไปด้วยความคิดเห็น แต่ฉันคิดว่ามันจะทำให้ทุกอย่างง่ายขึ้นถ้าคุณได้เพิ่มคำอธิบายทั่วไปเกี่ยวกับวิธีการทำงานนอกรหัสเช่นข้อความปกติ คุณกรุณาแก้ไขคำถามของคุณและทำมันได้หรือไม่ ขอบคุณ!
ฟาบิโอพูดว่า Reinstate Monica

การสร้างอาเรย์ของพอยน์เตอร์ให้แต่ละองค์ประกอบเพื่อให้คุณสามารถค้นหาแบบเชิงเส้นสำหรับมันNULLน่าจะเป็นทางเลือกที่มีประสิทธิภาพน้อยที่สุดเท่าที่จะเป็นไปได้เพียงแค่จัดเก็บแยกต่างหากsizeโดยตรง โดยเฉพาะอย่างยิ่งถ้าคุณใช้เลเยอร์ทางอ้อมพิเศษนี้ตลอดเวลา
ปีเตอร์กอร์เดส
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.