黑马程序员————C语言基础语法三(函数、进制、变量内存解析、类型说明符、位运算)

第一讲  函数

一、  什么是函数

  • 任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,你可以说C语言程序是由函数构成的。
  • 比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:

       

二、函数的定义

1)定义函数的目的

  • 将一个常用的功能封装起来,方便以后调用

 

2)定义函数的步骤

  • 函数名:函数叫什么名字
  • 函数体:函数是干啥的,里面包含了什么代码

 

3)格式

  • 固定格式(很多语言的函数都是这么写的)

返回值类型函数名(形式参数列表)

{

        函数体

}

  • 举例
 1 //定义一个函数,计算两个整数的和
 2 
 3 int sum(int a, int b)  //函数的返回值类型为 int
 4  
 5 {
 6           int c = a + b;
 7 
 8           return c ;  
 9          
10 }

 

三、函数调用

1 int main()
2 {
3     int a = 10;
4     int b = 11;// 定义两个实参,传递给 sum函数
5     int d = sum(a,b); //定义一个变量d来接受函数的返回值
6     return 0 ;   
7     //return 退出函数并 返回一个具体值给函数调用者
8 }

 

四、函数的参数

 参数注意点:

  1. 定义函数时函数名后面中的参数,简称形参
  2. 调用函数式传入的具体数据,简称实参
  3. 实参个数必须等于形参个数
  4. 函数体内部不能定义和形参一样的变量
  5. 参数的传递是值传递
  6. 参数名不能跟函数内的局部变量同名
  7. 一个函数可以没有形参,也可以有无限多个形参
1 int sum(int num1, int num2) //num1 、num2  是形参
2 {
3     // 函数体内部不能定义和形参一样的变量
4     // int num1;  
5 
6      num1 = 50;
7 
8     return num1 + num2;
9 }

 

五、函数的返回值

return的特点

1)退出函数

2)返回一个具体值给函数调用者

3)可以多次使用return

 

返回值的注意点

1)void代表没有返回值,可以省略return
2)如果没有明确说明返回值类型,默认是返回int类型
3)就算明确声明了返回值类型,也可以不返回任何值

 

六、函数的注意点

  • 不能嵌套定义函数
  • 死循环调用,自己调用自己
  • 不能重复定义、可以重复声明
 1 void printLine();
 2 void printLine();  //可以重复声明
 3 
 4 int main()
 5 {
 6     void printLine(); // 在主函数内也可以声明
 7     
 8     printLine();
 9     return 0;
10 }
11 
12 // 函数的定义
13 
14 void printLine()
15 {
16     printf("--------\n");
17 
18     //void Sumawithb(); 函数不能嵌套定义
19 }

 

七、函数的补充

1.main函数

  • 返回值:0,正常退出;1,异常退出

2.printf函数

  • 调用<stdio.h>头文件
  • printf函数的返回值:字符串的长度

 

 

第二讲   进制、变量内存解析

一、进制

1. 什么是进制

  • 是一种计数的方式,数值的表示形式
  • 常用的进制:十进制、二进制、八进制、十六进制

2.二进制

1)特点:只有0和1,逢2进1

2)书写格式:0b或者0b开头

3)使用场合:二进制指令\二进制文件,变量在内存中就是二进制存储

4)二进制和十进制的互相转换

5)n为二进制位所能表示的数据范围(不考虑负数):0~2的n次方-1

1 //二进制转十进制
2  0b1100 = 0 * 2的0次方 + 0 * 2的1次方 + 1 * 2的2次方+ 1 * 2的3次方
3               = 0 + 0 + 4 + 8
4               = 12            
5 //十进制转二进制
6  67 = 64 + 2 + 1 = 2的6次方 + 2的1次方 + 2的0次方
7       = 0b1000000 + 0b10 + 0b1
8       = 0b1000011

 

3.八进制

1)特点:0~7,逢八进一

2)书写格式:0开头

4.十六进制

1)特点:0~F,逢十六进一

2)书写格式:0x或者0X开头

 

5.printf函数以不同进制形式输出格式符

 

二、变量内存解析

1.字节和地址

为了更好地理解变量在内存中的存储细节,先得了解内存中的“字节”和“地址”。

1)内存以“字节为单位”

2)不同类型占用的字节是不一样的

 

2.变量的存储

1)所占用字节数跟类型有关,也跟编译器环境有关

2)变量实例

int number = 12;

int number2 = 13;

  • 内存由大到小寻址
  • 只存储二进制形式
  • 每个变量都有地址:第一个字节的地址就是变量的地址

     

3)查看内存地址的两种方式:%x和%p

1  int a =10;
2  printf("%p",&a);  //输出变量a的内存地址
3 // printf("%x",&a);这种方式也可以

 

 

第三讲  类型说明符

1. short和long

1)short和long可以提供不同长度的整型数,也就是可以改变整型数的取值范围。在64bit编译器环境下,int占用4个字节(32bit),取值范围是-231~231-1;short占用2个字节(16bit),取值范围是-215~215-1;long占用8个字节(64bit),取值范围是-263~263-1

2)在64位编译器环境下,short占2个字节(16位),int占4个字节(32位),long占8个字节(64位)。因此,如果使用的整数不是很大的话,可以使用short代替int,这样的话,更节省内存开销。

3)世界上的编译器林林总总,不同编译器环境下,int、short、long的取值范围和占用的长度又是不一样的。比如在16bit编译器环境下,long只占用4个字节。不过幸运的是,ANSI \ ISO制定了以下规则:

  • short跟int至少为16位(2字节)
  • long至少为32位(4字节)
  • short的长度不能大于int,int的长度不能大于long
  • char一定为为8位(1字节),毕竟char是我们编程能用的最小数据类型

4)可以连续使用2个long,也就是long long。一般来说,long long的范围是不小于long的,比如在32bit编译器环境下,long long占用8个字节,long占用4个字节。不过在64bit编译器环境下,long long跟long是一样的,都占用8个字节。

5)还有一点要明确的是:short int等价于short,long int等价于long,long long int等价于long long

 1      // long == long int    long 8个字节  输出格式符 %ld
 2     long int a = 100645654654645645l;
 3     long a2 = 100645654654645645l; // 一般以l 结尾
 4     
 5     // long long int == long long   long long 8个字节  输出格式符%lld
 6     long long int c = 100645654654645645ll;  //一般ll结尾
 7     long long c2 = 4535435435435ll;
 8     
 9     // short == short int       short 2个字节 输出格式符 %d
10     short int d = 5454;
11     short d2 = 43434;
12     
13     //printf("%lld\n", c);
14     
15     int s = sizeof(long long int);  // s结果为 8

 

2. signed和unsigned

1)首先要明确的:signed int等价于signed,unsigned int等价于unsigned

2)signed和unsigned的区别就是它们的最高位是否要当做符号位,并不会像short和long那样改变数据的长度,即所占的字节数。

  • signed:表示有符号,也就是说最高位要当做符号位,所以包括正数、负数和0。其实int的最高位本来就是符号位,已经包括了正负数和0了,因此signed和int是一样的,signed等价于signed int,也等价于int。signed的取值范围是-231 ~ 231 - 1
  • unsigned:表示无符号,也就是说最高位并不当做符号位,所以不包括负数。在64bit编译器环境下面,int占用4个字节(32bit),因此unsigned的取值范围是:0000 0000 0000 0000 0000 0000 0000 0000 ~ 1111 1111 1111 1111 1111 1111 1111 1111,也就是0 ~ 232 - 1
 1   /*
 2      signed和unsigned的区别:
 3       signed 最高位要当做符号位
 4      unsigned 最高位不要当做符号位
 5       都不会改变字节长度
 6     */
 7     // signed == signed int
 8     // signed 有符号:正数、0、负数
 9     signed int a = 10;
10     signed a2 = 10;
11     
12     // unsigned int == unsigned
13     // unsigned 无符号:0、正数
14     unsigned int b = 10;
15     unsigned b2 = 10;
16     
17     long unsigned int c = 34343;
18     long unsigned c2 = 423432;
19     
20     short unsigned int d = 4343;
21     short unsigned d2 = 43243;
22     
23     short signed int e = 54354;
24     short signed e2 = 434;

 

 

第四讲  位运算

1.&按位与

1)功能

只有对应的两个二进位均为1时,结果位才为1,否则为0。

2)举例:比如9&5,其实就是1001&101=1,因此9&5=1

3)规律

  • 二进制中,与1相&就保持原位,与0相&就为0

 

1     int a = 15;
2     a&1 == 1 // 奇数按位与 1  结果 都为 1
3     a&1 == 0 // 偶数按位与 1  结果 都为 0
4    //利用这个规律可以判断 一个整数的奇偶性

 

2.| 按位或

1)功能

只要对应的二个二进位有一个为1时,结果位就为1,否则为0。

2)举例: 比如9|5,其实就是1001|101=1101,因此9|5=13

 

3.^ 按位异或

1)功能

当对应的二进位相异(不相同)时,结果为1,否则为0。

2)举例: 比如9^5,其实就是1001^101=1100,因此9^5=12

3)规律

  • 相同整数相^的结果是0。比如5^5=0
  • 多个整数相^的结果跟顺序无关。比如5^6^7=5^7^6
  • 因此得出结论:a^b^a = b

 

 1     //交换两个变量的值
 2     int a = 10;
 3     int b = 11;
 4     
 5     /* 借助第三方变量   第一种方式
 6     int temp = a;
 7     a = b;
 8     b = temp;
 9     */
10     
11     /*  第二种方式
12     a = b - a;
13     b = b - a;
14     a = b + a;
15     */
16     
17     // a^b^a == b
18     
19     // a -->  10^11
20     // b -->  10
21     a = a ^ b;
22     b = a ^ b;      //用按位异或运算实现 ,第三种方式
23     a = a ^ b;

 

4.~ 取反

对整数a的各二进位进行取反,符号位也取反(0变1,1变0)

 

1  /*
2     9 按位取反 ~
3      ~0000 0000 0000 0000 0000 0000 0000 1001
4         1111 1111 1111 1111 1111 1111 1111 0110
5      */
6     //     printf("%d\n", ~9); 

 

5.<<左移

  • 把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方
  • 由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性

 

1      9<<1== 18    -> 9 * 2的1次方 
2      9<<2 ==36    -> 9 * 2的2次方 
3    //  9<<n           -> 9 * 2的n次方

 

6.>>右移

  • 把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方
  • 为正数时,符号位为0,最高位补0
  • 为负数时,符号位为1,最高位是补0或是补1 取决于编译系统的规定
1     /*
2      8>>1  -> 8/2 == 4
3      8>>2  -> 8/2的2次方 == 2
4      8>>n  -> 8/2的n次方
5      */

 

posted @ 2015-05-07 17:08  英雄出少年  阅读(221)  评论(0编辑  收藏  举报