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 = # *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
- C基础学习笔记01
- C/C++基础学习笔记
- C语言基础学习笔记
- C、C++基础学习笔记
- 【C#】C#基础学习笔记
- C基础学习笔记02
- C++&C学习笔记(一)(基础)
- ios学习笔记基础-c语言01基本了解
- iOS学习笔记之-C语言基础01
- 学习笔记之C语言基础篇
- C/C++基础 达内学习笔记
- C语言基础学习笔记综合
- 数据结构学习笔记之C指针基础
- Object-c基础编程学习笔记-Foundation
- Object-c基础编程学习笔记-NSString
- Object-c基础编程学习笔记-集合
- Object-c基础编程学习笔记-分类
- Object-c基础编程学习笔记-协议
- 大牛的acm建议
- 关于alertdialog显示问题,显示有延迟
- 非阻塞式TCP 服务器/客户端 基础
- 下拉刷新
- HTTP协议的报文结构
- C基础学习笔记01
- Unity 编辑器环境下不能正确加载Android Assetbundle 中的 Shader 解决方法
- mongos的Java端操作
- EditText软键盘的回车按钮,改状态。
- Android的各种Dialog
- CSU - 1202 剪刀石头布
- C++ PRIMER 5th 学习小结(第二章)
- android kuangjia
- 每天一个linux命令(5):rm 命令