起初我在想,
“他们需要使用指针算法,所以
对象不会被自动取消引用
"[ ]" 运算符。
然后我意识到,不... C 中的数组没有
空槽。
我的结论是,提问者是:
使用结构数组。
像使用数组一样使用它
指向结构的指针。
peoro 的解决方案 很不错。但我建议稍微修改一下。
如果您想以懒惰/简单的方式进行操作,请将“.exists”属性添加到您的结构中。
简单并不是一件坏事,机器中的零件越多,可能出错的事情就越多。
下面的代码演示了两件事:
使用 .exists 标志修改的 peoro 解决方案伪造一个稀疏数组。
使用双指针的实际稀疏数组。
#include<stdlib.h> //:for: malloc(...)
#include<stdlib.h> //:for: free(...)
#include <stdio.h> //:for: printf(...)
int main( void ){
printf("[BEG:main]\n");
typedef struct MyStruct{
int whatever;
} MyStruct;
int num = 16; //:sixteen_elements
//:USE CALLOC HERE! If you use malloc you'll
//:end up with something even worse than
//:null pointers... Pointers that point to
//:random places in memory.
//:
//: It will make your:
//: if( arr[i] != NULL )...
//: look before you leap check worthless.
MyStruct** arr =(
calloc(
1 //:allocating 1 item: arr
//:Amount of memory taken up by
//:all 16 MyStruct pointers in array.
, sizeof(MyStruct*)*num
)
);;
//:Initialize only the EVEN slots:
for(int i = 0; i < num; i+=2 ){
//:Create new MyStruct in slot i,
//:initialized with junk data.
arr[i]= malloc(sizeof(MyStruct));
};;
//:If element not null, set it's whatever:
for(int i = 0; i < num; i++){
if(NULL != arr[i]){
arr[i] -> whatever = i;
};;
};;
//:Loop and print to confirm:
for(int i = 0; i < num; i++){
if(NULL != arr[i]){
printf("whatever: %d\n", arr[i] -> whatever);
};;
};;
//:ALTERNATIVELY:
//:If we were going to use peoro's method,
//:I would advise adding a ".exists" flag
//:to your struct.
typedef struct DoublePointersAreTooMuchWork{
int exists;
//:Because we are going to use malloc this
//:time, we have no guarantee what this
//:value will be. but you will probably
//:see all of them == 0. If you set
//: num=1000 you'll probably see a non-zero
//: entry somewhere. But, no guarantees!
int mystery_value;
} MyStruct02;
MyStruct02* arr2 = malloc(sizeof(MyStruct02)*num);
for(int i = 0; i < num; i++ ){
if( i%2 ){ //:evens
arr2[i].exists = 1;
}else{
arr2[i].exists = 0;
};;
};;
for(int i = 0; i < num; i++ ){
if( arr2[i].exists ){
printf("Exists:val:%d\n", arr2[i].mystery_value);
}else{
printf("[Pretend_I_Dont_Exist]\n");
};
}
printf("[END:main]\n");
} //[[main]____________________________________]//
/** ****************************************** ***
OUTPUT:
[BEG:main]
whatever: 0
whatever: 2
whatever: 4
whatever: 6
whatever: 8
whatever: 10
whatever: 12
whatever: 14
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[Pretend_I_Dont_Exist]
Exists:val:0
[END:main]
*** ****************************************** **/
当我在做的时候。如果要从命令行运行,请将文件命名为:
“NAE.C99”,然后创建一个名为“NAE.SH”的 bash 文件并将其放入其中。
双击脚本运行它,或者使用它所在的“./NAE.SH”
git bash 终端。
##################################################
############################# SC[ hkmf-strict ] ##
##################################################
base_name_no_extension="NAE"
##################################################
MY_COMMAND_STRING=$(cat << GCC_COMMAND_01
gcc
-x c
-c $base_name_no_extension.C99
-o my_object_file.o
-m64
GCC_COMMAND_01
)
C=$MY_COMMAND_STRING ############################
C=$C"-Werror " ## WarningsAreErrors ##
C=$C"-Wfatal-errors " ## StopAtFirstError ##
C=$C"-Wpedantic " ## UseStrictISO_C ##
C=$C"-Wall " ## WarnAboutAnyWeirdCode ##
C=$C"-Wextra " ## "-Wall" WarningsExtra ##
C=$C"-std=c99 " ## VersionOf_C_ToUse ##
MY_COMMAND_STRING=$C ############################
echo $MY_COMMAND_STRING
$MY_COMMAND_STRING
C1=" gcc -o EXE.exe my_object_file.o "
C2=" ./EXE.exe "
C3=" rm my_object_file.o "
C4=" rm EXE.exe "
$C1 && echo "OK:"$C1 || "FAIL:$C1"
$C2 && echo "OK:"$C2 || "FAIL:$C2"
$C3 && echo "OK:"$C3 || "FAIL:$C3"
$C4 && echo "OK:"$C4 || "FAIL:$C4"
##################################################
read -p "[END_OF_BUILD_SCRIPT:PressAnyKey]:"
##################################################
############################# SC[ hkmf-strict ] ##
##################################################
顺便说一下,这是C99代码。我尝试编写它以避免任何 C99 特定功能。