C基础学习笔记01

来源:互联网 发布:python脚本怎么写 编辑:程序博客网 时间:2024/04/23 14:56

LinuxC基础学习(知识点)_01

  • 野指针的产生与解决
#include <stdio.h>#include <stdlib.h>int main(){    char * p = NULL;//初始化p = NULL,即p->0x0000    p = (char *)malloc(100);//为p分配内存,p->0x1234     strcpy(p,"hello world");     //操作系统为"hello world"分配内存,并将"hello world"复制到p指向的内存空间     // p->0x1234     // *p -> "hello world"     if (p != NULL){ //此时p->0x1234不为空        free(p);//产生野指针        //free(p) 使p 指向的内存为空, 即 *p = NULL,也就是将"hello world"->NULL,但是p仍旧指向0x1234//解决方案:p = NULL;//置空解决野指针的产生问题     }    if (p != NULL)//当p没有置空的时候,p->0x1234不为空, *p 里面的内容为空    {            free(p);//回收p,即free(NULL);会引发中断    }    printf("Hello world!\n");    return 0;}
当分配内存回收的时候,记得置空[free(p),p = NULL]
  • 不要向[NULL]写入数据
#include <stdio.h>#include <stdlib.h>int main (){  char * p = NULL; //初始化内存//解决方案: p = (char *)malloc(100); //为p分配内存空间  strcpy(p,"hello world"); // NULL -> 0x0000 即 p->0x0000这段内存空间,这段内存空间是操作系统大哥//所使用的,不能写入。  return 0;}
 char * p = (char *)malloc(100);//当需要自己手动分配内存的时候,可以在初始化的时候顺便分配内存。
  • 一个指针可以指向多个不同的内存
#include <stdio.h>#include <stdlib.h>int main(){  char * p = NULL;  char buf[128] = "hello";  char * temp = (char *)malloc(100);  strcpy(temp,"world");  p = buf;//合法  p = temp;//合法  return 0;}
  同一个指针可以操作不同地址的内存,C语言和Java语言的区别
  • 指针间接赋值技术
#include <stdio.h>#include <stdlib.h>int change(int num){  num = 30;  return num;}void changep(int * num){  *num = 100;}int main (){  //1.在同意作用域利用p间接改变num的值  int num = 10;  int * p = &num;  *p = 20;  //===============  //2.利用函数的返回值,但是return 每次只能返回一个数,即使返回 struct 也不方便  num = change(num);    //==============  //3.利用指针传递地址  changep(&num);  //=============  return 0;}
  • 二级指针
#include <stdio.h>#include <stdlib.h>void changep(char ** temp){  *temp = 0x300;}int main(){  char *temp_1 = NULL;  char ** temp_2 = NULL;  temp_1 = 0x111;  temp_2 = 0x222;  //直接修改temp_1的值  temp_1 = 0x1122;  //间接修改temp_1的值  temp_2 = &temp_1;  //temp_2存储的temp_1的地址  //*temp_2 ==> temp_1的地址  //**temp_2 ==> *temp ==> 拿到一个内存地址的值  *temp_2 = 0x100;//将temp_1的地址指向0x100  printf("temp_1:%p\n",temp_1);  //在函数外部改变temp_1的地址  changep(&temp_1);  printf("temp_1:%p\n",temp_1);}
修改一个变量的地址需要一级指针;修改一个一级指针的地址需要二级指针
  • 指针间接赋值,C语言接口设计思想
//指针间接赋值//接口封装设计#include <stdio.h>#include <stdlib.h>#include <string.h>//函数声明[返回值判断此函数块的运行状态是否正常]int Interface(char ** temp_1,int * temp_1_len,char ** temp_2,int * temp_2_len);void Freestr(char ** temp_1,char ** temp_2);int main(){    char * one = NULL;    char * two = NULL;    int len_1 = 0;    int len_2 = 0;    int type = Interface(&one,&len_1,&two,&len_2);    if (type == 0){        printf(" application is error!\n");        return type;    }    printf("one->%s || %d\n",one,len_1);    printf("two->%s || %d\n",two,len_2);    //回收内存    Freestr(&one,&two);     return 0;}int Interface(char ** temp_1/*out*/,int * temp_1_len/*out*/,char ** temp_2/*out*/,int * temp_2_len/*out*/){    char * t_one = (char *)malloc(1024);    char * t_two = (char *)malloc(1024);    if (t_one == NULL || t_two == NULL)            return 0;    //application run error!    /*================    处理分配的内存    ================*/    strcpy(t_one,"This is temp_1 memery is run ");    strcpy(t_two,"This is temp_two memery is tun too ");    int one_length = strlen(t_one);    int two_length = strlen(t_two);    //指针间接赋值    *temp_1 = t_one;    *temp_2 = t_two;    *temp_1_len = one_length;    *temp_2_len = two_length;    return 1;}//释放内存void Freestr(char ** temp_1/*in*/,char ** temp_2/*in*/){    if (*temp_1 == NULL) return ;    free(*temp_1);    *temp_1 = NULL;    if (*temp_2 == NULL) return ;    free(*temp_2);    *temp_2 = NULL;}
  • 一级指针的用法[数组|字符串]
char str[] = {'a','b','c','d'};//代表一个数组,并不是一个字符串char string = "hello world";//作为字符数组,占用12个字节,作为字符串,占用11个字节int len = strlen(string);//计算字符串的长度int size = sizeof(string);//计算数组的大小//打印字符串string//1.int i = 0;for (i = 0;i < strlen(string);i++){  printf("%c",string[i]);} printf("\n");//2.char * p = NULL;p = string;//拿到字符串元素的首地址for (i = 0;i < strlen(string);i++){  printf("%c",*(p+i));}printf("\n");
  • 指针和内存的首地址区别
char str[] = "abcd";str = 0x1234;//错误,str是一个常量,不可被更改int * p = NULL;//指针是一个变量,可以被更改p = 0x1234;//允许p = 0x1122;//允许
  • 字符串的内存分布
char str[20] = "abcd";//栈区,可读可写,占用20个字节,由系统自动回收char str2[] = "abcd";//栈区,可读可写,占用5个字节,由系统自动回收char * pstr1 = "abcd";//代码区,可读不可写,占用4个字节,由系统自动回收char * pstr2 = (char *)malloc(100);//堆区,可读可写,占用100个字节,由程序员手动回收strcpy(pstr2,"abcd");
  • 字符串strcpy手动实现及优化
void str_copy(char * from,char * to){    /*1.==========================    for (;*from != '\0';from++,to++) *to = *from;    *to = '\0';    ===========================*/    /*2.==========================    for (;*from != '\0';) *to++ = *from++;    *to = '\0';    ===========================*/    /*3.==========================    while (*from != '\0'){        from++;        to++;    }    *to = '\0';    ===========================*/    /*4.==========================    while ((*from = *to) != '\0' ){        from++;        to++;    }    ===========================*/    /*5.==========================    while ((*to++ = *from++) != '\0');    ===========================*/    /*6.==========================    while ((*to++ = *from++));    ===========================*/    return ;}
  • 在母串中查找子串出现的次数
int getstrcount(char * str/*in*/,char * sub/*in*/,int * count/*out*/){    //记录出现的次数    int tempcount = 0;    //不要轻易去改变形参的值    char * temp = str;    if (str == NULL || sub == NULL || count == NULL)        return -1;    while (temp = strstr(temp,sub)){        printf("%s\n",temp);        tempcount++;        temp += strlen(sub);        if (*temp == '\0') break;    }    *count = tempcount;    return 0;}
  • 字符串两头堵模型[计算非空字符串的长度|字符串去空格]
/*去掉字符串的空格*/int LeftandRightTrimSpaceInterface(char * str/*in*/,char * buf/*out*/){    if (str == NULL || buf == NULL)        return -1;    int start = 0;    int end = strlen(str) - 1;    while (isspace(str[start]) && str[start] != '\0') start++;    while (isspace(str[end]) && str[end] != '\0') end++;    strncpy(buf,str+start,end-start+1);    return 0;}/*计算非空字符串的长度*/int LeftandRightCountSpaceInterface(char * str/*in*/,int * count/*out*/){    if (str == NULL || count == NULL)        return -1;    int start = 0;    int end = strlen(str) - 1;    while (isspace(str[start]) && str[start] != '\0') start++;    while (isspace(str[end]) && str[end] != '\0') end--;    *count = end - start + 1;    return 0;}
  • 字符串反转
/**    函数在调用前应该先初始化用作输出的字符串[memset(string,0,sizeof(string));]**//*1.========================================================================int inreverse(char * str/*in*/){    if (str == NULL)        return -1;    int start = 0;    int end = strlen(str) - 1;    for (;start < end;start++,end--){        char temp = str[start];        str[start] = str[end];        str[end] = temp;    }    return 0;}========================================================================*//*2========================================================================void inreverse_2(char * str /*in*/,char * string /*out*/){    if (str == NULL ||string = NULL ||  *str == '\0'){        *(string + strlen(string) + 1) = '\0';         return ;    }    *(string + strlen(str) - 1) = *str;    inreverse_2(str+1,string);}========================================================================*//*3========================================================================void inreverse_3(char * str/*in*/,char * string/*out*/){    if (str == NULL || string == NULL || *str == '\0'){        return ;    }    inreverse_3(str+1,string);    printf("str = %c\n",*str);    strncat(string,str,1);}========================================================================*/
  • 根据key解析value的值案例
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>int getKeyByValue(char * str,char * key,char * value);int getStringTrimSpace(char * str,char * value);int main(){    char value[20] = {0};    char * str = "name = xiaoming";    getKeyByValue(str,"name",value);    printf("value = %s\n",value);    return 0;}//根据key解析valueint getKeyByValue(char * str/*in*/,char * key/*in*/,char * value/*out*/){    char * pstr = NULL;//临时指针变量    if (str == NULL || key == NULL || value == NULL)        return -1;    //查找key是否在str中    pstr = str;    pstr = strstr(pstr,key);    if (pstr == NULL)        return -1;    pstr = pstr + strlen(key);    //查找等号的位置    pstr = strstr(pstr,"=");    if (pstr == NULL)        return -1;    pstr = pstr + strlen("=");    //去除value左右两边的空格    int type =getStringTrimSpace(pstr,value);    if (type == -1)        return -1;    return 0;}//去空格int getStringTrimSpace(char * str/*in*/,char * value/*out*/){    if (str == NULL || value == NULL)        return -1;     int start = 0;     int end = strlen(str) - 1;     while (isspace(str[start]) && str[start] != '\0') start++;;     while (isspace(str[end]) && str[end] != '\0') end--;    strncpy(value,str+start,end-start+1);    return 0;}
  • const修饰符
const int A = 10;//常量const char * str = NULL;//str所指向的内存不能被修改char * const str = NULL;//str的指针地址不能被修改 const char * const str;//只读
  • 二级指针内存模型
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>//分配内存char ** getMemery(int num);//显示void printMyArray(char ** pstr,int num);//排序void sortArray(char ** str,int num);//释放内存void freeArray(char *** str,int num);#define NUM 5int main(){    char ** str = NULL;    str = getMemery(NUM);    printMyArray(str,NUM);    sortArray(str,NUM);    printMyArray(str,NUM);    freeArray(&str,NUM);    return 0;}char ** getMemery(int num/*in*/){    int i = 0;    char ** pstr = NULL;    //分配一个指针数组    pstr = (char **)malloc(sizeof(char *) * num);    if (pstr == NULL)        return NULL;    for (i = 0;i < num;i++ )     {         //为指针数组里的每个指针所指向的内存空间分配内存        pstr[i] = (char *)malloc(sizeof(char *) * 100);        sprintf(pstr[i],"%d%d%d",i+1,i+1,i+1);     }     return pstr;}void printMyArray(char ** pstr/*in*/,int num/*in*/){    int i  = 0;    for (i = 0;i < num;i++){        printf("%s\n",pstr[i]);    }}void sortArray(char ** str/*in*/,int num/*in*/){    int i = 0,j = 0;    char * temp = NULL;    for ( i = 0;i < num;i++){        for ( j = i;j < num;j++){            if (strcmp(str[i],str[j]) < 0){                //交换的是指针的指向                temp = str[i];                str[i] = str[j];                str[j] = temp;            }        }    }}void freeArray(char *** str/*in*/,int num/*in*/){    int i = 0;    char ** temp = NULL;    if (str == NULL)        return ;     //拿到二级指针    temp = *str;    for (i = 0;i < num;i++)    {        //释放一级指针        free(temp[i]);        temp[i] = NULL;    }    //释放二级指针    free(temp);    //注:temp = NULL 和 *str = NULL不同,temp = NULL并不能改变*str的指向    *str = NULL;}
  • 根据标识符切割字符串
#include <stdio.h>#include <stdlib.h>#include <ctype.h>#include <string.h>int stringsplit(const char * str,char c,char *** pstr ,int * length);int getstringleng(const char * str,char c,int * len,int * maxlen);void printfArray(char ** str,int len);int main(){    char * str = "aaa,bbb,cccc,ddddd,abcdefg,111,2222,333333";//测试数据    int len = 0;    char ** list = NULL;//创建数组    stringsplit(str,',',&list,&len);//初始化数组    printfArray(list,len);//显示    //释放内存...    //先释放一级指针,在释放二级指针    return 0;}//显示void printfArray(char ** str/*in*/,int len/*in*/){    int i = 0;    for (i = 0;i < len;i++){        printf("[%s]\n",str[i]);    }}//分配内存并切割字符串int stringsplit(const char * str/*in*/,char c/*in*/,char *** arr/*out*/ ,int * length/*out*/){    //为字符串末尾补充标识符    char * newstr = (char  *)malloc(strlen(str) + 2);    sprintf(newstr,"%s%c",str,c);    int len=0;    int maxlen = 0;    if (!getstringleng(newstr,c,&len,&maxlen))        return -1;     printf("len = %d\n",len);     printf("maxlen = %d\n",maxlen);    char ** pstr = NULL;    pstr = (char **)malloc(sizeof(char *) * len);    char * temp = newstr;    char * current = newstr;    int i = 0;//pstr数组下标    while (*newstr != '\0'){        current = strchr(current,c);        if (current != NULL){            if (current - temp > 0){                pstr[i] = (char *)malloc(sizeof(char) * maxlen + 1);                strncpy(pstr[i],temp,current - temp);                strncat(pstr[i],"\0",1);                temp = current = current + 1;                i++;            }else{                break;            }        }else{            break;        }    }    *arr = pstr;    *length = len;    free(newstr);    newstr = NULL;    return 0;}//拿到字符串的数量以及字符串的最大长度int getstringleng(const char * str/*in*/,char c/*in*/,int * len/*out*/,int * maxlen/*out*/){    if (str == NULL || len == NULL || maxlen == NULL)        return -1;    //临时指针    char * pstr = str;    char * temp = str;    int count = 0;    int index = 0;    while (*str != '\0'){        pstr = strchr(pstr,c);        if (pstr != NULL){            //防止标识符连在一起            if (pstr - temp > 0){                int tp = (int)(pstr - temp);                if (tp > index)                    index = tp;                    count++;                temp = pstr = pstr + 1;            }else{                break;            }        }else{            break;        }    }    *len = count;    *maxlen = index;    return 0;}
0 0