Some points needing attention in learning C language

C language learning

1. Pointer array and 2D array pointer

int *p[3];//Array of pointers.
int (*p)[3];//A pointer is defined, pointing to the data type int[3], pointing to the pointer of a two-dimensional array.

int buf[3][5];      2D array name, buf Represents the first address of the array
int (*a)[5];        Define a pointint[5]Pointer variable of type a;
a[0],*(a+0),*a;     0That's ok0Address of column element;
a+1;                The first1First address of line;
a[1],*(a+1);        The first1That's ok,0Column element address;
a[1]+2,*(a+1)+2,&a[1][2];       The first1That's ok,2Address of column element;
*(a[1]+2),*(*(a+1)+2),a[1][2];  The first1That's ok,2Value of column element;

2. Function pointer

int add(int a, int b)
{
    return a+b;
}
int main()
{
    ......
    int (*p)(int, int);//A pointer to a function is defined. It can point to two parameters that are int, and the return value is also an int function;
    p = add;//Write the name of the function directly, representing the address of the function, and assign the address of the add function to the pointer variable p;
    int i = 0;
    i = p(5,7);//Indirectly call the function pointed by the pointer through the pointer variable

//==========================================================================

    void *p(int ,char*); //Function declaration, function name: p, return value: void *, parameter: int, char*
    void (*p)(int ,char*);//A function pointer p is defined. The return value of this function is void. The parameters are int, char*

3.memset,memcpy,memmove
These three functions respectively implement memory setting, memory copying and memory moving.
When using memcpy, make sure that there are no overlapping areas of memory.
Contain

int buf[10] = { 0 };//It can only be used to initialize content at the same time when defining an array.
......
buf[10] = { 0 };//Wrong syntax

memset(buf,0,sizeof(buf));//The first parameter is the memory address to be set, the second parameter is the value to be set, and the third parameter is the memory size (unit: byte).
//The most common method is to initialize a block of memory to 0.
memcpy(buf2,buf1,sizeof(buf1));//Copy the contents of buf1 to buf2.

3. Parameters of main function

int main(int argc,char *argv[])
{
    printf("%d\n", argc);
    //Argc means that there are several parameters when the program is executing, and the program name itself is a parameter, so the minimum value of argc is 1.
    //The second parameter is an array of pointers, where the type of each member is char*
    //argvs is an array of pointers. argc tells the main function how many members argv has
    return 0;
}

4.register variable, static variable

register int i = 0;//It is recommended that if the register is free, this variable should be used in the register
int *p = &i;//Error. For a register variable, the address operation is not allowed.
......
static int a = 0;//Static variables, which are initialized only once, exist all the time during program running.

//===========================================================

main.c
static int a = 0;//Once the global variable defines static, it means that the variable is only valid inside the file where the variable is defined.
//Cannot be called with extern keyword in other files.

5. Four areas of memory

void test (int a, int b)//Formal parameter, stack area
{
    printf("%d,%d\n",&a,&b);
}
int a = 0;//Global variable, static area
int main()//Function, code area
{
    int a = 0;//Local variable, stack area
    static int i = 0;//Static variable, static area
    return 0;
}
......
char array[1024 * 1024 * 10];//Defining a large array will surely overflow the stack
//=====================================================
//Heap area
//Like stack, heap is a memory area that can be modified at any time in the process of program running, but there is no first in first out sequence like stack.
//Heap is a large container, its capacity is much larger than stack, but in c language, the release of heap memory space needs to be done manually through code.

//Heap allocation and release
int main()
{
    //1. stack array
    int array[10] = { 0 };
    //2. heap array
    int *p = (int*)malloc(sizeof(int) * 10);//Request memory space of 10 int s in the heap
    //char *p1 =(char*)malloc(sizeof(char) * 10); / / request memory space of 10 chars in the heap
    //free(p); / / free memory allocated through malloc
    //free(p1); / / free memory allocated through malloc
    //malloc and free are used in pairs
    memset(p, 0, sizeof(int) * 10);
    int i;
    for (i = 0; i < 10; i++)
    {
        p[i] = i;
    }
    return 0;
}

6. About the return value of stack and function, and the misunderstanding

int *get_a()//Error, cannot return the address of a stack variable through the return value of the function
{
    int a = 0;
    return &a;
}

int *get_a1()//You can return a heap address through the return value of the function, but remember to be free
{
    int *p = (int *)malloc(sizeof(int));//A heap space was requested
    return p;
}


//===================================================================

//misunderstanding
void getheap(int *p)
{
    p = (int *)malloc(sizeof(int) * 10);
}//After getheap is executed, p disappears, resulting in the address number of the specific heap space it points to disappear

int main()
{
    int *p = NULL;
    getheap(p);//There is no change to the arguments. The following operations are illegal
    //p[0] = 1;
    //p[1] = 2;
}

//Correct writing
void getheap(int **p)
{
    *p = (int *)malloc(sizeof(int) * 10);
}//After getheap is executed, p disappears, resulting in the address number of the specific heap space it points to disappear

int main()
{
    int *p = NULL;
    getheap(&p);//There is no change to the arguments. The following operations are illegal
    //p[0] = 1;
    //p[1] = 2;
}

//==================================================================
const char *getString()//The right model
{
    return "hello";//Constant in static memory
}
int main()
{
    char *p = getString();
    return 0;
}

7. Consortium
If there is a pointer member in the union, you must use the pointer completely, and you can use other members only after free pointer.

8. Read and write files

fopen("File path","%Pattern%");
//"r" opens the file as read-only. The file must exist "
//"r +" opens the file in a read-write mode. The file must exist
//"rb +" reading and writing opens a binary file, allowing reading and writing data. The file must exist
//"rw +" read / write opens a text file, allowing reading and writing
//"w" opens a write only file. If the file exists, the length of the file is clear 0, that is, the contents of the file will disappear. If the file does not exist, the file will be created
//"w +" opens a read-write file. If the file exists, the length of the file is clear 0, that is, the contents of the file will disappear. If the file does not exist, the file will be created
//"A" opens a write only file as an attachment. If the file does not exist, the file will be created. If the file exists, the written data will be appended to the end of the file, that is, the original contents of the file will be preserved. (EOF reserved)
//"A +" opens a read-write file in an additional way. If the file does not exist, the file will be created. If the file exists, the written data will be appended to the end of the file, that is, the original contents of the file will be preserved. (original EOF is not reserved)

9. Some functions to be noted

//========================================
fopen
fclose
//Text file operation function
    //Read and write files by character
int getc ( FILE * stream );
int putc ( int character, FILE * stream );

int feof ( FILE * stream );
int fprintf ( FILE * stream, const char * format, ... );
int fscanf ( FILE * stream, const char * format, ... );
    //Read and write files by line
char * fgets ( char * str, int num, FILE * stream );
int fputs ( const char * str, FILE * stream );
//========================================
//Binary read write function
//The free return value represents the number of records read
    //Read and write files by block
size_t fread(void*  _Buffer,size_t _ElementSize,size_t _ElementCount,FILE* _Stream);
size_t fwrite(void const* _Buffer,size_t _ElementSize,size_t _ElementCount,FILE* _Stream);

static int stat(char const* const _FileName, struct stat* const _Stat);
//Fseek's post return value 0 represents success, - 1 represents failure, but if the file pointer is moved backward and exceeds the file size, fseek's return value is still 0, but the forward move exceeds the file start position and returns - 1
int fseek(FILE* _Stream,long  _Offset,int _Origin);
long ftell(FILE* _Stream);
int fflush(FILE* _Stream);
int remove(char const* _FileName);
int rename(char const* _OldFileName,char const* _NewFileName);

//Pay attention to the code difference
while (!feof)//This function reads one more line
{
    fread(&buf, 1, sizeof(buf), p);
}
while (fread(&buf, 1, sizeof(buf), p))

C language improvement

I saw Wang Baoming's C language improvement these days and found that it was a bit messy. I need to sort it out. Easy to review later. explain profound theories in simple language.

1. The first day (mainly speaking some basic rules of C language)
1) Analysis of data types

int b[40];
//B + 1 & B + 1 result is different / / B & B represents different data types
//b represents the address of the first element of the array
//&B represents the address of the entire array

2. The next day (primary pointer memory model and key points of project development)

//1> Classic string copy function
void copy_str(char *from, char *to)
{
    //while((*to = *from)!='\0')
    //{
    //  from++;
    //  to++;
    //}

    //while((*to++ = *from++)!='\0')
    //{
    //  ;
    //}

    while(*to++ = *from++);
}

//2> String model 1 in project development: strstr while while model

#include<stdio.h>


int getCount_dowhile(char *mystr/*in*/,char *sub/*in*/,int *ncount)
{
    int ret = 0;
    char *p = mystr;//Do not change the value of parameter easily
    int tmpCount;

    if (mystr == NULL || sub == NULL || ncount == NULL)
    {
        ret = -1;
        printf("func getCount() err:%d.(mystr == NULL || sub == NULL || ncount == NULL) \n", ret);
        return ret;
    }

    do
    {
        p = strstr(p, sub);
        if (p != NULL)
        {
            tmpCount++;
            p = p + strlen(sub);
        }
        else
        {
            break;
        }
    } while (*p != '\0');

    *ncount = tmpCount;//Indirect assignment is the greatest meaning of pointer existence
    return 0;
}


int getCount_while(char *mystr/*in*/, char *sub/**/, int *ncount)
{
    int ret = 0;
    char *p = mystr;//Do not change the value of parameter easily
    int tmpCount;
    if (mystr == NULL || sub == NULL || ncount == NULL)
    {
        ret = -1;
        printf("func getCount() err:%d.(mystr == NULL || sub == NULL || ncount == NULL) \n", ret);
        return ret;
    }

    while (p = strstr(p, sub))
    {
        ncount++;
        p = p + strlen(sub);
        if (*p = '\0')
        {
            break;
        }
    }

    *ncount = tmpCount;//Indirect assignment is the greatest meaning of pointer existence
    return 0;
}

int main()
{
    int ret = 0;
    char *p = "abcd11111abcd2222abcdqqqq";
    char sub[] = "abcd";
    int count = 0;
    ret = getCount(p, sub, &count);
    if (ret != 0)
    {
        printf("func getCount() err:%d\n", ret);
    }
    return 0;
}


//String model 2 in project development: two end plug model

int trimSpaceStr2( char *p, char *buf2)
{
    int ret = 0;

    int ncount = 0;
    int i, j;
    i = 0;
    j = strlen(p) -1;

    while (isspace(p[i]) && p[i] != '\0')
    {
        i++;
    }

    while (isspace(p[j]) && j>0 )
    {
        j--;
    }

    ncount = j - i + 1;
    //
    strncpy(buf2, p+i, ncount);
    buf2[ncount] = '\0';
    return ret;
}

3. The third day (second level pointer memory model and key points of project development)

//String model 3 in project development: String inversion 1
void inverse(char *str)
{
    int length;
    int *p1, *p2;
    if (str == NULL)
    {
        return -1;
    }

    length = strlen(str);
    p1 = str;
    p2 = str + length - 1;

    while (p1 < p2)
    {
        char c = *p1;
        *p1 = *p2;
        *p2 = c;
        p1++;
        p2--;
    }
}

//String model 3 in project development: String inversion 2

void inverse02(char *p,char *bufresult)
{
    if (p == NULL || bufresult == NULL)
    {
        return;
    }

    if (*p == '\0')
    {
        return;
    }

    inverse02(p + 1, bufresult);
    strncat(bufresult,p,1);
}
What should be paid attention to in array size
    char a[10] = { 0 };
    printf("sizeof(a):%d \t a:%p \nsizeof(&a):%d \t &a:%p \n", sizeof(a), a, sizeof(&a), &a);
    printf("a+1:%p \n&a+1:%p \n", a + 1, &a + 1);

    char* b[10] = { 0 };
    printf("sizeof(b):%d \t b:%p \nsizeof(&b):%d \t &b:%p \n", sizeof(b), b, sizeof(&b), &b);
    printf("b+1:%p \n&b+1:%p \n", b + 1, &b + 1);
//Operation result:
sizeof(a):10    sizeof(&a):4     
a:0116FE34  a+1:0116FE35    
&a:0116FE34 &a+1:0116FE3E

sizeof(b):40    sizeof(&b):4 
b:0116FE04  b+1:0116FE08
&b:0116FE04 &b+1:0116FE2C

//in general,sizeof(Array name)The size of the array can be calculated directly, but the step size represented by the array name pointer is equal to the size of the first element; however, the step size of the second level pointer after the address of the array name is the size of the whole array,sizeofThe result is4. 

Keywords: C

Added by scialom on Thu, 09 Apr 2020 18:56:46 +0300