Re-understanding C language

Source: Internet
Author: User
Tags array definition

1. Origins

The C language has been in contact for three or four years, and the work has been using C language. But for some C language features and definitions there are some questions, here to summarize, as a reference later.

Link Properties for 2.C languages

in the work of no intention to discover the C language an interesting problem, in two source files defined the same uninitialized variable, the compiler should not error, but if in one of the files defined and initialized, it will be an error. My test uses the following code ( test Environment window7 (32-bit) gcc 4.5.0):

MAIN.C:

/* MAIN.C */#include <stdio.h>char g_testvalue;int g_testvalue2;void printtestvalue (void); int main (int Argc,char    *argv[]) {printtestvalue (); printf ("main:\t\t (&g_testvalue) =0x%08x\n\t\t" "(G_testvalue) =%d\n\t\tsizeof ((g_testvalue)) =%d\n" "\t\tG_ testvalue2=%d\n "\t\t&g_testvalue2=0x%08x\n",& (G_testvalue), G_testvalue, sizeof (G_testvalue), G_    Testvalue2,&g_testvalue2); return 0;}

GLOBAL_TEST.C:

/* global_test.c*/#include <stdio.h>typedef struct test_struct_t{char a;int b;} teststruct_t; teststruct_t G_testvalue = {2,8};int g_testvalue2; void Printtestvalue (void) {printf ("printtestvalue:\t (&g_testvalue) =0x%08x\n\t\t" "(G_TESTVALUE.A) =%d\n\t\tsiz EOF (G_testvalue) =%d\n "" \t\tg_testvalue2=%d\n "" \t\t&g_testvalue2=0x%08x\n ",& (g_testvalue), G_TestValue . A, sizeof (G_testvalue), g_testvalue2,&g_testvalue2);p rintf ("-----------------------------------------\ n");}

Makefile:

TEST:GLOBAL_TEST.O main.o gcc-o Test GLOBAL_TEST.O main.o-std=gnu99global_test.o:global_test.cgcc-c global_test.c- Std=gnu99main.o:main.cgcc-c main.c-std=gnu99 clean:rm *.O test

The code execution results are as follows:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/6F/4D/wKioL1WYml_TvtP_AAAV2KT-Y2k468.gif "title=" Grab 2.gif "alt=" Wkiol1wyml_tvtp_aaav2kt-y2k468.gif "/>

According to the above code analysis, we found that a phenomenon, in the Main.c file definition of the Char type variable g_testvalue but uninitialized, in the global_test.c file defines the structure type of the variable g_testvalue and initialized, All two files define the same global variable, one uninitialized and one initialized. Compile the above program without error, the result of the operation of the G_testvalue address is the same (I Experiment environment is (&g_testvalue) =0x00402000), and main.c in the print out of g_ The value of TestValue is 2 (that is, the value that is defined and initialized in the global_test.c file). This also indicates that the C linker link is only allocated a storage space for this variable, and if two times define the same type of variable name, allocate space by taking up the space that is large. In addition I used g_testvalue2 to do the verification, in two files are defined and are not initialized, from the print results, they are the same address.

Why is that so?

This involves the C compiler's parsing and linking of global symbols for multiple definitions. during the compile phase, the compiler implicitly encodes the global symbolic information in the symbol table of the relocatable target file. Here is the concept of "strong sign (strong)" and "weak symbol (weak)" -the former refers to variables that are defined and initialized, such as the structure g_testvalue in global_test.c, The latter refers to variables that are undefined or undefined but not initialized, such as Integer g_testvalue and g_testvalue2 in Main.c, and when the symbol is multi-defined, the GNU Linker (LD) uses the following rule resolution:

    • Multiple identical strong symbols are not allowed.

    • If you have a strong symbol and multiple weak symbols, select the strong symbol.

    • If there are more than one weak symbol, then the first resolution to the size of the largest, if the same size, then follow the link order to select the number one.

As in the above example, the global variable g_testvalue has a duplicate definition. If we assign a value of B initialization in MAIN.C, then there are two strong symbols that violate rule one, and the compiler gives an error. If rule two is met, only a warning is provided, and the actual runtime resolution is the strong symbol in global_test. C. The variable global_test2 is a weak symbol, so select only one (in the order in which the target file is linked).


The most authoritative explanation for the C language's Link property is in ISO/IEC 9899 programming languages -C ( See article Attachment ) 6.2.2 Chapters, interested buddies can download down to see. Another recommended article about the C language Link Property Description:The scope, namespace, link property, life cycle, storage type of identifiers in C language.

Specific knowledge about linker, the comparison system can be read: linker and loader.

3.malloc application space, and free space

One Day to work, think of a problem: Define a struct type, the member variable has a pointer row variable. Defines a struct-type variable, allocates space for it, and then allocates space to the member variable, freeing the struct-member variable for space to request? Or does it need to be released separately?

To test this situation, write the code to verify:

/* main.c */#include  <stdio.h> #include  <stdlib.h>typedef struct  Malloc_test_tag{char *str;int  n;} Malloctest_t ,*p_malloctest_t;int main (int argc,char *argv[]) {P_MallocTest_t test, saved_test;printf ("malloc for test\n");    test =  (P_MallocTest_t) malloc (sizeof (malloctest_t));    if  (null == test )       {       exit  (1);     }  printf ("the address of  (Test)  = 0x%x\n", test); saved_test = test;printf (" malloc for test->str\n ");test->str =  (char *) malloc (6);if  (NULL == &NBSP;TEST-&GT;STR)         {              exit  (1);         }  printf ("the address of  (test->str[0))  = 0x%x\n", Test->str);p rintf ("------ -----------------------------------\ n ");     printf (" free for test->str\n "); Free (TEST-&GT;STR);p rintf ("free for test\n"), free (test), test = null;printf ("malloc  For test again!!! \ n ");    test =  (p_malloctest_t) malloc (sizeof (malloctest_t));     if  (null == test )          {                 exit  (1);          } printf ("the address of " (test)  =  0x%x\n ", test);p rintf (" Malloc for test->str again!!!! \ n ");test->str =  (char *) malloc (6);if  (NULL&NBSP;==&NBSP;TEST-&GT;STR)           {                 exit  (1);          } printf ("The address of   (test->str[0])  = 0x%x\n ", Test->str);p rintf (" free for test->str 2\n "); Free (SAVED_TEST-&GT;STR); saved_test->str = null;printf ("free for test 2\n"); test); test = null;    return 0;}

The test idea is this, according to the principle of malloc, apply after the application, the application is the last space released. I first applied for the structure space required by test, then applied for the space of the struct member variable test->str, then freed the Test->str space, freed the test space, and then applied for the above two spaces. The result of the execution is this:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/6F/51/wKiom1WY1nqj7nPhAAATjUT_X0c763.gif "title=" Grab 3.gif "alt=" Wkiom1wy1nqj7nphaaatjut_x0c763.gif "/>

You can see that the test->str space for the two applications is the same, both the address of (test->str[0]) = 0x4c0ed0.

Then I did not release after the first application of test->str space, and re-applied for space in the second application. The code executes as follows:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/6F/4F/wKioL1WY2Prif1HQAAASgIoQ-c8175.gif "title=" Grab 4.gif "alt=" Wkiol1wy2prif1hqaaasgioq-c8175.gif "/>

You can see that the Test->str space for two applications is different, one is the address of (test->str[0]) = 0x4c0ed0, and one is the address of (test->str[0 ]) = 0x570ee0.

From the above experiment, we can see that, when using malloc, free to manage memory space, malloc and free as the basic unit, you use malloc to apply for how much space, you should use after the completion of the free space. In the example above, the space you apply for in the structure needs to be released separately. Personal conjecture, the basic implementation of malloc and free: The system manages a memory space (heap), when you use malloc application, the system will remember the first address you apply for space, the size of your application, etc., when you free will be based on the memory address you want to release, Then query for additional information such as the size of the system record when you apply for the space, and perform the release operation. Therefore, when you release the space for the malloc application, the address parameter should be the one you request for space, or the free function may fail.


4.C language variable length array

The C99 specification Specifies that variable-length arrays can be used, but it is only known that the actual project is useless. I wrote the following code:

/* MAIN.C */#include <stdio.h> #include <stdlib.h>int n = 10;int Test_array[n] = {1,2,3,4,5,};int main (int argc    , Char *argv[]) {printf ("The value test_array[0] is%d\n", test_array[0]); return 0;}

But the compile time gave a bunch of errors:

650) this.width=650; "src=" Http://s3.51cto.com/wyfs02/M00/6F/52/wKiom1WY28vR8RIsAAAYQSRLUGs708.gif "title=" Grab 5.gif "alt=" Wkiom1wy28vr8risaaayqsrlugs708.gif "/>

The first sentence of error: Defines a variable-length array at the file scope. Gee, it's strange, C99. Is it not supported to define variable-length arrays? My compiler is specified using the C99 standard compiled!

Later I will

int n = 10;

int Test_array[n] = {1,2,3,4,5,};

Move to the inside of the function, there is no error. Subsequently consulted ISO/IEC 9899 programming languages-c learned that C99 does not support variable-length array definition and use of file scope. and the variable-length array does not support initialization. You can only define a variable and assign a value. After that, the following tests were done:

/* MAIN.C */#include <stdio.h> #include <stdlib.h>void test (int n) {char test_array[n];p rintf ("the size of Test_array is%d\n ", sizeof (Test_array)); int main (int argc,char *argv[]) {int n = 10;int Test_array[n];test_array[0] = 10;printf ("The value test_array[0] is%d\n", t    EST_ARRAY[0]); test (4); test (5); return 0;}

Look at this variable-length array supported by C99, and it's pretty useful, huh.

5.C language long statement split, line wrapping

When writing code, a statement is too long, C is useful to support direct segmentation?

printf ("Printtestvalue:\t (&g_testvalue) =0x%08x\n\t\t" "(G_TESTVALUE.A) =%d\n\t\tsizeof (g_testvalue) =%d\n" "\ T \tg_testvalue2=%d\n "\t\t&g_testvalue2=0x%08x\n",& (G_testvalue), G_testvalue.a, sizeof (G_TestValue), G_Te Stvalue2,&g_testvalue2);

C Language Sentence segmentation symbol is a semicolon, space and line is ignored by the parser, so the general statement can be divided into multiple lines of writing.

Like the printf function above, the preceding format statement requires double quotation marks on each line.

There are also macro definitions that are more special:

#define SAFE_DELETE (P) do {DELETE p;              p = NULL; } while (0)

You need to wrap the statement using the ' \ ' delimiter.


Re-understanding C language

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.