C语言基础之一

1. 一般地源程序文件到可执行程序文件经过如下四步:

预处理 —— 头文件内容插入、宏替换、删注释(#include、#define)

编译 —— 把预处理过的源文件编程汇编文件 .c -> .S *.S文件中已经包含机器码和文件格式等

汇编 —— 把汇编程序编程目标代码 .S -> .o

链接 —— 把.o文件和库文件链接到一起,生成可执行程序 .o + .so -> .out

2. 二进制文件与文本文件

所有文件都采用二进制方式记录数字。

如果文件里的所有二进制内容都对应字符,则这种文件叫做文本文件。

除了文本文件以外的所有文件叫做二进制文件。

文本文件可以当做二进制文件使用。

3. 标识符
第一个单词可以是英文单词或者下划线
后面的字符可以是英文单词、下划线或者阿拉伯数字
大小写敏感
标识符的长度没有限制,但是计算机只会截取前面的一部分使用

标识符的书写方式:

驼峰式——XiAn 下划线方式——xi_an

4. 内存、字节、存储区

程序中的所有数字必须记录在内存中;

扫描二维码关注公众号,回复: 1739452 查看本文章

内存由大量的字节构成,每个字节可以用来记录一个数字,每个字节都有一个编号,不同字节的编号不同。这个编号叫做字节的地址。

内存中所有字节的地址都是从0开始向正数方向增长的;

可以把几个相邻的字节合并成一个整体用来记录一个数字;

一个存储区只能记录一种类型的数字;

存储区也有地址,它的地址是他所包含的所有字节中地址最小的字节的地址;

程序中使用变量代表存储区,程序中对变量的操作就是对它所代表的存储区的操作。

d变量声明语句会让计算机为变量分配存储区。

赋值操作符(=)左边的内容应该可以代表存储区,这种内容叫左值;赋值操作符右边的内容应该可以代表数字,这种内容叫做右值;赋值语句可以把右边的数字放在左边的存储区里。

变量的初始化——在声明变量的时候立即对变量进行赋值。

可以用%p作为占位符把地址数据显示在屏幕上。

5. 数据类型

(1)char

一共包含256(2^8)个不同的整数,每个整数可以代表一个字符。

0 — 127 -128—-1 有符号char

0—255 无符号char

字符和整数之间可以相互替换。

'd' - 'a' == 'D' - 'A' == '3' - '0' == 3 - 0 == 3

转义字符

'\n'        换行
'\r'        回车(让它后面紧挨着的内容出现在本行的最左端,覆盖原有字符)
'\\'        代表字符'\'
'\''        代表字符'''
...         ...
#include <stdio.h>
//将一个小于255的十进制的正整数转换成二进制并打印出来(\r的使用)
void TransToBinary(int Num)
{
        printf("       %d\r", Num%2);
        Num /= 2;
        printf("      %d\r", Num%2);
        Num /= 2;
        printf("     %d\r", Num%2);
        Num /= 2;
        printf("    %d\r", Num%2);
        Num /= 2;
        printf("   %d\r", Num%2);
        Num /= 2;
        printf("  %d\r", Num%2);
        Num /= 2;
        printf(" %d\r", Num%2);
        Num /= 2;
        printf("%d\n", Num%2);
        return;
}
int main(int argc, char **argv)
{
        int num = atoi(*(argv+1));
        TransToBinary(num);
        return 0;
}
[root@localhost 0623]# vim transTobinary.c
[root@localhost 0623]# gcc transTobinary.c
[root@localhost 0623]# ./a.out  10
00001010
[root@localhost 0623]# ./a.out  255
11111111

(2)整数

程序中不带小数点的数字默认是整数类型;

如果在不带小数点的数字后面加上u表示这个数字类型是无符号整数类型。

(3)浮点型

程序中带小数点的数字默认是双精度浮点型;

如果在小数点后面加上f表示这个数字的类型是单精度浮点型。

(4)布尔类型

C99规范中引入了布尔类型。

(5)数据类型和占位符的对应关系

char/unsigned char              %c
short                           %hd
unsigned short                  %hu
long                            %ld
unsigned long                   %lu
int                             %d(十进制)%o(八进制) %x(十六进制)
unsigned int                    %u
float                           %f 或者 %g
double                          %lf 或者 %lg
指针类型保存的地址(*)            %p
char* 保存的字符串                %c  

(6)不同数据类型的存储区在内存里包含的字节个数不同。

char/unsigned char                  1个字节
short/unsigned short                2个字节
int/unsigned int                    4个字节
long/unsigned long                  4个字节
float                               4个字节
double                              8个字节

(7)sizeof

sizeof关键词后面的小括号里面可以写任意能当数字使用的内容。

sizeof小括号里如果修改了任何存储区的内容,这个修改不会真正发生。例如:sizeof(num=10);不会使num的值编程10。

6. scanf 语句

可以在一条语句里获得多个数字并记录到不同的存储区里。例如 scanf("%d %d", &num1, &num2)。

如果用户输入的格式和程序希望的格式不同,程序可能无法再获取后面的数字。

7. 二进制

(1)任何一个数字既可以用十进制方式表示,也可以用二进制方式表示。

(2)非负数二进制与十进制的转换

二进制的非负数 ——> 十进制的非负数
0000 1010 = 2^3 + 2^1 = 8 + 2 = 10
十进制的非负数 ——> 二进制的非负数
除2取余法  示例见上文转义字符

(3)负数的二进制和十进制之间是不能直接转换的,需要借助该负数的相反数(即对应的正数)

转换过程分为三步:
计算相反数
根据相反数进行计算
根据转换结果再计算相反数

把二进制数字中每个数位内容变成相反数字(0/1),然后再加1,就得到了该二进制数的二进制相反数。

有符号类型最左边的二进制数位叫符号位,符号位是0表示非负数,符号位是1表示负数,符号位能帮助我们判断符号,但它并不是符号。

当把占地大的整数赋值给占地小的整数类型存储区时,只能保留最后的二进制数位,这会导致数据丢失;当把占地小的有符号整数类型数字赋值给占地大的整数类型存储时,扩展的所有二进制数位上都填充符号位,这样可以保证符号位不变。

(4)十六进制和八进制都可以看做是二进制的简写方式。
8. 运算符

(1)如果参与除法(/)计算的两个数字都是整数,结果只会保留整数部分。

(2)赋值语句可以当做数字使用,这个数字就是赋值语句完成后存储区里的数字。

(3)可以在一条语句里使用多个赋值操作符,这个时候先计算右边的,后计算左边的。

(4)符合赋值操作符的优先级和赋值操作符的优先级一样低。例如:n* = 2 + 3; 先计算加法,再乘等。

(5)不要在一条语句里对同样一个变量多次进行自增或者自减计算。

(6)“与”(&&)和“或”(||)都具有短路特性

如果前一个逻辑表达式的结果可以决定整个逻辑表达式的结果,则后一个逻辑表达式将被忽略。

0 && num++;       //后面的自加不会运算
1 || num++;       //后面的自加不会运算,num的值不变

(7)位操作符——对二进制数进行操作

~           取法操作符       0变1,1变0
&           按位与           两个位都为1时,结果才为1
|           按位或          两个位都为0时,结果才为0
^           按位异或        两个位相同为0,相异为1
<<          按位左移        各二进位全部左移若干位,高位丢弃,低位补0
>>          按位右移        各二进位全部右移若干位,对无符号数,高位补0

例如,位操作符简单使用

ch ^ 0010 0000              变换大小写
num & 1 == 1                  为真表示num为奇数,否则为偶数
        0000 0011            3
       0000 0011               3 << 2
         0000 1100             12     

左移时右边空出来的位置一定填充0。

有符号类型整数右移后左边空出来的位置一定填充符号位;无符号类型整数右移后左边空出来的位置一定填充0。

一般情况下,数字向左移动n位,相当于乘以2的n次方;数字向右一定n位,相当于除以2的n次方。

所有位操作符不会修改存储区内容,而只会得到一个新数字(类似加减乘除)。

三目操作符中,不要在问号后面写赋值操作符。

#include<stdio.h>
//将一个小于255的十进制的正整数转换成二进制并打印出来(位运算符的使用)
void TransToBinaryByBit(int num)
{
        unsigned char ch = 0x80;
        int i = 0;
        for(i=0; i<7; i++)
        {
                printf("%d", (num & ch) != 0);
                ch >>= 1;
                if(3 == i)
                {
                        printf(" ");
                }
        }
        printf("%d\n", (num & ch) != 0);
}
int main(int argc, char** argv)
{
        int num = atoi(*(argv+1));
        printf("num = %d\n", num);
        TransToBinaryByBit(num);
        return 0;
}
[root@localhost 0624]# vim TransToBinaryByBit.c
[root@localhost 0624]# gcc TransToBinaryByBit.c
[root@localhost 0624]# ./a.out  10
num = 10
0000 1010
[root@localhost 0624]# ./a.out  255
num = 255
1111 1111
9. 类型转换

(1)不同类型的数出现在一条表达式中时,发生强制类型转换。例如:-7 + 3u > 0 的结果是1。

(2)类型转换不会修改任何存储区的内容,计算机会分配一个新的存储区,把转换后的结果记录在新的存储区里。然后用这个新的存储区进行后面的计算。

(3)赋值运算符(=),从右向左执行,例如:num = ch = 300;

(4)逻辑运算符(>、<、==、!=)从左向右执行,例如:3 < 7 < 5; 结果为真,返回1。

10. 流程控制

(1)if分支中的逻辑表达式有先后顺序,如果前分支的逻辑表达式为真,就忽略后面分支的逻辑表达式,可以利用这一点简化后面的逻辑表达式。

(2)if分支里的逻辑表达式可能是不完整的,必须结合前面的所有逻辑表达式一起理解。

(3)如果for循环正常结束,则循环变量一定落在指定的数字范围之外。

(4)如果循环采用break语句结束,则循环结束后循环变量一定落在指定的数字范围之外。

(5)for循环可能不执行大括号里面的语句(一开始循环条件就不成立)。

(6)for循环中,小括号中最前面的部分和最后面的部分可以用逗号连接多条语句,但是中间的语句必须是逻辑表达式。

(7)所有的死循环都必须使用break语句结束。

(8)使用for循环打印图案

54321
5432
543
54
5
#include <stdio.h>
void PrintByFor()
{
        int i = 0;
        for(i=54321; i>=5; i /= 10)
        {
                printf("%d\n", i);
        }
}
int main()
{
        PrintByFor();
        return 0;
}
[root@localhost 0624]# vim PrintByfor.c
[root@localhost 0624]# gcc PrintByfor.c
[root@localhost 0624]# ./a.out
54321
5432
543
54
5

(10)将一个十进制数字转换成二进制

#include <stdio.h>
void TransToBinaryByFor(int num)
{
        unsigned char ch = 0x0;
        for(ch=0x80; ch>=1; ch>>=1)
        {
                printf("%d", (num & ch)!= 0);
                if(ch == 0x10)
                {
                        printf(" ");
                }
        }
        printf("\n");
}
int main(int argc, char** argv)
{
        int num = atoi(*(argv+1));
        TransToBinaryByFor(num);
        return 0;
}
[root@localhost 0624]# vim TransToBinaryByFor.c
[root@localhost 0624]# gcc TransToBinaryByFor.c
[root@localhost 0624]# ./a.out  10
0000 1010

猜你喜欢

转载自www.cnblogs.com/rock-cc/p/9221524.html