C语言---总结

Posted blknemo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言---总结相关的知识,希望对你有一定的参考价值。

基础

  • 程序结构是三种: 顺序结构、选择结构(分支结构)、循环结构。
  • 读程序都要从 main()入口, 然后从最上面顺序往下读(碰到循环做循环,碰到选择做选择),有且只有一个main函数。
  • 计算机的数据在电脑中保存是以二进制的形式. 数据存放的位置就是他的地址.
  • bit是位,指为0或1。byte是指字节,一个字节=八个位。
  • 每个C语言程序写完后,都是先编译,后链接,最后运行。(.c→.obj→.exe)这个过程中注意.c 和.obj 文件时无法运行的,只有.exe文件才可以运行。

常考

  • 编译预处理不是 C语言的一部分,不占运行时间不要加分号
    C语言编译的程序称为源程序,它以ASCII数值存放在文本文件中。
  • define PI 3.1415926; 这个写法是错误的,一定不能出现分号
  • 每个C语言程序中main函数是有且只有一个。
  • 在函数中不可以再定义函数。
  • 算法:可以没有输入,但是一定要有输出。
  • break可用于循环结构和switch语句。
  • 逗号运算符的级别最低,赋值的级别倒数第二。
  • int *p 中 *p 和 p 的差别:简单说*p 是数值,p 是地址
    • *p:可以当做变量来用;*的作用是取后面地址 p 里面的数值。
    • p:是当作地址来用。可以用在 scanf 函数中:scanf(“%d”,p);
  • *p++ 和 (*p)++的之间的差别:(笔试重点)
    • *p++:地址会变化。
      口诀:取当前值,然后再移动地址!
    • (*p)++:数值会要变化。
      口诀:取当前值,然后再使数值增加 1。

      例题:int *p,a[]={1,3,5,7,9};
      p=a;
      请问*p++和(*p)++的数值分别为多少?
      *p++:这个本身的数值为1。由于是地址会增加一,所以指针指向数值3了。
      (*p)++:这个本身的数值为1。由于++表示数值会增加,指针不移动,但数值1由于自加了一次变成了2。

  • 二级指针:
    • *p:一级指针:存放变量的地址。
    • **q:二级指针:存放一级指针的地址。

      常考题目:int x=7;int*p=&x,**q=p;
      问你:*p 为多少?*q为多少?**q为多少?
      *p=7,*q=p,**q=7
      再问:**q=&x 的写法可以吗?不可以,二级指针只能存放一级指针的地址。

  • 程序进行编译时,并不为形式参数分配存储穿间。只有在被调用时形式参数才临时地占有存储空间。形式参数用关键字auto作存储类别的声明时,关键字“auto”可以省略,auto 不写则隐含确定为“自动存储类别”,它属于动态存储方式。
  • 函数的存储类型是函数定义时函数名前面的数据类型前面的存储类型,缺省时应该是:extern,表示该函数属外部函数(即 可以被本 C 文件外的其他 C 源程序文件中的函数调用
    • extern:
      整个工程可见,其他文件可以使用extern外部声明后直接使用。也就是说其他文件不能再定义一个与其相同名字的变量了(否则编译器会认为它们是同一个变量)
    • static:代表静态全局
      仅对当前文件可见,其他文件不可访问,其他文件可以定义与其同名的变量,两者互不影响。

重点

  • strlen 和 sizeof 的区别(重点):
    • sizeof:(求实际存储空间
      相当于是个宏一样的东西,因为它只是一个运算符,而不是函数,编译时展开为常数,编译的时候有每个变量的定义表,sizeof通过查表确定变量占用的空间,这是分配内存给process 之前要确定的。
      其实可以简单的理解sizeof针对"类型"的,而非"变量",但此时不能这样看如:sizeof("HELLO");中括号中为const char *,而是一个"字符串",所以结果大小为 5.但:
    char *ps = "HELLO";
    sizeof(ps) = 4  //只是指针的大小,即 地址(整数类型占4个字节)
    sizeof(*ps) = 1 //*ps+0代表数组第一个元素的大小,即ps[0]
    
    char as[8];
    sizeof(as) = 8  //因为as的类型为 char [8],这个大小的确是8
    sizeof(*as) = 1 //*as+0代表数组第一个元素的大小,即as[0]
    
    char aa[8][9];
    sizeof((char *)aa) = 4  //还是 char *
    
    char arr[100] = "HELLO";
    sizeof(arr) = 100   //和赋什么值没什么关系,关键是"类型"是什么
    
    int func(char p[100]) {
        sizeof(p) = 4;
        /*C/C++中不能传数组,只能传指针,所以任何数组都会隐式转成指针形式进行操作。*/
    }
    • strlen:(求字符串长度,即 字符个数,不包括结束符)
      它是一个函数,参数是 const char*,搞清楚它的实现,就是碰到‘‘(字符串结尾,就停止计数,但不包括‘‘)。所以它不是看类型而是看变量,取决于变量赋的什么值。
  • 函数的递归一定会考。
  • 两种重要的数组长度:
    char a[]={‘a’,’b’,’c’}; 数组长度为3,字符串长度不定(因为没有‘‘结束符)。sizeof(a)为3。
    char a[5]={ ‘a’,’b’,’c’}; 数组长度为5,字符串长度3。sizeof(a)为5。
    char a[]={‘a‘,‘b‘,‘c‘}; 这是一个字符数组,占3个字节
    char a[]="abc" 则不同,它是一个字符串,最后还有一个‘‘结束符,占4个字节

  • scanf 和 gets 的区别:
    如果输入的是 good good study!
    • scanf(“%s”,a);
      只会接收 good。 考点:不可以接收空格。(遇到空格或回车就终止)
    • gets(a);
      会接收 good good study! 考点:可以接收空格。(遇到回车终止)
  • 指针考点:
    char ch[]=”iamhandsome”;
    char *p=ch;
    问你:*(p+2) 和 *p+2 的结果是多少?
    *(p+2) = ‘m’ *p+2 = ‘k’

    解析:
    第一个是地址+2,所以取m;
    第二个则是数值+2,即 ASCII码值+2,ijk,所以取k。

  • 字符串的赋值:
    C语言中没有字符串变量,所以用数组和指针存放字符串:
    1. char ch[10]={“abcdefgh”};
    2. char ch[10]=“abcdefgh”;
    3. char ch[10]={‘a’,’b’,’c’,’d’,’e’,’f’,’g’,’h’};
    4. char *p=“abcdefgh”;
    5. char *p;
    6. ch=“abcdefgh”; !数组名不可以赋值!(只能一个一个循环赋值)
    7. char *p={“abcdefgh”}; !不能够出现大括号!
  • 逗号表达式:
    优先级别最低。表达式的数值逗号最右边的那个表达式的数值。
    (2,3,4)的表达式的数值就是4。
    z =(2,3,4)(整个是赋值表达式),这个时候z的值为4。
    z = 2,3,4 (整个是逗号表达式),这个时候z的值为2。

宏定义defind

问题:#define f(x)(x*x) 和 #define f(x) x*x 之间的差别。

define是C语言中的宏定义关键字,其定义格式如下:

#define [MacroName] [MacroValue]宏定义分为普通宏定义和带参数的宏定义

  • 普通宏定义:#define PI (3.1415926)

  • 带参数的宏定义 (宏函数):#define max(a,b) ((a)>(b)? (a),(b))
    注意:变量在宏中要用括号括起来
    因为,在C语言中define宏定义在编译时,会被展开,进行“傻瓜式”替换,也称为“字面”替换,如果没有括号有可能会产生歧义。

    如:

    int a,b,c,d,e;
    a=1;b=2;c=6;d=4;
    e=f(a+b) * f(c+d) ;  //理论值e=9*100=900
    
    #define f(x)(x*x)
    替换结果为:e=(a+b*a+b)*(c+d*c+d) = 5*34=170
    
    #define f(x) x*x 
    替换结果为:e=a+b*a+b*c+d*c+d=1+2+12+24+4=43
    
    #define f(x) ((x)*(x))
    替换结果为:e=( (a+b)*(a+b)*(c+d)*(c+d) )=3*3*10*10=900

    这个才是我们想要的结果!

字符

  • 字符数据的合法形式:
    ‘1‘ 是字符占一个字节,"1"是字符串占两个字节(含有一个结束符号)。
    ‘0‘ 的 ASCII 数值表示为 48,‘a‘ 的 ASCII 数值是 97,‘A‘的 ASCII 数值是 65。
    一般表示单个字符错误的形式:‘65‘ "1"
    字符是可以进行算术运算的,记住:‘0‘-0=48

  • 大写字母和小写字母转换的方法:
    ‘A‘+32=‘a‘ 相互之间一般是相差32。
    这个32不用记,要用的时候直接‘a‘-‘A‘,就可以得出转换大小写的数值了。

  • 字符型和整数是近亲:两个具有很大的相似之处
    char a = 65 ;
    printf(“%c”, a); 得到的输出结果:a
    printf(“%d”, A); 得到的输出结果:65

转义字符

转义字符分为一般转义字符、八进制转义字符、十六进制转义字符。

  • 一般转义字符:背诵、 、 ’、 ”、 \。
  • 八进制转义字符‘‘:‘141’ 是合法的, 前导的0是不能写的。
  • 十六进制转义字符‘x‘:’x6d’ 才是合法的,前导的0不能写,并且x是小写。

未完待续

以上是关于C语言---总结的主要内容,如果未能解决你的问题,请参考以下文章

我的C语言学习进阶之旅解决 Visual Studio 2019 报错:错误 C4996 ‘fscanf‘: This function or variable may be unsafe.(代码片段

VS中添加自定义代码片段——偷懒小技巧

SQL Select 语句的用法

#yyds干货盘点#愚公系列2023年02月 .NET/C#知识点-程序运行计时的总结

C语言100个经典算法源码片段

需要示例代码片段帮助