C语言复习第二天

分支语句分析

if 语句

if语法

	1、if 语句按条件选择执行语句。
	2、else 总是和最近的if进行匹配。

if中的零值匹配

	1、bool类型应直接出现于条件中,不用进行比较。
	2、if 中与常量的比较最好常量都放在左边。
	3、if中 float不能直接和0值比较,需要定义精度。

switch 语句

switch 语法

  1、switch 语句用于单个条件多个分支的情况。
  2、每个case后面需要加上break,不然会导致分支重叠。
  3、语句中default很有必要加上,以应对特殊情况。

case 的注意点

	1、case 后面匹配的只能是整形常量或者字符常量。
	2、case 语句的排列顺序
					--按字母或数字顺序依次排列
					--正常情况放在前面,异常放在后面
					--deafult只用来处理真正的默认情况。

代码示列:if 和 switch基本的使用:

#include <stdio.h>
void f1(int i)
{
    if( i < 6 )
    {
        printf("Failed!\n");
    }
    else if( (6 <= i) && (i <= 8) )
    {
        printf("Good!\n");
    }
    else
    {
        printf("Perfect!\n");
    }
}
void f2(char i)
{
    switch(i)
    {
        case 'c':
            printf("Compile\n");
            break;
        
        case 'd':
            printf("Debug\n");
            break;
        
        case 'o':
            printf("Object\n");
            break;
            
        case 'r':
            printf("Run\n");
            break;
        
        default:
            printf("Unknown\n");
            break;          
    }
}
int main()
{
    f1(5);
    f1(9);
    f1(7);
    f2('o');
    f2('d');
    f2('e');
    return 0;
}

代码示列:if 和switch 互换使用

#include <stdio.h>
void f1(int i)
{
    switch( i < 6 )
    {
        case 1:
            printf("Failed!\n");
            break;
        
        default:
            switch( (6 <= i) && (i <= 8) )
            {
                case 1:
                    printf("Good!\n");
                    break;
                    
                default:
                    printf("Perfect!\n");
                    break;
            }
            break;
    }
}
void f2(char i)
{
    if( 'c' == i )
    {
        printf("Compile\n");
    }
    else if( 'd' == i )
    {
        printf("Debug\n");
    }
    else if( 'o' == i )
    {
        printf("Object\n");
    }
    else if( 'r' == i )
    {
        printf("Run\n");
    }
    else
    {
        printf("Unknown\n");
    }
int main()
{
    f1(5);
    f1(9);
    f1(7);  
    f2('o');
    f2('d');
    f2('e');
    return 0;
}

循环语句分析

do,while for区别

1、do 语句先执行,后判断,循环最少执行一次。
2、while语句先判断再执行,循环体可能一次都不执行。
3、for语句先判断后执行。

编程示列:

#include <stdio.h>
int f1(int n)
{
    int ret = 0;
    
    if( n > 0 )
    {
        do
        {
            ret += n;
            n--;
        }
        while( n > 0 );
    }    
    return ret;
}

int f2(int n)
{
    int ret = 0;
    
    while( n > 0 )
    {
        ret += n;
        n--;
    }   
   return ret;
}
int f3(int n)
{
    int ret = 0;
    int i = 0; 
    for(i=1; i<=n; i++)
    {
        ret += i;
    }  
    return ret;
}
int main()
{
    printf("%d\n", f1(100));
    printf("%d\n", f2(100));
    printf("%d\n", f3(100));
    
    return 0;
}

break和continue的区别

1、break退出整个循环(跳转到循环体大括号之外)。
2、continue退出本次循环。(跳转到循环体大括号之前,只有循环体能使用)

tips:continue 不能代替break,continue只能用在循环体中,否则会出现
代码示列:
在这里插入图片描述
结果编译错误:
在这里插入图片描述

goto 和void 分析

goto 分析

1、goto为从一个程序段跳到转到另外一个程序段。
2、一般禁用goto.

goto的副作用

1、跳转,破坏程序的顺序话执行。

void 分析

1、void 修饰返回值和参数
2、函数没有返回值,应将其声明为void
3、函数没有参数,应该将其声明为void,如果不写,则示意为任意参数。
4、不存在void 变量

void 指针的含义

1、C语言规定只用相同类型的指针才可以互相赋值
2、void *指针作为左值用于接收"接收"任意类型的指针。
3、void * 指针作为右值使用需要进行强制类型转换。

示列分析:

#include <stdio.h>
void MemSet(void* src, int length, unsigned char n)
{
    unsigned char* p = (unsigned char*)src;
    
    int i = 0;
    
    for(i=0; i<length; i++)
    {
        p[i] = n;
    }
}
int main()
{
    int a[5];
    int i = 0;
    MemSet(a, sizeof(a), 0);
    for(i=0; i<5; i++)
    {
        printf("%d\n", a[i]);
    }    
    return 0;
}

在这里插入图片描述

const 和 volatile分析

const只读变量

1、const修饰的变量是只读,但本质还是变量。
2、const修饰的局部变量在栈上分配内存空间。
3、const修饰的全局变量在全局数据区分配空间。
4、const只在编译期有用,在运行期无用。

tips:
const修饰的变量不是真的常量,只是告诉编译器该变量不能出现赋值符号的左边。

const全局变量的分歧

1、在现在C语言编译器中,修改const全局变量将导致程序崩溃(存入只读存储区,不能修改。)------------gcc
2、标准C语言编译器不会将其存入只读存储区,其值使用一个指向它内存地址的指针仍然可以修改------------bcc。

示列程序:

#include <stdio.h>
const int g_cc = 2;
int main()
{
    const int cc = 1;   
    int* p = (int*)&cc;   
    printf("cc = %d\n", cc);    
    *p = 3;   
    printf("cc = %d\n", cc);   
    p = (int*)&g_cc;    
    printf("g_cc = %d\n", g_cc);    
    *p = 4;    
    printf("g_cc = %d\n", g_cc);
    return 0;
}

结果:修改全局const变量时发生段错误(使用的gcc编译器)。
在这里插入图片描述

const 本质分析

注意:static变量 和 全局变量 都存储在全局数据区,加以const修饰之后就就能修改其值了。
代码示列:

#include <stdio.h>

const int g_array[5] = {0};

void modify(int* p, int v)
{
    *p = v;
}

int main()
{
    int const i = 0;
    const static int j = 0;  
    int const array[5] = {0}; 
    modify((int*)&i, 1);           // ok
    modify((int*)&j, 2);           // error:因为加入static修饰,
    								//其生命周期是全局,存储在全局				//区。所以修改失败。
    modify((int*)&array[0], 3);    // ok
    modify((int*)&g_array[0], 4);  // error   
    printf("i = %d\n", i);
    printf("j = %d\n", j);
    printf("array[0] = %d\n", array[0]);
    printf("g_array[0] = %d\n", g_array[0]);
    return 0;
}

struct 和 union分析

struct 分析

struct 在C语言中可以看作变量的集合

struct的问题
空结构体占用多大的内存?

strcut Ts
{
};
sizeof(struct Ts)=?

这个问题取绝于编译器。
1、gcc编译器编译出来的结果。
在这里插入图片描述
2、vc编译器会报错提示至少应该拥有一个成员。
在这里插入图片描述

结构体和柔性数组

	1、柔性数组即数组大小待定的数组。
	2、C语言可以由结构体产生柔性数组。
	3、C语言中结构体的最后一个元素可以是大小未知的数组。
struct SoftArray
{
	int len;
	int array[];
};
sizeof(struct SoftArray)=?

tips
结果是4字节,SoftArray中的array仅是一个标识符,不占用内存空间。

柔性数组的用法

#include <stdio.h>
#include <stdlib.h>
struct SoftArray
{
  int len;
  int array[];
};
//create a SoftArray
struct SoftArray * create_soft_array(int size)
{
  struct SoftArray *ret =NULL;
  if(size>0)
  {
    ret=(struct SoftArray *)malloc(sizeof(struct SoftArray)+sizeof(int)*size);
    ret->len=size;
  }
  return ret;
}

在这里插入图片描述

union分析

1、C语言中的union在语法上与struct相似
2、union只分配最大成员的内存空间,所有成员共享这个空间。

tips
union的使用受系统大小端的影响:
union实现的方法是内存截断,当使用内存较小的变量时,是直接将高内存地址往后的内存空间截断,所以它的使用受系统大小端的影响。
小端:小地址存放低位
大端:大地址存放地位。
判断系统大小端的做法:两种基本方法:

#include <stdio.h>
//利用union的高位地址截断的特性
int system_mode()
{
  union system
  {
    int i;
    char c;
  };
  
  union system mode;
  mode.i=1;
  return mode.c;
}
//定义一个char*类型的指针指向int 的低地址空间查看内存的值即可判断。
int check_cpu()
{
   int i=1;
   char *c =&i;
   return c[0]==1;
}
int main()
{
  printf(" check_cpu is %d\n",check_cpu());
  printf("system mode is %d\n",system_mode());
  return 0;
}

说明是小端序
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值