අරාවෙහි සියලුම සාමාජිකයන් එකම අගයකට ආරම්භ කරන්නේ කෙසේද?


985

මට C හි විශාල අරාවක් ඇත ( එය වෙනසක් කරන්නේ නම් C ++ නොවේ ). එකම වටිනාකමක් ඇති සියලුම සාමාජිකයින් ආරම්භ කිරීමට මට අවශ්‍යය.

මට දිවුරන්න පුළුවන් මම වරක් මෙය කිරීමට සරල ක්‍රමයක් දැන සිටි බව. memset()මගේ නඩුවේදී මට භාවිතා කළ හැකිය , නමුත් සී සින්ටැක්ස් තුළම ගොඩනගා ඇති මෙය කිරීමට ක්‍රමයක් නැද්ද?


17
C99 සහ ඊට ඉහළින් කළ හැකි නම් කරන ලද ආරම්භක අංකනය මෙතෙක් කිසිදු පිළිතුරක සඳහන් නොවේ. උදාහරණයක් ලෙස: enum { HYDROGEN = 1, HELIUM = 2, CARBON = 6, NEON = 10, … };සහ struct element { char name[15]; char symbol[3]; } elements[] = { [NEON] = { "Neon", "Ne" }, [HELIUM] = { "Helium", "He" }, [HYDROGEN] = { "Hydrogen", "H" }, [CARBON] = { "Carbon", "C" }, … };. ඔබ ඉලිප්සිස් ඉවත් කළහොත් , එම කොටස් C99 හෝ C11 යටතේ සම්පාදනය වේ.
ජොනතන් ලෙෆ්ලර්

ඇත්ත වශයෙන්ම අබලෙන්කිගේ පිළිතුර නම් කරන ලද ආරම්භක භාවිතා කිරීමයි, නමුත් එය සම්පුර්ණයෙන්ම ආරම්භක කේතය නොවේ
Rob11311

memset () උදව් කළ හැකි නමුත් වටිනාකම මත රඳා පවතී.
නික්

2
memset()නිශ්චිත සාකච්ඡාව: stackoverflow.com/questions/7202411/… මම හිතන්නේ එය ක්‍රියාත්මක වන්නේ 0 සඳහා පමණි.
සීරෝ සැන්ටිලි 郝海东 冠状 病 六四 法轮功 事件

Answers:


1261

එම අගය 0 නොවේ නම් (ඔබට ආරම්භකයේ යම් කොටසක් අතහැර දැමිය හැකි අතර අනුරූප මූලද්‍රව්‍ය 0 දක්වා ආරම්භ වේ), පහසු ක්‍රමයක් නොමැත.

නමුත් පැහැදිලි විසඳුම නොසලකා හරින්න.

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 };

නැතිවූ අගයන් සහිත මූලද්‍රව්‍ය 0 ට ආරම්භ කෙරේ:

int myArray[10] = { 1, 2 }; // initialize to 1,2,0,0,0...

එබැවින් මෙය සියලුම අංග 0 ට ආරම්භ කරයි:

int myArray[10] = { 0 }; // all elements 0

C ++ හි, හිස් ආරම්භක ලැයිස්තුවක් මඟින් සෑම අංගයක්ම 0 දක්වා ආරම්භ කරනු ඇත. මෙය C සමඟ අවසර නැත :

int myArray[10] = {}; // all elements 0 in C++

ආරම්භකය නිශ්චිතව දක්වා නොමැති නම් ස්ථිතික ගබඩා කාල සීමාවක් ඇති වස්තු 0 දක්වා ආරම්භ වන බව මතක තබා ගන්න:

static int myArray[10]; // all elements 0

“0” යන්නෙහි අර්ථය “සියලු බිටු-ශුන්‍යය” යන්න නොවේ, එබැවින් ඉහත භාවිතා කිරීම මෙම්සෙට් () ට වඩා හොඳ සහ අතේ ගෙන යා හැකි ය. (පාවෙන ලක්ෂ්‍ය අගයන් +0 ට ද, දර්ශක ශුන්‍ය අගයට ද ආරම්භ කෙරේ.)


28
C ++ ප්‍රමිතිය හරහා කියවීමෙන් ඔබට int array ද කළ හැකිය [10] = {}; ආරම්භක ශුන්‍යයට. මෙය වලංගු C ද යන්න පරීක්ෂා කිරීමට මට C ප්‍රමිතියක් නොමැත.
workmad3

54
6.7.8 වගන්තිය දෙස බලන විට C99 ප්‍රමිතිය ආරම්භ කිරීමේදී හිස් ආරම්භක ලැයිස්තුවකට ඉඩ දී ඇති බවක් නොපෙනේ.
ජොනතන් ලෙෆ්ලර්

8
C99 ව්‍යුහය සහ අරාව ආරම්භ කිරීම සඳහා හොඳ ලක්ෂණ රාශියක් ඇත; එහි නොමැති එක් අංගයක් (නමුත් ෆෝට්රාන් IV, 1966, තිබුනේ) අරාව සඳහා නිශ්චිත ආරම්භකය පුනරාවර්තනය කිරීමේ ක්‍රමයකි.
ජොනතන් ලෙෆ්ලර්

9
EtCetinSert: ඔබ අදහස් කරන්නේ එය ක්‍රියාත්මක නොවන බවයි? එය කළ යුත්තේ මෙම පිළිතුර පවසන දේමයි. ඔබගේ කේතයේ අදහස් දැක්වීම එය නොකරයි, නමුත් එම ප්‍රකාශය වැරදිය.
බෙන්ජමින් ලින්ඩ්ලි

10
EtCetinSert: එම ප්‍රකාශයේ දී සියලුම මූලද්‍රව්‍ය -1 ලෙස සකසනු ඇතැයි කියා සිටියේ ඔබ පමණි. මෙම පිළිතුර කියා සිටින්නේ, නිශ්චිතව දක්වා නැති සියලුම අංග ශුන්‍යයට සකසා ඇති බවයි. ඔබගේ කේතයේ ප්‍රති results ල මෙම හිමිකම් පෑමට අනුකූල වේ.
බෙන්ජමින් ලින්ඩ්ලි

400

ඔබේ සම්පාදකයා ජීසීසී නම් ඔබට පහත සින්ටැක්ස් භාවිතා කළ හැකිය:

int array[1024] = {[0 ... 1023] = 5};

සවිස්තරාත්මක විස්තරය බලන්න: http://gcc.gnu.org/onlineocs/gcc-4.1.2/gcc/Designated-Inits.html


12
එම සින්ටැක්ස් මඟින් සම්පාදනය කරන ලද ද්විමයන්හි ගොනු ප්‍රමාණය විශාල ලෙස වැඩි කරයි. N = 65536 සඳහා (1024 වෙනුවට), මගේ ද්විමය ප්‍රමාණය 15 KB සිට 270 KB දක්වා ඉහළ යයි !!
සෙටින් සර්ට්

51
EtCetinSert Compiler විසින් intස්ථිතික දත්ත වලට 65536 s එකතු කළ යුතු අතර එය 256 K වේ - ඔබ නිරීක්ෂණය කළ ප්‍රමාණය වැඩි වීම.
qrdl

15
EtCetinSert මා කළ යුත්තේ ඇයි? එය සම්මත සම්පාදක හැසිරීමකි, නම් කරන ලද ආරම්භකයින් සඳහා විශේෂිත නොවේ. ඔබ සංඛ්‍යාත්මකව 65536 ints ආරම්භ කළහොත්, ඔබට int foo1 = 1, foo2 = 1, ..., foo65536 =1;සමාන ප්‍රමාණයේ වැඩිවීමක් ලැබෙනු ඇත.
qrdl

28
වඩා හොඳ තවමත්: "int array [] = {[0 ... 1023] = 5}", අරාවේ ප්‍රමාණය ස්වයංක්‍රීයව 1024 ලෙස සකසනු ඇත, වෙනස් කිරීමට පහසු සහ ආරක්ෂිත වේ.
ෆ්‍රැන්කොයිස්

4
Ran ෆ්‍රැන්කොයිස් හෝ 2 ඩී අරා සඳහා, bool array[][COLS] = { [0...ROWS-1][0...COLS-1] = true}සම්පූර්ණ ආකෘතියට වඩා කියවිය හැකි බව මට විශ්වාස නැත.
g33kz0r

182

බහු පිටපත්-පේස්ට් නොමැතිව එකම අගයක් සහිත විශාල අරාවක් ස්ථිතිකව ආරම්භ කිරීම සඳහා, ඔබට මැක්‍රෝස් භාවිතා කළ හැකිය:

#define VAL_1X     42
#define VAL_2X     VAL_1X,  VAL_1X
#define VAL_4X     VAL_2X,  VAL_2X
#define VAL_8X     VAL_4X,  VAL_4X
#define VAL_16X    VAL_8X,  VAL_8X
#define VAL_32X    VAL_16X, VAL_16X
#define VAL_64X    VAL_32X, VAL_32X

int myArray[53] = { VAL_32X, VAL_16X, VAL_4X, VAL_1X };

ඔබට අගය වෙනස් කිරීමට අවශ්‍ය නම්, ප්‍රතිස්ථාපනය කළ යුත්තේ එක් ස්ථානයක පමණි.

සංස්කරණය කරන්න: හැකි ප්‍රයෝජනවත් දිගු

(අනුග්‍රහය ජොනතන් ලෙෆ්ලර් )

ඔබට මෙය පහසුවෙන් සාමාන්‍යකරණය කළ හැකිය:

#define VAL_1(X) X
#define VAL_2(X) VAL_1(X), VAL_1(X)
/* etc. */

මෙය භාවිතයෙන් ප්‍රභේදයක් නිර්මාණය කළ හැකිය:

#define STRUCTVAL_1(...) { __VA_ARGS__ }
#define STRUCTVAL_2(...) STRUCTVAL_1(__VA_ARGS__), STRUCTVAL_1(__VA_ARGS__)
/*etc */ 

එය ව්‍යුහයන් හෝ සංයුක්ත අරා සමඟ ක්‍රියා කරයි.

#define STRUCTVAL_48(...) STRUCTVAL_32(__VA_ARGS__), STRUCTVAL_16(__VA_ARGS__)

struct Pair { char key[16]; char val[32]; };
struct Pair p_data[] = { STRUCTVAL_48("Key", "Value") };
int a_data[][4] = { STRUCTVAL_48(12, 19, 23, 37) };

සාර්ව නම් හුවමාරු කර ගත හැකිය.


13
මම මෙය සලකා බලන්නේ ආන්තික අවස්ථාවන්හිදී පමණි, නිසැකවම එය ප්‍රකාශ කිරීමට වඩා අලංකාර ක්‍රමයක් වන්නේ මෙම්සෙට් එකක්.
u0b34a0f6ae

48
දත්ත ROM වලට හැකියාව තිබිය යුතු නම්, memset භාවිතා කළ නොහැක.
මහාචාර්ය ෆැල්කන්

9
Preprocessor ඇත්ත වශයෙන්ම # අර්ථ දැක්වීම් වලින් කේතය ජනනය කරනු ඇත. විශාල අරා මානයන් සමඟ ක්‍රියාත්මක කළ හැකි ප්‍රමාණය වර්ධනය වේ. නමුත් නියත වශයෙන්ම + අදහස සඳහා;)
ලියොනිඩ්

7
L ඇල්කොට්, පැරණි පරිගණකවල සහ තවමත් කාවැද්දූ බොහෝ පද්ධතිවල කේතය අවසානයේ EPROM හෝ ROM තුළ තැන්පත් කර ඇත . ROM- හැකියාව යනු කාවැද්දූ පද්ධතිවල “ෆ්ලෑෂ් කේතය” යන්නෙහි අර්ථය වී ඇත්තේ එයට සමාන ඇඟවුම් ඇති නිසාය, එනම් මතකය ධාවන වේලාවට ලිවිය නොහැකි බවය. මතකය යාවත්කාලීන කිරීමට හෝ වෙනස් කිරීමට වෙනත් උපදෙස් භාවිතා කළ නොහැක. වැඩසටහන ආරම්භ වීමට පෙර නියතයන් ප්‍රකාශ කළ හැකි අතර ෆ්ලෑෂ් හෝ ROM-ed කළ හැකිය.
මහාචාර්ය ෆැල්කන්

4
@ u0b34a0f6ae: VAL_1Xතනි සංඛ්‍යාවක් නොව ලැයිස්තුවක් නම් ඔබට මෙම ක්‍රමය භාවිතා කළ හැකි බව මතක තබා ගන්න . Amigable ජනපද මෙන්, EEPROM හෝ Flash මතකයේ ආරම්භක අගයන් අර්ථ දැක්වීමට ඔබට අවශ්‍ය කාවැද්දූ පද්ධති සඳහා යා යුතු මාර්ගය මෙයයි. අවස්ථා දෙකේදීම ඔබට භාවිතා කළ නොහැක memset().
මාටින් ෂාරර්

64

අරාවෙහි සෑම සාමාජිකයෙකුම පැහැදිලිවම ආරම්භ කර ඇති බව සහතික කිරීමට ඔබට අවශ්‍ය නම්, ප්‍රකාශයේ මානය අතහරින්න:

int myArray[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };

සම්පාදකයා ආරම්භක ලැයිස්තුවෙන් මානය අඩු කරයි. අවාසනාවකට මෙන්, බහුමානීය අරා සඳහා පිටත මානය පමණක් ඉවත් කළ හැකිය:

int myPoints[][3] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

හරි, නමුත්

int myPoints[][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };

නැත.


මේක හරිද ? int myPoints[10][] = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9} };
ප්‍රවීන් ගවුඩා IV

10
නැත. ඔබ ඉඩ නොදෙන අභ්‍යන්තර මානය මඟ හැරේ. මෙය සම්පාදක දෝෂයක් ලබා දෙනු ඇත.
ෆ්‍රෑන්ක් ස්ක්සර්බා

4
ආරම්භක සහ දිග අනුමාන කිරීම් දෙකම C99 හි හඳුන්වා දෙන ලදී.
පලෙක්

3
Ale පැලේක්: පූර්ව සම්මත සී කාලයේ සිට සී හි නැත - කේ ඇන්ඩ් ආර් 1 වන සංස්කරණය ප්‍රකාශයට පත් වූ දා සිට, ඊට ටික කලකට පෙර). C99 හි නම් කරන ලද ආරම්භකයින් නව ඒවා විය, නමුත් මෙය නම් කරන ලද ආරම්භක භාවිතා නොකරයි.
ජොනතන් ලෙෆ්ලර්

54

මෙම සින්ටැක්ස් භාවිතා කරන කේත කිහිපයක් මම දුටුවෙමි:

char* array[] = 
{
    [0] = "Hello",
    [1] = "World"
};   

එය විශේෂයෙන් ප්‍රයෝජනවත් වන්නේ කොතැනද යන්න නම්, ඔබ දර්ශකය ලෙස enums භාවිතා කරන අරාවක් සාදන්නේ නම්:

enum
{
    ERR_OK,
    ERR_FAIL,
    ERR_MEMORY
};

#define _ITEM(x) [x] = #x

char* array[] = 
{
    _ITEM(ERR_OK),
    _ITEM(ERR_FAIL),
    _ITEM(ERR_MEMORY)
};   

ඔබ සමහර එන්-අගයන් පිළිවෙලට ලිවීමට සිදුවුවද, මෙය දේවල් පිළිවෙලට තබා ගනී.

මෙම තාක්ෂණය පිළිබඳ වැඩි විස්තර මෙතැනින් සහ මෙතැනින් සොයාගත හැකිය .


9
මෙය C99 ආරම්භක සින්ටැක්ස් වේ, දැනටමත් වෙනත් පිළිතුරු වලින් ආවරණය වී ඇත. ඔබ විමසිය බවට ප්රකාශ කළ හැකි char const *array[] = { ... };හෝ char const * const array[] = { ... };, ඔබ නැහැ කියලා කියන්නේ කොහොමද?
ජොනතන් ලෙෆ්ලර්

22
int i;
for (i = 0; i < ARRAY_SIZE; ++i)
{
  myArray[i] = VALUE;
}

මම හිතන්නේ මේකට වඩා හොඳයි

int myArray[10] = { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5...

අරාවෙහි විශාලත්වය වෙනස් කරන්න.


12
වාර්තාව සඳහා, එය මූලික වශයෙන් මන්දගාමී, වඩා වාචික අනුවාදයකිmemset(myArray, VALUE, ARRAY_SIZE);
බෙන්සන්

18
255 ට වඩා විශාල අගයකට int අරාව ආරම්භ කිරීමට ඔබ memset භාවිතා කරන්නේ කෙසේද? memset ක්‍රියාත්මක වන්නේ අරාව බයිට් ප්‍රමාණයේ නම් පමණි.
මැට්

21
En බෙන්සන්: ඔබට ඉහත කේතය ප්‍රමාණයේ (int)> sizeof (char) වේදිකාවල memset සමඟ ආදේශ කළ නොහැක. උත්සහ කරන්න.
ක්‍රිස්වු

12

ඉහත විස්තර කර ඇති පරිදි ඔබට සම්පූර්ණ ස්ථිතික ආරම්භක දේ කළ හැකිය, නමුත් ඔබේ අරාවෙහි ප්‍රමාණය වෙනස් වන විට එය සැබෑ බමරයක් විය හැකිය (ඔබේ අරාව එම්බිජෙන් කරන විට, ඔබ සුදුසු අතිරේක ආරම්භක එකතු නොකරන්නේ නම් ඔබට කුණු ලැබේ).

memset මඟින් ඔබට වැඩ කිරීම සඳහා ධාවන කාල පහරක් ලබා දෙයි, නමුත් නිවැරදිව සිදු කරන ලද කේත ප්‍රමාණයේ කිසිදු පහරක් අරාව ප්‍රමාණයේ වෙනස්වීම් වලින් නිදහස් නොවේ. අරාව මූලද්‍රව්‍ය දුසිම් කිහිපයකට වඩා විශාල වූ විට මම සෑම අවස්ථාවකම පාහේ මෙම විසඳුම භාවිතා කරමි.

අරාව ස්ථිතිකව ප්‍රකාශයට පත් කිරීම ඇත්තෙන්ම වැදගත් නම්, මා වෙනුවෙන් වැඩසටහන ලිවීමට හා එය ගොඩ නැගීමේ ක්‍රියාවලියේ කොටසක් බවට පත් කිරීමට මම වැඩසටහනක් ලියමි.


memsetඅරාව ආරම්භ කිරීම සඳහා කරුණාකර එම උදාහරණයට උදාහරණයක් එකතු කළ හැකිද ?
සොපාලජෝ ඩි ඇරියරෙස්

8

මෙන්න තවත් ක්‍රමයක්:

static void
unhandled_interrupt(struct trap_frame *frame, int irq, void *arg)
{
    //this code intentionally left blank
}

static struct irqtbl_s vector_tbl[XCHAL_NUM_INTERRUPTS] = {
    [0 ... XCHAL_NUM_INTERRUPTS-1] {unhandled_interrupt, NULL},
};

බලන්න:

සී දිගු

නම් කරන ලද inits

ඉන්පසු ප්‍රශ්නය අසන්න: කෙනෙකුට සී දිගු භාවිතා කළ හැක්කේ කවදාද?

ඉහත කේත නියැදිය කාවැද්දූ පද්ධතියක ඇති අතර වෙනත් සම්පාදකයෙකුගේ ආලෝකය කිසි විටෙකත් නොපෙනේ.


6

'සාමාන්‍ය' දත්ත වර්ග ආරම්භ කිරීම සඳහා (int අරා වැනි), ඔබට වරහන් අංකනය භාවිතා කළ හැකිය, නමුත් අරාවෙහි තවමත් ඉඩ තිබේ නම් එය අවසාන අගයෙන් පසු ශුන්‍ය වනු ඇත:

// put values 1-8, then two zeroes
int list[10] = {1,2,3,4,5,6,7,8};

5

අරාව int හෝ විශාලත්වයකින් යුක්ත නම් හෝ ඔබේ මතක රටාවේ ප්‍රමාණය හරියටම වේලාවට int ට ගැලපේ නම් (එනම් සියලුම ශුන්‍ය හෝ 0xA5A5A5A5), හොඳම ක්‍රමය වන්නේ memset () .

එසේ නොමැතිනම් දර්ශකය චලනය වන ලූපයක memcpy () අමතන්න.


5

කම්මුලට මඳක් පිළිතුර; ප්රකාශය ලියන්න

array = initial_value

ඔබගේ ප්‍රියතම අරාව-හැකියාව ඇති භාෂාවෙන් (මගේ ෆෝට්රාන්, නමුත් තවත් බොහෝ දේ ඇත), එය ඔබේ සී කේතයට සම්බන්ධ කරන්න. ඔබට එය බාහිර ශ්‍රිතයක් ලෙස ඔතා ගැනීමට අවශ්‍ය වනු ඇත.


4

දී ඇති අගය සහිත ඕනෑම වර්ගයක අරාව ආරම්භ කිරීමට වේගවත් ක්‍රමයක් තිබේ. එය විශාල අරා සමඟ ඉතා හොඳින් ක්රියා කරයි. ඇල්ගොරිතම පහත පරිදි වේ:

  • අරාවේ පළමු අංගය ආරම්භ කරන්න (සුපුරුදු ක්‍රමය)
  • පිටපත් කරන ලද කොටස සකසා නොමැති කොටසකට සකසා ඇති අතර, එක් එක් ඊළඟ පිටපත් කිරීමේ ක්‍රියාවලිය සමඟ ප්‍රමාණය දෙගුණ කරයි

සඳහා 1 000 000අංග intරැසක් එය නිත්ය පුඩුවක් ආරම්භය (i5, 2 මධ්යය, 2.3 GHz, 4GiB මතකය, 64 බිට්) ට වඩා 4 ගුණයක් වේගවත් වේ:

loop runtime 0.004248 [seconds]

memfill() runtime 0.001085 [seconds]


#include <stdio.h>
#include <time.h>
#include <string.h>
#define ARR_SIZE 1000000

void memfill(void *dest, size_t destsize, size_t elemsize) {
   char   *nextdest = (char *) dest + elemsize;
   size_t movesize, donesize = elemsize;

   destsize -= elemsize;
   while (destsize) {
      movesize = (donesize < destsize) ? donesize : destsize;
      memcpy(nextdest, dest, movesize);
      nextdest += movesize; destsize -= movesize; donesize += movesize;
   }
}    
int main() {
    clock_t timeStart;
    double  runTime;
    int     i, a[ARR_SIZE];

    timeStart = clock();
    for (i = 0; i < ARR_SIZE; i++)
        a[i] = 9;    
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("loop runtime %f [seconds]\n",runTime);

    timeStart = clock();
    a[0] = 10;
    memfill(a, sizeof(a), sizeof(a[0]));
    runTime = (double)(clock() - timeStart) / (double)CLOCKS_PER_SEC;
    printf("memfill() runtime %f [seconds]\n",runTime);
    return 0;
}

2
කණගාටුයි, නමුත් මෙය සත්‍ය නොවේ. ඔබගේ පරීක්ෂණ අතරතුරදී සම්පාදක ප්‍රශස්තිකරණය සක්‍රිය කිරීමට ඔබට අමතක වී ඇත (නිදොස් කිරීමේ මාදිලිය සමඟ පරීක්ෂා කර තිබේද?). මම මෙය පරික්ෂා කළහොත්, ලූපය සෑම විටම පාහේ මෙම්ෆිල් වලට වඩා 50% වේගවත් වේ (මගේ පරිගණකයේ ඇති සමහර බර පැටවුම් නිසා 'සැමවිටම'). සහ මෙම්සෙට් භාවිතා කිරීම (a, 0, sizeof (a)); ලූප්ෆිල් වලට වඩා දෙගුණයක් වේගවත් වේ.
RS1980

3
ඕනෑම මිණුම් සලකුණු කේතයක් මෙන්, ඔබ අතිශයින්ම පරෙස්සම් විය යුතුය. කාල කේතය 10 වතාවක් ක්‍රියාත්මක කිරීම සඳහා ලූපයක් එක් කිරීම (සහ අරාවේ ප්‍රමාණය 20M දක්වා දෙගුණ කිරීම) පෙන්වයි - මට නම්, MacOS සියෙරා 10.12.3 සමඟ මැක්බුක් ප්‍රෝ එකක් මත ධාවනය වන අතර GCC 6.3.0 භාවිතා කරයි - පළමු වරට, භාවිතා කිරීම ලූපය 4600 abouts පමණ වන අතර memfill()කේතය 1200 abouts පමණ වේ. කෙසේ වෙතත්, පසුකාලීන පුනරාවර්තන වලදී, ලූපය 900-1000 abouts පමණ වන අතර memfill()කේතය 1000-1300 takess ගනී. හැඹිලිය පිරවීම සඳහා පළමු පුනරාවර්තනය බොහෝ විට බලපායි. පරීක්ෂණ ආපසු හරවන්න සහ memfill()පළමු වරට මන්දගාමී වේ.
ජොනතන් ලෙෆ්ලර්

2

ආරම්භක අරාවෙහි මූලද්‍රව්‍යයන්ට ප්‍රවේශ වීම සඳහා දර්ශක අනුපිළිවෙල කිසිවෙකු සඳහන් කර නැත. මගේ උදාහරණ කේතය එයට නිදර්ශන උදාහරණයක් ලබා දෙනු ඇත.

#include <iostream>

void PrintArray(int a[3][3])
{
    std::cout << "a11 = " << a[0][0] << "\t\t" << "a12 = " << a[0][1] << "\t\t" << "a13 = " << a[0][2] << std::endl;
    std::cout << "a21 = " << a[1][0] << "\t\t" << "a22 = " << a[1][1] << "\t\t" << "a23 = " << a[1][2] << std::endl;
    std::cout << "a31 = " << a[2][0] << "\t\t" << "a32 = " << a[2][1] << "\t\t" << "a33 = " << a[2][2] << std::endl;
    std::cout << std::endl;
}

int wmain(int argc, wchar_t * argv[])
{
    int a1[3][3] =  {   11,     12,     13,     // The most
                        21,     22,     23,     // basic
                        31,     32,     33  };  // format.

    int a2[][3] =   {   11,     12,     13,     // The first (outer) dimension
                        21,     22,     23,     // may be omitted. The compiler
                        31,     32,     33  };  // will automatically deduce it.

    int a3[3][3] =  {   {11,    12,     13},    // The elements of each
                        {21,    22,     23},    // second (inner) dimension
                        {31,    32,     33} };  // can be grouped together.

    int a4[][3] =   {   {11,    12,     13},    // Again, the first dimension
                        {21,    22,     23},    // can be omitted when the 
                        {31,    32,     33} };  // inner elements are grouped.

    PrintArray(a1);
    PrintArray(a2);
    PrintArray(a3);
    PrintArray(a4);

    // This part shows in which order the elements are stored in the memory.
    int * b = (int *) a1;   // The output is the same for the all four arrays.
    for (int i=0; i<9; i++)
    {
        std::cout << b[i] << '\t';
    }

    return 0;
}

ප්‍රතිදානය:

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

a11 = 11                a12 = 12                a13 = 13
a21 = 21                a22 = 22                a23 = 23
a31 = 31                a32 = 32                a33 = 33

11      12      13      21      22      23      31      32      33

4
<iostream>වලංගු නොවේ Cලෙස std::cout, std::cinආදිය අයත් වේ, std::namespaceසහ Cපහසුකම් සපයන්නේ නැත namespaces. ඒ වෙනුවට භාවිතා <stdio.h>කිරීමට උත්සාහ කරන්න printf(...).
ෆ්‍රැන්සිස් කූග්ලර්

1
  1. ඔබගේ අරාව ස්ථිතික ලෙස ප්‍රකාශයට පත් කර ඇත්නම් හෝ ගෝලීය නම්, අරාවෙහි ඇති සියලුම අංගවල පෙරනිමි පෙරනිමි අගය 0 ඇත.
  2. සමහර සම්පාදකයින් විසින් අරාවෙහි පෙරනිමිය 0 ලෙස නිදොස් කිරීමේ ප්‍රකාරයේදී සකසයි.
  3. පෙරනිමිය 0 ලෙස සැකසීම පහසුය: int array [10] = {0};
  4. කෙසේ වෙතත්, වෙනත් අගයන් සඳහා, ඔබට මෙම්සෙට් () හෝ ලූප් භාවිතා කර ඇත;

උදාහරණය: int array [10]; memset (අරාව, -1, 10 * ප්‍රමාණය (int));


1

සියලු කතාබහ කපා හරිමින්, කෙටි පිළිතුර නම්, ඔබ සම්පාදනය කරන වේලාවේදී ප්‍රශස්තිකරණය සක්‍රිය කළහොත් ඔබ මීට වඩා හොඳ දෙයක් නොකරනු ඇත:

int i,value=5,array[1000]; 
for(i=0;i<1000;i++) array[i]=value; 

ප්‍රසාද දීමනාව: කේතය ඇත්ත වශයෙන්ම පැහැදිලි ය :)


7
ආරම්භය සඳහා විශේෂයෙන් ඇසූ ප්‍රශ්නය. මෙය පැහැදිලිවම ආරම්භ කිරීම නොවේ, නමුත් ආරම්භ කිරීමෙන් පසුව පැවරීම . එය වහාම සිදු කළ හැකි නමුත් එය තවමත් ආරම්භ කර නොමැත.
ඇන්ඩි

බොහෝ වාර ගණනක් හැඳින්වෙන ශ්‍රිතයක් තුළ විශාල ස්ථිතික බැලීමේ වගුවක් සඳහා මුලුමනින්ම ප්‍රයෝජනවත් නොවේ.
මාටින් බොනර් මොනිකාට සහය දක්වයි

... මුල් ප්‍රශ්නයේ කොටසක් වන කාර්යයන් තුළ ස්ථිතික බැලීමේ වගු මතක තබා නොගන්න - එය සරලව තබා ගන්න. එයින් කියැවුණේ, “ප්‍රජාව බොහෝ විට එය ඇණ ගැසූ බවයි.
JWDN

1

මුල් ප්‍රශ්නයේ C ගැන නොව C ++ ගැන පැහැදිලිවම සඳහන් වන බව මම දනිමි, නමුත් ඔබ (මා වැනි) මෙහි පැමිණියේ C ++ අරා සඳහා විසඳුමක් සොයමින් නම්, මෙන්න ඉතා හොඳ උපක්‍රමයක්:

ඔබේ සම්පාදකයා ගුණයකින් යුත් ප්‍රකාශන සඳහා සහය දක්වන්නේ නම් , ඔබට අච්චු මැජික් භාවිතා කළ හැකි std::index_sequenceඅතර ඔබට අවශ්‍ය අගය සමඟ ආරම්භක ලැයිස්තුවක් ජනනය කළ හැකිය. ඔබට එය පවා කළ හැකි constexprඅතර ලොක්කා මෙන් දැනිය හැකිය:

#include <array>

/// [3]
/// This functions's only purpose is to ignore the index given as the second
/// template argument and to always produce the value passed in.
template<class T, size_t /*ignored*/>
constexpr T identity_func(const T& value) {
    return value;
}

/// [2]
/// At this point, we have a list of indices that we can unfold
/// into an initializer list using the `identity_func` above.
template<class T, size_t... Indices>
constexpr std::array<T, sizeof...(Indices)>
make_array_of_impl(const T& value, std::index_sequence<Indices...>) {
    return {identity_func<T, Indices>(value)...};
}

/// [1]
/// This is the user-facing function.
/// The template arguments are swapped compared to the order used
/// for std::array, this way we can let the compiler infer the type
/// from the given value but still define it explicitly if we want to.
template<size_t Size, class T>
constexpr std::array<T, Size> 
make_array_of(const T& value) {
    using Indices = std::make_index_sequence<Size>;
    return make_array_of_impl(value, Indices{});
}

// std::array<int, 4>{42, 42, 42, 42}
constexpr auto test_array = make_array_of<4/*, int*/>(42);
static_assert(test_array[0] == 42);
static_assert(test_array[1] == 42);
static_assert(test_array[2] == 42);
static_assert(test_array[3] == 42);
// static_assert(test_array[4] == 42); out of bounds

ඔබට වැඩ කරන කේතය දෙස බැලිය හැකිය (වැන්ඩ්බොක්ස් හි)


0
#include<stdio.h>
int main(){
int i,a[50];
for (i=0;i<50;i++){
    a[i]=5;// set value 5 to all the array index
}
for (i=0;i<50;i++)
printf("%d\n",a[i]);
   return 0;
}

එය සම්පූර්ණ අරාවෙහි ප්‍රමාණය දක්වා o / p 5 5 5 5 5 5 ...... ලබා දෙනු ඇත


0

පරිශීලකයා Tarskiමෙම ප්‍රශ්නයට සමාන ආකාරයකින් පිළිතුරු දුන් බව මම දනිමි , නමුත් මම තවත් විස්තර කිහිපයක් එකතු කළෙමි. C ++ භාවිතා කිරීමට මා වැඩි කැමැත්තක් දක්වන බැවින් මගේ C ට සමාව දෙන්න.


වේලාවට පෙර අරාවේ ප්‍රමාණය ඔබ දන්නේ නම් ...

#include <stdio.h>

typedef const unsigned int cUINT;
typedef unsigned int UINT;

cUINT size = 10;
cUINT initVal = 5;

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal );
void printArray( UINT* myArray ); 

int main() {        
    UINT myArray[size]; 
    /* Not initialized during declaration but can be
    initialized using a function for the appropriate TYPE*/
    arrayInitializer( myArray, size, initVal );

    printArray( myArray );

    return 0;
}

void arrayInitializer( UINT* myArray, cUINT size, cUINT initVal ) {
    for ( UINT n = 0; n < size; n++ ) {
        myArray[n] = initVal;
    }
}

void printArray( UINT* myArray ) {
    printf( "myArray = { " );
    for ( UINT n = 0; n < size; n++ ) {
        printf( "%u", myArray[n] );

        if ( n < size-1 )
            printf( ", " );
    }
    printf( " }\n" );
}

ඉහත අවවාද කිහිපයක් තිබේ; එකක් නම් UINT myArray[size];ප්‍රකාශය මත කෙලින්ම ආරම්භ නොකෙරේ, කෙසේ වෙතත් ඊළඟ කේත වාරණය හෝ ක්‍රියාකාරී ඇමතුම මඟින් අරාවෙහි සෑම අංගයක්ම ඔබට අවශ්‍ය අගයටම ආරම්භ කරයි. අනෙක් අවවාදය නම්, ඔබ සහාය දක්වන initializing functionඑක් එක් සඳහා typeඔබට ලිවිය යුතු අතර printArray()එම වර්ග සඳහා සහය දැක්වීම සඳහා ශ්‍රිතය වෙනස් කිරීමටද ඔබට සිදුවේ .


ඔබට මෙහි ඇති සබැඳි සම්පාදකයෙකු සමඟ මෙම කේතය උත්සාහ කළ හැකිය .


0

ප්‍රමාද කිරීම සඳහා (එනම් පන්ති සාමාජික ඉදිකිරීම්කරු ආරම්භ කිරීම) සලකා බලන්න:

int a[4];

unsigned int size = sizeof(a) / sizeof(a[0]);
for (unsigned int i = 0; i < size; i++)
  a[i] = 0;

-1

ප්‍රශ්නයේ කිසිදු අවශ්‍යතාවයක් මා දකින්නේ නැත, එබැවින් විසඳුම සාමාන්‍ය විය යුතුය: ආරම්භක සාමාජික අගයක් සහිත නිශ්චිතව දක්වා නොමැති ව්‍යුහමය අංග වලින් සාදන ලද නිශ්චිතව දක්වා නැති බහුමානීය අරාවක් ආරම්භ කිරීම:

#include <string.h> 

void array_init( void *start, size_t element_size, size_t elements, void *initval ){
  memcpy(        start,              initval, element_size              );
  memcpy( (char*)start+element_size, start,   element_size*(elements-1) );
}

// testing
#include <stdio.h> 

struct s {
  int a;
  char b;
} array[2][3], init;

int main(){
  init = (struct s){.a = 3, .b = 'x'};
  array_init( array, sizeof(array[0][0]), 2*3, &init );

  for( int i=0; i<2; i++ )
    for( int j=0; j<3; j++ )
      printf("array[%i][%i].a = %i .b = '%c'\n",i,j,array[i][j].a,array[i][j].b);
}

ප්‍රති ult ලය:

array[0][0].a = 3 .b = 'x'
array[0][1].a = 3 .b = 'x'
array[0][2].a = 3 .b = 'x'
array[1][0].a = 3 .b = 'x'
array[1][1].a = 3 .b = 'x'
array[1][2].a = 3 .b = 'x'

සංස්කරණය කරන්න: start+element_sizeවෙනස් කර ඇත(char*)start+element_size


1
මෙය විසඳුමක් ද නැද්ද යන්න ගැන මට සැක සහිත ය. sizeof(void)පවා වලංගු දැයි මට විශ්වාස නැත .
ක්‍රිස් ලුට්ස්

3
එය ක්‍රියා නොකරයි. පළමු දෙක පමණක් ආරම්භ කර ඇති අතර, ඉතිරි සියල්ල ආරම්භ කර නොමැත. මම මැක් ඕඑස් එක්ස් 10.4 හි ජීසීසී 4.0 භාවිතා කරමි.
ඩ්‍රීම්ලැක්ස්

දෙවනුවෙහි ප්‍රභව දත්ත memcpy()ගමනාන්ත අවකාශය සමඟ අතිච්ඡාදනය වන බැවින් මෙය නිර්වචනය නොකළ හැසිරීමක් ඉල්ලා සිටී. බොළඳ ලෙස ක්‍රියාත්මක කිරීමත් සමඟ memcpy(), එය ක්‍රියාත්මක විය හැකි නමුත් පද්ධතිය එය ක්‍රියාත්මක කිරීම අවශ්‍ය නොවේ.
ජොනතන් ලෙෆ්ලර්

-1

ආපසු දවසේ (මම එය හොඳ අදහසක් යැයි නොකියමි), අපි පළමු අංගය සකසා පසුව:

memcpy (&element [1], &element [0], sizeof (element)-sizeof (element [0]);

එය තව දුරටත් ක්‍රියා කරනු ඇතැයි විශ්වාස නැත (එය memcpy ක්‍රියාත්මක කිරීම මත රඳා පවතී) නමුත් එය ක්‍රියාත්මක වන්නේ ආරම්භක මූලද්‍රව්‍යය ඊළඟට නැවත නැවත පිටපත් කිරීමෙනි - ව්‍යුහයන්ගේ අරා සඳහා පවා ක්‍රියා කරයි.


එය විශ්වාසදායක ලෙස ක්‍රියා නොකරනු ඇත. IMHO, ස්ටෑන්ඩර්ඩ් විසින් memcpyඅතිච්ඡාදනයකදී මෙන් පහළ නමුත් ඉහළ හෝ පහළ පිටපත් ඇණවුම වැනි කාර්යයන් ලබා දී තිබිය යුතුය , නමුත් එය එසේ නොවේ.
සුපර් කැට්

මා පැවසූ පරිදි, එය අප කළ දෙයක් පමණක් විශ්වාසදායක ලෙස ක්‍රියා නොකරනු ඇත, නමුත් ඒ වන විට, අපි ලේඛනගත නොකළ අංගයන් මග හැරීමට වඩා කාර්යක්ෂමතාව කෙරෙහි වැඩි අවධානයක් යොමු කළෙමු. මතක ඉදිරියට පිටපත් කිරීම වඩා කාර්යක්ෂම වන අතර, එය අහඹු ලෙස අනුපිළිවෙලින් හෝ පිටුපසට පිටපත් කළ නොහැකි යැයි පැවසීමට කිසිවක් නැත. memmove () ගැටුම් නොමැතිව පිටපත් කිරීමේ හැකියාව සපයයි.
මයික්

මෙය වෙනත් පිළිතුරක කේතයට සමාන වේ - සහ දෝෂ සහිතය. භාවිතා කිරීමෙන් memmove()එය ක්‍රියාත්මක නොවේ.
ජොනතන් ලෙෆ්ලර්

-2

ඔබ සමාන්තරව අදහස් කරන්නේ නම්, කොමා ක්‍රියාකරුට ප්‍රකාශනයක් සමඟ භාවිතා කරන විට එය කළ හැකි යැයි මම සිතමි.

a[1]=1, a[2]=2, ..., a[indexSize]; 

හෝ ඔබ අදහස් කරන්නේ තනි ඉදිකිරීමක් නම්, ඔබට එය ලූපයක් සඳහා කළ හැකිය:

for(int index = 0, value = 10; index < sizeof(array)/sizeof(array[0]); index++, value--)
  array[index] = index;

// තර්ක ලැයිස්තුවේ කොමා ක්‍රියාකරු ඉහත විස්තර කර ඇති සමාන්තර ක්‍රියාකරු නොවන බව සලකන්න.

ඔබට අරාව ප්‍රකාශ කිරීම ආරම්භ කළ හැකිය:

array[] = {1, 2, 3, 4, 5};

වස්තුවකට ස්ථාවර ගබඩා කලාපයක් වෙන් කිරීම සඳහා ඔබට malloc / calloc / sbrk / alloca / etc වෙත ඇමතුමක් ලබා ගත හැකිය:

int *array = malloc(sizeof(int)*numberOfListElements/Indexes);

සහ සාමාජිකයින්ට ප්‍රවේශ විය හැක්කේ:

*(array + index)

ආදිය.


කොමා ක්‍රියාකරු නාමික වශයෙන් වමේ සිට දකුණට ඇගයීම සහතික කරයි. ප්‍රකාශනවල අතුරු ආබාධ නොමැති නම්, මෙහෙයුම් සමාන්තරගත කිරීමට හැකි විය හැකි නමුත්, සම්පාදකයෙකු එසේ කිරීම අසාමාන්‍ය දෙයක් වනු ඇත.
ජොනතන් ලෙෆ්ලර්
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.