direktori cari
Algorithms Algorithms(算法) bsearch bsearch_s qsort qsort_s Atomic operations Atomic operations library(原子操作库) ATOMIC_*_LOCK_FREE atomic_compare_exchange_strong atomic_compare_exchange_strong_explicit atomic_compare_exchange_weak atomic_compare_exchange_weak_explicit atomic_exchange atomic_exchange_explicit atomic_fetch_add atomic_fetch_add_explicit atomic_fetch_and atomic_fetch_and_explicit atomic_fetch_or atomic_fetch_or_explicit atomic_fetch_sub atomic_fetch_sub_explicit atomic_fetch_xor atomic_fetch_xor_explicit atomic_flag atomic_flag_clear atomic_flag_clear_explicit ATOMIC_FLAG_INIT atomic_flag_test_and_set atomic_flag_test_and_set_explicit atomic_init atomic_is_lock_free atomic_load atomic_load_explicit atomic_signal_fence atomic_store atomic_store_explicit atomic_thread_fence(线程围栏) ATOMIC_VAR_INIT kill_dependency memory_order(内存排序) C keywords auto(自动存储) break(跳出循环) C keywords(关键词) case char const(常量修饰符) continue default(预设运算式) do double(双精度浮点型) else enum(枚举类型) extern(全局变量) float(浮点数) for fortran goto(goto语句) if(if语句) inline(行内函式) int long(长整型) register(寄存器变量) restrict( restrict类型限定符) return short signed sizeof(sizeof运算符) static(静态变量) struct(结构体) switch(switch语句) typedef(typedef关键字) union(联合体) unsigned(无符号) void(空类型) volatile(volatile变量) while(while语句) _Alignas _Alignof _Atomic _Bool _Complex _Generic _Imaginary _Noreturn _Static_assert _Thread_local C language #define directive #elif directive #else directive #endif directive #error directive #if directive #ifdef directive #ifndef directive #include directive #line directive #pragma directive alignas(对齐指定符) Alternative operators and tokens(替代运算符和令牌) Analyzability Arithmetic operators Arithmetic types Array declaration(数组声明) Array initialization(阵列初始化) ASCII Chart Assignment operators(赋值运算符) types(atomic类型限定符) Basic concepts Bit fields(位域) break statement C language C Operator Precedence cast operator character constant(字符字面量) Comments(注释符) Comparison operators(比较运算符) compound literals(符合字面量) Conditional inclusion(条件包含) Conformance(一致性) const type qualifier(const 限定符) Constant expressions(常量表达) continue statement Declarations(声明) do-while loop Enumerations(枚举类型) Escape sequences(转义字符) Expressions(表达式) External and tentative definitions(外部和暂定的定义) File scope(文件范围) floating constant(浮点常量) for loop Function declarations(函数声明) Function definitions(函数声明) Functions Generic selection泛型选择 goto statement Identifier(标示符) if statement Implicit conversions(隐式转换) Increment/decrement operators(前置/后置操作符) Initialization(初始化) inline function specifier(内联函式) integer constant Lifetime(生命期) Logical operators(逻辑运算符) Lookup and name spaces Main function(主函式) Member access operators(会员接入运营商) Memory model Objects and alignment(字节对齐) Order of evaluation(评估顺序) Other operators Phases of translation(翻译阶段) Pointer declaration Preprocessor(预处理) restrict type qualifier(restrict类型限定符) return statement Scalar initialization(标量类型初始化) Scope(范围) sizeof operator(sizeof运算符) Statements(陈述) static assert declaration(静态断言声明) Static storage duration(静态存储周期) Storage-class specifiers(存储类说明符) string literals(字符串字面量) Struct and union initialization(结构体与联合体初始化) Struct declaration(结构体声明) switch statement Thread storage duration(线程存储时间) Type Type(类型) Typedef declaration(Typedef声明) Undefined behavior(未定义行为) Union declaration(联合体声明) Value categories(值类别) Variadic arguments(变长参数宏) volatile type qualifier(volatile 类型限定符) while loop _Alignof operator _Noreturn function specifier Date and time asctime(asctime函数) asctime_s clock CLOCKS_PER_SEC clock_t ctime(ctime函数) ctime_s Date and time utilities(日期和时间库) difftime(计算两个时间的间隔) gmtime gmtime_s localtime localtime_s mktime(将时间结构数据转换成经过的秒数的函数) strftime(格式化输出时间函数) time timespec timespec_get time_t tm wcsftime(格式化时间宽字符) Dynamic memory management aligned_alloc C memory management library(内存管理库) calloc free(释放动态分配空间的函数) malloc(动态分配内存空间的函数) realloc(重新分配内存空间的函数) Error handling abort_handler_s assert(断言) constraint_handler_t errno(错误报告) Error handling(错误处理) Error numbers(错误个数) ignore_handler_s set_constraint_handler_s static_assert File input/output clearerr(清除/复位) fclose feof ferror fflush(清空文件缓冲区) fgetc fgetpos fgets fgetwc fgetws File input/output fopen fopen_s fprintf fprintf_s fputc fputs fputwc fputws fread freopen freopen_s fscanf fscanf_s fseek fsetpos ftell fwide fwprintf fwprintf_s fwrite fwscanf fwscanf_s getc getchar gets gets_s getwchar perror printf printf_s putc putchar puts putwc putwchar remove rename rewind scanf scanf_s setbuf setvbuf snprintf sprintf sscanf sscanf_s swprintf swprintf_s swscanf swscanf_s tmpfile tmpfile_s tmpnam tmpnam_s ungetc ungetwc vfprintf vfprintf_s vfscanf vfscanf_s vfwprintf vfwprintf_s vfwscanf vfwscanf_s vprintf vprintf_s vscanf vscanf_s vsnprintf vsprintf vsscanf vsscanf_s vswprintf vswprintf_s vswscanf vswscanf_s vwprintf vwprintf_s vwscanf vwscanf_s wprintf wprintf_s wscanf wscanf_s Localization support lconv LC_ALL LC_COLLATE LC_CTYPE LC_MONETARY LC_NUMERIC LC_TIME localeconv Localization support setlocale Numerics abs acos acosf acosh acoshf acoshl acosl asin asinf asinh asinhf asinhl asinl atan atan2 atan2f atan2l atanf atanh atanhf atanhl atanl cabs cabsf cabsl cacos cacosf cacosh cacoshf cacoshl cacosl carg cargf cargl casin casinf casinh casinhf casinhl casinl catan catanf catanh catanhf catanhl catanl cbrt cbrtf cbrtl ccos ccosf ccosh ccoshf ccoshl ccosl ceil ceilf ceill cexp cexpf cexpl cimag cimagf cimagl clog clogf clogl CMPLX CMPLXF CMPLXL Common mathematical functions complex Complex number arithmetic conj conjf conjl copysign copysignf copysignl cos cosf cosh coshf coshl cosl cpow cpowf cpowl cproj cprojf cprojl creal crealf creall csin csinf csinh csinhf csinhl csinl csqrt csqrtf csqrtl ctan ctanf ctanh ctanhf ctanhl ctanl div double_t erf erfc erfcf erfcl erff erfl exp exp2 exp2f exp2l expf expl expm1 expm1f expm1l fabs fabsf fabsl fdim feclearexcept fegetenv fegetexceptflag fegetround feholdexcept feraiseexcept fesetenv fesetexceptflag fesetround fetestexcept feupdateenv FE_ALL_EXCEPT FE_DFL_ENV FE_DIVBYZERO FE_DOWNWARD FE_INEXACT FE_INVALID FE_OVERFLOW FE_TONEAREST FE_TOWARDZERO FE_UNDERFLOW FE_UPWARD Floating-point environment float_t floor floorf floorl fma fmaf fmal fmax fmaxf fmaxl fmin fminf fminl fmod fmodf fmodl fpclassify FP_INFINITE FP_NAN FP_NORMAL FP_SUBNORMAL FP_ZERO frexp frexpf frexpl HUGE_VAL HUGE_VALF HUGE_VALL hypot hypotf hypotl I ilogb ilogbf ilogbl imaginary imaxabs imaxdiv INFINITY isfinite isgreater isgreaterequal isinf isless islessequal islessgreater isnan isnormal isunordered labs ldexp ldexpf ldexpl ldiv lgamma lgammaf lgammal llabs lldiv llrint llrintf llrintl llround llroundf llroundl log log10 log10f log10l log1p log1pf log1pl log2 log2f log2l logb logbf logbl logf logl lrint lrintf lrintl lround lroundf lroundl MATH_ERREXCEPT math_errhandling MATH_ERRNO modf modff modfl nan NAN nanf nanl nearbyint nearbyintf nearbyintl nextafter nextafterf nextafterl nexttoward nexttowardf nexttowardl Numerics pow powf powl Pseudo-random number generation rand RAND_MAX remainder remainderf remainderl remquo remquof remquol rint rintf rintl round roundf roundl scalbln scalblnf scalblnl scalbn scalbnf scalbnl signbit sin sinf sinh sinhf sinhl sinl sqrt sqrtf sqrtl srand tan tanf tanh tanhf tanhl tanl tgamma tgammaf tgammal trunc truncf truncl Type-generic math _Complex_I _Imaginary_I Program support abort atexit at_quick_exit exit EXIT_FAILURE EXIT_SUCCESS getenv getenv_s jmp_buf longjmp Program support utilities quick_exit raise setjmp SIGABRT SIGFPE SIGILL SIGINT signal SIGSEGV SIGTERM sig_atomic_t SIG_DFL SIG_ERR SIG_IGN system _Exit Strings atof atoi atol atoll btowc c16rtomb c32rtomb char16_t char32_t isalnum isalpha isblank iscntrl isdigit isgraph islower isprint ispunct isspace isupper iswalnum iswalpha iswblank iswcntrl iswctype iswdigit iswgraph iswlower iswprint iswpunct iswspace iswupper iswxdigit isxdigit mblen mbrlen mbrtoc16 mbrtoc32 mbrtowc mbsinit mbsrtowcs mbsrtowcs_s mbstate_t mbstowcs mbstowcs_s mbtowc memchr memcmp memcpy memcpy_s memmove memmove_s memset memset_s Null-terminated byte strings Null-terminated multibyte strings Null-terminated wide strings strcat strcat_s strchr strcmp strcoll strcpy strcpy_s strcspn strerror strerrorlen_s strerror_s Strings library strlen strncat Thread support call_once cnd_broadcast cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait mtx_destroy mtx_init mtx_lock mtx_plain mtx_recursive mtx_timed mtx_timedlock mtx_trylock mtx_unlock once_flag ONCE_FLAG_INIT thrd_busy thrd_create thrd_current thrd_detach thrd_equal thrd_error thrd_exit thrd_join thrd_nomem thrd_sleep thrd_success thrd_timedout thrd_yield Thread support library thread_local tss_create tss_delete TSS_DTOR_ITERATIONS tss_get tss_set Type support Boolean type support library Fixed width integer types FLT_EVAL_METHOD FLT_ROUNDS max_align_t NULL Numeric limits offsetof ptrdiff_t size_t Type support Variadic functions Variadic functions va_arg va_copy va_end va_list va_start
watak

结构是一种由一系列成员组成的类型,其存储按有序顺序进行分配(与union相反,这是一种由存储重叠的成员序列组成的类型)。

union除了使用的关键字之外,结构的类型说明符与   类型说明符相同:

句法

结构名称(可选){结构声明列表}

(1)


结构名称

(2)


1)结构定义:引入新的类型结构名称并定义它的含义

2)如果在struct名称上使用它自己的行;,则声明但不定义该结构name(请参见下面的前向声明)。在其他上下文中,命名先前声明的结构。

name

-

正在定义的结构的名称

结构声明列表

-

任何数量的变量声明,位域声明和静态断言声明。不完整类型的成员和函数类型的成员是不允许的(除了下面描述的灵活数组成员)

说明

在一个结构对象中,其元素的地址(以及位字段分配单元的地址)按照成员定义的顺序增加。指向结构的指针可以转换为指向其第一个成员的指针(或者,如果该成员是位域,则指向其分配单元)。同样,可以将指向结构第一个成员的指针转换为指向封闭结构的指针。在结构的任何两个成员之间或者在最后一个成员之后,可能存在未命名的填充,但不在第一个成员之前。结构的大小至少与其成员大小的总和一样大。

如果一个结构至少定义了一个指定的成员,那么它允许额外地声明它的最后一个成员为不完整的数组类型。当访问灵活数组成员的元素时(在使用运算符的表达式中,或者使用灵活数组成员的名称作为右手边操作数),那么结构的行为就好像数组成员具有最长的大小适合为该对象分配的内存。如果没有分配额外的存储空间,则它的行为就像一个具有1个元素的数组,除非该行为是未定义的(如果访问该元素或产生了经过该元素的指针)。初始化,sizeof和赋值运算符忽略了灵活的数组成员。具有灵活数组成员的结构(或其最后一个成员是具有灵活数组成员的结构的联合结构)不能以数组元素或其他结构成员的形式出现。struct s {int n; double d []; }; // sd是一个灵活的数组成员struct s t1 = {0}; // OK,d就好像是double d1,但UB访问struct s t2 = {1,{4.2}}; //错误:初始化忽略灵活数组//如果sizeof(double)== 8 struct s * s1 = malloc(sizeof(struct s)+ 64); //好像d是双d8 struct s * s2 = malloc(sizeof(struct s)+ 46); //好像d是double d5 s1 = malloc(sizeof(struct s)+ 10); //现在好像d是double d1 s2 = malloc(sizeof(struct s)+ 6); //相同,但UB访问double * dp =&(s1-> d0); // OK * dp = 42; // OK dp =&(s2-> d0); // OK * dp = 42; //未定义行为* s1 = * s2; //只复制sn,而不是sd的任何元素//除了在sizeof(struct s)中捕获的元素外,

(自C99以来)

类似于联合,一个结构的未命名成员的类型是一个没有名字的结构被称为匿名结构。匿名结构的每个成员都被认为是封闭结构或联合的成员。如果封闭的结构或联合也是匿名的,则这将递归应用。struct v {union {//匿名联合结构{int i,j; }; //匿名结构struct {long k,l; } w; }; int m; } v1; v1.i = 2; //有效v1.k = 3; //无效:内部结构不是匿名的v1.wk = 5; // valid与union类似,如果struct没有任何指定成员(包括通过匿名嵌套结构或联合获得的成员)定义,则程序的行为是未定义的。

(自C11以来)

前向声明

以下表格的声明。

结构名称;



隐藏标签名称空间中名称名称的任何先前声明的含义,并将名称声明为当前作用域中的新结构名称,稍后将对其进行定义。在定义出现之前,此结构名称的类型不完整。

这允许相互引用的结构:

struct y;struct x { struct y *p; /* ... */ };struct y { struct x *q; /* ... */ };

请注意,只需在另一个声明中使用结构标签即可引入新的结构名称,但如果在标签名称空间中存在以前声明的具有相同名称的结构,则该标签将引用该名称。

struct s* p = NULL; // tag naming an unknown struct declares itstruct s { int a; }; // definition for the struct pointed to by pvoid g(void){
    struct s; // forward declaration of a new, local struct s              // this hides global struct s until the end of this block
    struct s *p;  // pointer to local struct s                  // without the forward declaration above,                  // this would point at the file-scope s
    struct s { char* p; }; // definitions of the local struct s}

关键词

struct.

注释

有关结构初始化程序的规则,请参阅结构初始化。

因为不完整类型的成员是不允许的,并且结构类型直到定义结束才会完成,所以结构体不能拥有自己类型的成员。允许指向它自己的类型的指针,并且通常用于实现链接列表或树中的节点。

因为结构声明不会建立范围,所以struct-declaration-list中的声明引入的嵌套类型,枚举和枚举器在定义了结构的周围范围内是可见的。

#include <stddef.h>#include <stdio.h>
 int main(void){
    struct car { char *make; char *model; int year; }; // declares the struct type    // declares and initializes an object of a previously-declared struct type
    struct car c = {.year=1923, .make="Nash", .model="48 Sports Touring Car"};    printf("car: %d %s %s\n", c.year, c.make, c.model); 
    // declares a struct type, an object of that type, and a pointer to it
    struct spaceship { char *make; char *model; char *year; }
        ship = {"Incom Corporation", "T-65 X-wing starfighter", "128 ABY"},        *pship = &ship;    printf("spaceship: %s %s %s\n", ship.year, ship.make, ship.model); 
    // addresses increase in order of definition    // padding may be inserted
    struct A { char a; double b; char c;};    printf("offset of char a = %zu\noffset of double b = %zu\noffset of char c = %zu\n"           "sizeof(struct A)=%zu\n", offsetof(struct A, a), offsetof(struct A, b),           offsetof(struct A, c), sizeof(struct A));
    struct B { char a; char b; double c;};    printf("offset of char a = %zu\noffset of char b = %zu\noffset of double c = %zu\n"           "sizeof(struct B)=%zu\n", offsetof(struct B, a), offsetof(struct B, b),           offsetof(struct B, c), sizeof(struct B)); 
    // A pointer to a struct can be cast to a pointer to its first member and vice versa
    char* pmake = (char*)&ship;
    pship = (struct spaceship *)pmake;}

可能的输出:

car: 1923 Nash 48 Sports Touring Car
spaceship: 128 ABY Incom Corporation T-65 X-wing starfighter
offset of char a = 0offset of double b = 8offset of char c = 16sizeof(struct A)=24offset of char a = 0offset of char b = 1offset of double c = 8sizeof(struct B)=16

参考

  • C11标准(ISO / IEC 9899:2011):

    • 6.7.2.1结构和联合说明符(p:112-117)

  • C99标准(ISO / IEC 9899:1999):

    • 6.7.2.1结构和联合说明符(p:101-104)

  • C89 / C90标准(ISO / IEC 9899:1990):

    • 3.5.2.1结构和联合说明符

Artikel sebelumnya: Artikel seterusnya: