码迷,mamicode.com
首页 > 编程语言 > 详细

C语言基础及细节

时间:2018-01-20 22:57:35      阅读:336      评论:0      收藏:0      [点我收藏+]

标签:har   很多   而且   语句   数字   主函数   功能   转义   有符号   

简单来说什么是C语言,就是用c写的语言就是C语言。接下来言归正传。 1.没有注意数据类型存储范围 int main(int argc, char **argv) { char a; a = 1; for (a=0; a<128; a++) printf("#"); return 0; } 你猜是循坏了128,还是死循环呢? 答案是死循环,因为a的类型是有符号char型,它的取值范围为-128-127;当a=127时,a<128,会继续执行,代码执行完之后a会加1,但是a的最大值为127,在加1就会变成最小值-128,为什么会变成-128呢,就是我们平时的时钟,时间为12:59时,再过一分钟就会变成1点,这就简单的说明了为最大值加一会变成最小值,最小值减1就会变成最大值。在计算中数据都是以2进制进行存储的,127在计算机存储时为0x7f,加1,就会变成0x80,因为char中0x80表示最小值-128;所以-128小于128,以此类推,a<128;永远为真。

2.打印类型时,选择正确的格式。
例如 double a = 4.5;
printf("%lf",a);
一定不能使用%f打印,否则会报警告
小结:只要时double ,long类型的数据打印时别忘了加上l
3.显示无符号整数
%u:显示无符号整数
%o:显示无符号八进制
%x:显示无符号16进制
4.各种数据类型的变量与0进行比较正确的书写方式
int a=5;
if (0 == a);

 char ch = ‘a‘;
 if (‘\0‘ == char)

 float f =0.152;
 if ((x>-0.000 001) && (x<0.000 001))

 bool  flag = 1;
 if ( flag )

 int *p = &a;
 if ( NULL == p)

5.转义字符:转移字符是一种特殊的字符常量,转移字符常以反斜线"\"开头
常用的转移字符:
\a:蜂鸣,响铃
\b:回退:向后退一格
\f:换页
\n:换行:光标到下行行首
\r:回车,光标到本行行首
\t:水平制表符
6.调试代码有很多中一般分为printf调试,bug调试等、
我要讲的是用printf调试,这种方式方便简单易操作。
利用FILE,LINE,FUNCTIONDATE,
TIME实现代码跟中
FILE:显示代码的文件名;
FUNCTION:显示调用函数的名称,没有默认为主函数
LINE:显示所在的行数;
TIME:显示时间
DATE:显示日期
7.数据类型的转换
在多种数据类型混合运算时,系统一般自动完成类型转换
转化的规则:存储长度较短的转化成存储长度较长的,并且不丢失
(a)自动转换 :
int a=5; double d = 4.5;
a + d ;结果是double类型的
(b)赋值转换
int a=5; double d = 4.5; char ch;
ch = a + d ;结果是char类型的
(c)强制转换
a = (int ) d + c;
字符型数据赋值给整型变量时,将字符数据放到整型变量存储单元的低八位中
--对于无符号类型,则将字符的8位放到整型变量低八位中,高24位补零
--对于有符号字符类型,若最高位为0,整型变量高24为补0,若字符最高位为1 ,则高24位补1
char 0000 0001 --> 0000 0000 0000 0000 0000 0001
1111 1111 --> 11111 1111 1111 1111 1111 1111
将一个整型数据赋值给一个char类型变量时,直接将其低八位原封不动的送到char型变量(即截断),精度会丢失。
将整型数据赋给浮点型变量时,数值不变,但以浮点型形式存放到变量中精度可能丢失;
将浮点型数据赋给整型数据,直接将浮点型数据存放到int类型存储空间中;
将浮点型赋给double类型数据,直接将30--22位放到double类型62--52中,其他的放到剩下51位中,
将double类型数据赋给float类型,直接将取7位有效数字放到浮点型存储空间中。

8.运算符
运算符是非常常见的,无论你用那种语言写编程都会用到运算符,谈到运算符,就会想到他的优先级,这里我们不讲他的优先级,直降容易出错的地方。
优先级:不是谁的优先级高就先算谁,所谓的优先级就是结合型,谁的优先级高就和谁结合,至于知怎算个的要根据优先级运算顺序,相同的优先级运算顺序时由编译器决定的
(a) ++、 --
a++:就是献给状态值a;然后自行加一
++a; 先自加一,再给a+1的状态结果;
-- a ; a++ 同理
(b) 不要对同一个变量,在一个表达式多次赋值
例如: a = 5;
c = a++ + a++ + a++; //编译器不知道从那边开始算
a = 5;
a = a++;同理
printf("%d %d %d %d %d\n", a++, a++, a++, a++, a++);
你要想这么做,就把a++ 结果赋值给其他变量,用其他变量进行计算
(c) 位移(只能用于整数或者字符型)

                无符号数据类型:右移时左边高位补0;左移时右边补0;
                有符号:正数:右移时,左边补0;左移时右边补0;
                                            负数:右移时,左边补1;左移时,右边补0
                对于正数右移一位相当于除以2,左移1位相当于乘以2;
    (d)逻辑运算符
                &  |  ^
                &  :两者都是1,才为1,否则位0;  功能置零
                |   :两者只有要一个为1,结果为1,否则为0,  功能置一
                ^   :  相同为假,不同为假, 功能取反
                举例: &     A & 1 = A ; A & 0 = 0
                                    |       A  | 1 = 1;     A | 0 = A;
                                        ^       A ^ 1 = ~A ;  A ^ 0 = A;
        (e) 条件运算符:三目运算符
           表达式1 ? 表达式2 : 表达式3
             条件运算符运算有先后顺序的:先算表达式1,若表达式1为真,算表达式2,结束,否则,计算表达式3,算完结束
             例题: a = b=c= 1;
                                    x = a++ ? b++ ?c--:c++:b--?c++:c--;
                                    结果为:a=2;b=2,c=1;
         (f)逗号运算符
                 优先级最低,将两个表达式链接起来,从左往右以此计算、
                 注意:并不是任何地方的出现的逗号都是逗号运算符,例如函数参数,也是用逗号来间隔的

9.scanf和printf函数:
   scanf:
     修饰符   功能
     m   :输ru数据宽度,遇到空格或不可转换字符结束
     *  :抑制符,指定输入项读入后不赋给变量

     输入分割符的指定:
         一般以空格、TAB或回车键作为分隔符
         其他字符作分割符:格式串中两个格式符间字符

例题:scanf("%d,%d,%d",&a,&b,&c);
                输入方式必须以:12,13,14回车
            scanf("%d  ",&a);
            输入 12   12回车才能结束否则不结束   过滤分割符,要输入两次
            scanf("a=%d",&a);
            输入:必须以“a=”开头+数字+回车 结束
            scanf("%*4d",&a);
            输入:132345       a=45;
            scanf("%d%c",&a,&c);
            输入 12回车  就结束了  因为%c会自动读取回车、空隔

             char ch;
             int i;
             for (i=0; i<10; i++)
             {
                     printf("i=%d\n",i);
                     scanf("%c",&ch);
                     printf("%c\n",ch);
                     getchar();  //表示取走回车键,只能取走一次
             }
             %s he %c  遇到空格,回车键就自动停止
             scanf("%[^\n]",&a);//表示不取空格键
             scanf("%[a-z]",&a);//表示只取a-z

    10.switch:
        是一种多路判断语句,他判断表达式置是否与整型或字符常量例表中的某个值相匹配,若找到了相应的匹配,就会执行与常量关联的语句,switch,case,和default都是关键字。语句可以时简单或符合语句。
        switch后面只需要用圆括号括起来,而且switch的主题用{}括起来,计算表达式的数据类型与指定case常量数据类型匹配
        switch后的表达式可以包含任何变量名,也可以时常量
        case后面只能时常量(整型和字符型)
        case后面长量不能为相同,可以不按照顺序,不影响程序结果,但是一般时按照顺序。
        case 后面不加break,则表示找到匹配之后往下执行,如果没有遇到break;会执行到程序结束,
        default:是说明没有匹配的选项进行说明,放到开始位置要加上break,否则会继续执行,放到末尾,就不用加了,执行玩后就结束了
        例如:case 5: 语句 ;break;
                                case 5: 语句;break; //错误,有两个相同的case,因为在匹配中不知道该选则那个,
                                case 1: 语句 ;break;
                                case 7 || 6: 语句;break; //错误7 || 6 返回状态结果为1,与case 1:重复 ,但是你可以这样写 case 6:     case 7: 语句;break;

last :一维数组和二位数组
讲数组,就要集合,什么集合,就是把相同的东西放在一起。对于数组呢?也是一样的,就是把相同的类型的数据放在一起,如果不用一个数组来存放相同数据,用变量来表示,就会显得杂乱无章,没有条例性,时间久了,只有上帝知道,你所定义变量的含义了;接下来正式介绍数组
《存储类型》 《数据类型》 变量名 [元素个数] //数组实际是由 元素数据类型+[元素个数]组成
存储类型:说白了就是你定义了变量存放的位置。(一般默认auto,放在栈中,当代码块执行结束就是放空间,static 为静态类型,放在静态取,用static定义数据存储类型,知道程序结束才释放空间,否则不释放空间,extern声明为全局变量,可以使用其他文件用extern声明的变量,作用范围用于整个函数,register修饰符暗示编译程序相应的变量将频繁的使用,如果可能话应将放在CPU寄存器中,以加快其存储速度)
int a[5]; //a实际可以看成 int [5] ;类型
//数组的大小在编译的时候确定,而变量在运行时才有值
//数组元素个数必须为整型或char类型
初始化:定义同时对变量或数组元素赋值
int a[3] = {1,2,3}; //全部初始化.
char ch[5] = {65,66,67}; //没有初始化的部分自动清0
int be[100] = { [95] =15,} ; //指定元素初始化,没有初始化的部分自动清零
int c[6];
c[2] = 2; //对元素赋值,不会影响其他元素,不对数组初始化,起内存的存放的值是未知的,不对数组进行越界检查,对于越界的元素访问可能造成不可预知的错误;
int cat[9];
cat[2] = 5; //[ ] 数组定义固定格式
2[cat] = 5; //引用变量时,[ ] 时变址运算符 a[i] == (a+i) == (i+a) == i[a];

    数组名的含义:
    #define N 10
    int a[N];
    1.代表整个数组:只有子啊&a,和sizeof(a)
            &a得到的是整个数组地址
            sizeof(a)得到整个数组的字节大小
    2.其他情况数组名代表第一个元素的地址 即 a + 0 == &a[0], sizeof(a+0); 代表第一个数组元素的地址,是一个地址常量,不可以自加,不可以对数组名进行赋值
      a++; //错误
        a = {1,23,5};//错误 
        int a[0]; 表示是一个地址,不能存放数据
    3.数组遍历
       int a[10]= {0};
         int i;
         for (i=0; i<10; i++)
         {
                 printf("%d\n",a[i]);
         }

 4.int a[4] ;//数组在编译时,空间就已经确定了,变量在执行的时候才申请空间赋值

      二维数组:其实是由一维数组组成的,内存存储空间时线性。
            int a[] [5];  //可以省略一维数组的下标;
            初始化:
            int a[5][5]= {15,6,3,9,7,8,2,1,5,4,6};//部分初始化,其他都清0;
            int c[8][9] = { [6][3]=9,};指定元素初始化,先定行,再指定行中的某一个

            二维数组名的含义:
            1.数组名:
                sizeof(数组名) ==>整个数组大小
                    &(数组名)        ==> 整个数组地址
            2.对于二维数组来说。每一个元素都是一个一维数组,数组名中放在第一个一维数组地址&a[0] ,除了上面的情况,都是代表了&a[0]  即 a == &a[0];
            int a[M][N];
    例如:     sizeof(a) ==  4*M*N;
                   sizeof(a[0]) == 4*N;
                                 sizeof(a[0][0]) == 4;

        遍历:
        #define M  4
        #define N 5
        int main(int argc,char **argv)
        {
            int a[M][N]={0};
                int i,j;
                for (i=0; i<M; i++)
              {
                        for (j=0; j<N; j++)
                              printf("%d\t",a[i][j]);
                       printf("\n");
                    }
                    return 0;
                }

C语言基础及细节

标签:har   很多   而且   语句   数字   主函数   功能   转义   有符号   

原文地址:http://blog.51cto.com/13570004/2063234

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!