C语言提高 (一)

一 数据类型
1 “类型”是对数据的抽象;
2 类型相同的数据有相同的表示形式、存储格式以及相关的操作
3 程序中使用的所有数据都必定属于某一种数据类型
4 数据类型分类
1)简单类型
a)基本型:整型、浮点型、字符型、空类型
b)用户自定义类型:枚举(enum)
2) 结构类型
数组、结构体、联合体、类(c++)
3)指针类型
5 数据结构的本质:固定内存大小的别名。
6万能类型void
1)void的字面意思是“无类型”,void *则为“无类型指针”, void *可以指向任何类型的数据
2)void指针意义
a)C语言规定只有相同类型的指针才可以相互赋值
b) void*指针作为左值用于“接收”任意类型的指针
c)void*指针作为右值赋值给其它指针时需要强制类型转换
char *p2 = (char *)malloc(sizoeof(char)*20);

二 变量
1 概念 :既能读又能写的内存对象,称为变量;若一旦初始化后不能修改的对象则称为常量。
2 本质:一段连续内存空间的别名。
3 修该方法:修改方法:直接 、间接

三 内存四区
1 程序运行时建立流程
1、操作系统把物理硬盘代码load到内存
2、操作系统把c代码分成四个区
3、操作系统找到main函数入口执行
2 各区元素分析
1)栈区:由编译器自动释放,存放函数的参数值,局部变量的值

char *getmem2() 
{ 
   char buf[20];//临时变量,栈区存放 
   strcpy(buf,"12344"); 
   return buf; 
 } 

2)一般由程序员分配和释放,若没释放,程序结束后可能由操作系统回收

char * getmem(intnum) 
{ 
 char *p = NULL; 
p = (char*)malloc(sizeof(char) * num); 
 if (p == NULL) 
     returnNULL; 
 return p; 
} 

3)全局区(静态区 )
4 )常量区:字符串常量和其他常量的存储位置,程序结束后由操作系统释放
5 )代码区

四 指针体铁律
1)指针是一种数据类型:
a)指针也是一种变量,占有内存空间,用来保存内存地址;b)在指针声明时,*号表示所声明的变量为指针;c)在指针使用时,*号表示操作指针所指向的内存空间中的值;d)指针变量和它指向的内存块是两个不同的概念。
2) 间接赋值(*p)
a)间接赋值成立的条件:2个变量(通常一个实参,一个形参)、建立关系,实参取地址赋给形参指针、*p形参去间接修改实参的值。

    int iNum = 0; //实参 
    int *p = NULL; 
    p = &iNum; 
    iNum = 1; 
    *p =2 ; //通过*形参 == 间接地改变实参的值 *p成立的三个条件:

b) 函数调用时:用n级指针(形参)改变n-1级指针(实参)的值
3) 一级指针典型用法
4) 二级指针的典型用法

五 字符串和一级指针内存模型专题
1 字符数组初始化方法

int main() 
{        
     //1 大{}号法初始化列表 
     //数组初始化有2种方法默认元素个数、指定元素个数 
     char buf1[] = {'a', 'b', 'c', 'd', 'e'};      //若没有指定长度,默认不分配零 
     //若指定长度,不够报错;buf长度多于初始化个数,会自动补充零 
     char buf2[6] = {'a', 'b', 'c', 'd', 'e'}; 
     char buf3[6] = {'a', 'b', 'c', 'd', 'e'}; 
     //char buf4[5] = {'a', 'b', 'c', 'd', 'e'}; 
     printf("buf3:%s", buf3); 
     system("pause"); 
     }

2 字符串初始化

int main() 
{ 
     //1 用字符串来初始化数组 
     char buf2[] = {'a', 'b','c','d','\0'}; 
     //2 字符串常量初始化一个字符数组 
     char buf3[] = {"abcde"};   //结论:会补充零 
     char buf4[] = "abcde"; 
     char buf5[100] = "abcde"; 

     printf(" strlen(buf5) :%d \n", strlen(buf5)); 
     printf(" sizeof(buf4) :%d \n", sizeof(buf5)); 
     printf(" sizeof(buf4) :%d \n", sizeof(buf4)); 
}

3 数组法和指针法操作字符串

     char buf5[100] = "abcde"; 
     char *p = NULL;
     //指针法1 
     for (i=0; i<100; i++) 
     { 
               printf("%c", *(buf5+i)); 
     } 
     //指针法2 
     printf("\n"); 
     p = buf5; 
     for (i=0; i<100; i++) 
     { 
               printf("%c", *(p+i)); 
     } 
     //下标法 
     for (i=0; i<100; i++) 
     { 
               printf("%c", buf5[i]); 
     } 

4 字符串做函数参数

//不要轻易改变形参的值, 要引入一个辅助的指针变量. 把形参给接过来.....
int copy_str26_good(char *from , char *to)
{
char *tmpfrom = from;
char *tmpto = to;
if ( from == NULL || to == NULL)
{
    return -1;
}
while ( *tmpto++ = *tmpfrom++ ) ;  //空语句
printf("from:%s \n", from);
}

5 库函数api
1) extern char *strcat(char *dest, const char *src);把src所指字符串添加到dest结尾处(覆盖dest结尾处的’\0’)。
2)char*strnset(char*str,char ch,unsigned n);将一个字符串中的前n个字符都设为指定字符ch
3)size_t strcspn(const char str1, const char str2);在字符str1中查找,与str2中任意字符有公共交集的位置
4)extern char *strpbrk(const char *s1, const char *s2);返回源s1与s2第一个公共字符位置在str1中位置的指针,没有公共字符返回NULL
5)char *strtok(char s[], const char *delim);分解字符串为一组字符串,每次调用成功则返回指向被分割出片段的指针。
注释:
s为要分解的字符,delim为分隔符字符(如果传入字符串,则传入的字符串中每个字符均为分割符)。首次调用时,s指向要分解的字符串,之后再次调用要把s设成NULL。

     char str[] = "now # is the time for all # good men to come to the # aid of their country"; 
     //char delims[] = "#"; 
     char *delims = "#"; 
     char *result = NULL; 
     result = strtok( str, delims ); 
     while( result != NULL ) 
     { 
               printf( "result is \"%s\"\n", result ); 
               result = strtok( NULL, delims ); 
     } 

6)extern char *strstr(char *str1, const char *str2);用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。
7)extern char *strchr(const char *s,char c);查找字符串s中首次出现字符c的位置,返回首次出现c的位置的指针,返回的地址是被查找字符串指针开始的第一个与c相同字符的指针,如果s中不存在c则返回NULL。
8)strcpy,strcmp,strlen

6 项目开发字符串模型
求字符串p中 abcd出现的次数,char *p = “abcd111122abcd3333322abcd3333322qqq”;

int get_substr_cnt(char *str,char *sub,int* cnt)
{

    char *tmp_str = str;
    int tmp_cnt = 0;
    int ret = 0;
    if(tmp_str == NULL || sub == NULL)
    {
        ret = -1;
        printf("str or sun is NULL. \n");   
        return ret;
    }
    tmp_str =  strstr(tmp_str,sub);
    while(tmp_str !=NULL)
    {
        tmp_cnt++;
        tmp_str += strlen(sub);
        tmp_str =  strstr(tmp_str,sub);
    }
    *cnt = tmp_cnt;
    return ret;
}

7 const专题

int main() 
{ 
const int a;  // 代表一个常整形数 
int const b; //同上,代表一个常整形数 
const char *c; //指向常整形数的指针(所指向的内存数据不能被修改,但是本身可以修改)
char * const d; //常指针(指针变量不能被修改,但是它所指向内存空间可以被修改)
char buf[100] 
const char *const e ; //e一个指向常整形的常指针(指针和它所指向的内存空间,均不能被修改)
return 0; 
} 

8强化训练
1) 实现trim

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int trimSpace(char *inbuf, char **outbuf)
{
int ret = 0;
char * p = inbuf;
int len = strlen(inbuf) - 1;
int left = 0, right = len;
char *tmp = NULL;

if (!inbuf)
{
    ret = -1;
    printf("inbuf is NULL. \n");
    return -1;
}

while (p[left] == ' ')
    left++;
while (p[right] == ' ')
    right--;

if (left >= right)
{
    *outbuf = NULL;
    return ret;
}

tmp = (char*)malloc(right - left + 1);
memset(tmp, 0, right - left + 1);
strncpy(tmp, p + left, right - left);
*outbuf = tmp;
return ret;
}

int main()
{
int ret = 0;
char *inbuf = "   123124    ";
char *outbuf;
ret = trimSpace(inbuf, &outbuf);

if (ret == 0)
    printf("outbuf=%s.\n", outbuf);
return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_40878579/article/details/81269845