---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------
一、 函数:
1、函数的定义
定义函数的目的:将一个常用的功能封装起来,方便以后调用;
定义函数的步骤:函数名,函数体(函数是干什么用的,里面包含了什么代码);
函数的定义格式:
返回值类型 函数名(形参)
{
函数体
}
2、函数需要明确的东西
a、 取一个有意义的函数名;
b、确定函数的形参个数(是否需要传参,多少个参数);
c、 确定函数的返回值(函数执行完毕后,是否需要返回值给调用者);
3、形参和实参
形参(形式参数):定义函数时函数名后面的参数;用于接收外界传递的值;
实参(实际参数):调用函数时传入的具体的数据;
注意:
a、实参个数必须与形参个数相等;
b、函数体内部不能定义和形参一样的变量;
c、如果是基本数据类型作为函数形参,纯粹是值传递,修改函数内部形参的值,并不影响外面实参的值;
d、一个函数可以没有形参,也可以有无限多个形参;
4、return的作用
a、退出函数;
b、返回一个具体值给函数调用者;
void类型:该类型的函数没有返回值;可以多次返回return,也可以省略return。
返回值注意点:
a、 void代表没有返回值;
b、如果没有明确说明返回值类型,默认是int类型;
c、 就算明确声明了返回值类型,也可以不返回任何值;
d、默认情况下,C语言不允许两个函数的名称一样。
5、函数的使用注意
a、 默认情况下,C语言不允许有函数的名称一样;
b、不能嵌套定义函数;
c、 函数不能重复定义,但可以重复声明;
d、如果有函数的声明,没有函数的定义:
(a)、编译可以通过,因为编译只会检测语法是否合理,并不会检测函数有没有定义;
(b)、链接报错,因为链接的时候会检测函数是否定义。
#include <stdio.h>
void sum( int a,int b);
int main()
{
//void sum(int a,int b);//函数声明可以写在main()里,只要在调用之前就可以。
sum(10,12);
return 0;
}
void sum( int a,int b)
{
int sum = a +b;
printf(“%d+%d=%d\n”,a,b,sum);
return;
}
6、include的作用:
a、拷贝右边文件的所有内容到 #include所在的位置;
b、自定义的文件用””,系统自带的文件用<>;
c、#include <stdio.h>的目的:拷贝printf()等函数的声明;
7、多文件开发
张三.c
#include <stdio.h>
#include “李四.h”
int main()
{
inta=10,b=12;
int c= average(a,b);
printf(“平均分是%d\n”,c);
return0;
}
李四.c
int average( int a, int b)
{
return(a+b)/2;
}
李四.h
int average( int a, int b);
cc –c张三.c 通过生成张三.o (这里只有main()函数,没有average()函数),
cc张三.o 报错;
cc –c李四.c 通过生成李四.o (这里只有average ()函数,没有main ()函数),
cc李四.o报错;
将两者翻译文件合并,生成可执行文件:
cc张三.o李四.o;生成执行文件。
链接:把项目中所有相关联的.o目标文件、c语言函数库合并在一起,生成可执行文件。
注意:
a、 函数的定义放.c文件中,函数的声明放.h文件中;
b、如果要使用某个.c文件中定义的函数,只需要#include这个.c文件对应的.h文件;
c、 .h文件的作用:被别人拷贝;编译链接的时候不需要管.h文件。
8、main(),printf()
main()中return返回值:0代表正常退出,其他是异常退出,但对程序无影响;
printf()函数返回值:返回的是字符串的字节长度,函数返回的是字符串常量的字符数,而不是字数(一个汉字占据3个字符);
二、内存剖析
(一)、进制
1、定义:是一种计数的方式,数值的表示形式;
2、常用的4中进制:
二进制 以0b/0B开头 如 int num1=0b11001;
八进制 以0开头 如 int num2=015;
十进制 如 int num3=130;
十六进制 以0x/0X开头 如 int num4=0x12d;
3、输出格式符
%d:以带符号的十进制形式输出整数(但正数不输出正号+);
%o:以不带符号的八进制形式输出整数;
%x:以不带符号的十六进制形式输出整数;
%u:以不带符号的十进制形式输出整数;
%c:输出一个字符;
%s:输出一个或多个字符;
%f:以小数形式输出单、双精度数,默认输出6位小数;
%e:以标准指数形式输出单、双精度数,数字部分小数位数为6位;
4、
a、二进制转十进制
0b1100=1*2的3次方+1*2的3次方+0*2的1次方+0*2的0次方=12
b、十进制转二进制
56=32+16+8=2的5次方+2的4次方+2的3次方=0b111000
c、n位二进制的取值范围: 0 ~ 2的n次方-1。
(二)、变量的内存分析
1、内存是由大到小寻址,只存储二进制形式。
数值在内存中的存储:例: 12是0000 0000 0000 0000 0000 0000 0000 1100
负值在内存中的存储:例:-12是1111 1111 1111 1111 1111 1111 1111 0100
最前位是符号位,是0则为正数,是1则为负数。
负数的存储涉及到了原码、反码、补码。
基本数据类型的取值范围:
int 4个字节 32bit -2的31次方~ 2的31次方-1最高位来确认正负;
char 1个字节 8bit -2的7次方~ 2的7次方-1;
(三)、类型说明符
1、short 2个字节 %d输出
short== short int;short a=1和short int a=1;是相同的;
2、long 8个字节(扩充整型数据,扩充为8个字节) %ld输出
long== long int;一般有l来修饰说明是long类型;
如 long int a =29838742987489l;
long long 8个字节 %lld输出
longlong == long long int;一般有ll来修饰说明是long long类型;
如 long long int a =29838742987489ll;
3、signed 代表有符号,最高位是符号位,-2的31次方~ 2的31次方-1;%d输出;
4、unsigned 代表无符号,最高位不是符号位,0 ~ 2的32次方-1;%u输出;
signed和unsigned都是4个字节,signed和int是一样的,unsigned的最高位不要当做符号位。
long unsigned int a =23894234;
(四)、位运算
1、&按位与:只有对应的两个二进位均为1时,结果位才为1,否则为0。
12&5结果是4;
1100
0101 =>0100是4的二进制。
作用:可以精确的获取某一个精确位;
使用位与&运算符变量的奇偶性:
a&1 == 1; //a为奇数
a&1 == 0; //a为偶数
2、|按位或:只要对应的二个二进位有一个为1时,结果位就为1,否则为0。
12|5结果是13
1100
0101 =>1101是13的二进制。
3、^按位异或:当对应的二进位相异(不相同)时,结果为1,否则为0。
12^5结果是9
1100
0101 =>1001是9的二进制。
规律:
a、 相同整数相^的结果是0;5^5==0;
b、多个整数相^的结果跟顺序无关;5^6^7==5^7^6
c、 任何数值和0进行^,结果还是原来的数值;5^0==5
d、a^b^a==b;
不引入其他变量的情况下,使用异或^运算符实现两个变量值的互换:
#include <stdio.h>
int main()
{
int a =10,b=12;
a=a^b;
b=a^b;
a=a^b;
printf(“a=%d,b=%d\n”,a,b)
return 0;
}
4、~按位取反
~0000 0000 0000 0000 00000000 0000 1001
1111 1111 1111 1111 1111 1111 1111 0110
printf(“%d\n”,~9);输出的是-10;
5、<<左移
a << n => a * 2的n次方;
把整数a的各二进位全部左移n位,高位丢弃,低位补0。左移n位其实就是乘以2的n次方;
由于左移是丢弃最高位,0补最低位,所以符号位也会被丢弃,左移出来的结果值可能会改变正负性;
6、>>右移
a >> n => a /2的n次方;
把整数a的各二进位全部右移n位,保持符号位不变。右移n位其实就是除以2的n次方;为正数时,符号位为0,最高位补0;为负数时,符号位为1,最高位是补1;
编写一个函数,用来输出整数在内存中的二进制形式:
void printBinary(intnumber)
{
//记录现在挪到第几位
int temp = (sizeof(number)<<3) - 1;//相当于sizeof(number) * 8- 1
while (temp >= 0) {
int value = number >> temp &1;
printf("%d",value);
if( temp % 4 == 0)
{
printf(" ");
}
temp--;
}
printf("\n");
}
(五)、char类型
1、字符的存储是参照ASCII码表转成数值然后将二进制存入内存;
char c= ‘A’存在内存中是占1个字节存入的形式是0100 0001;
大写字母与小写字母差值固定32;’A’是65,’a’是97;
2、int num=6;存入内存为6的二进制:0000 0000 00000000 0000 0000 0000 0110;
char a = ‘6’;存入内存为’6’的ASCII码值:是54的二进制:00110110;
3、注意
单引号只能括住单字节的字符。
错误的写法:char c = A;char c = "A";char c = 'ABCD';char c = '男';
正确的写法:char c= ‘A’; char c = 65;
#include <stdio.h>
int main()
{
char c = ‘A’;
switch(c)
{
case ‘A’ : printf(“1\n”);break;
case ‘B’ : printf(“2\n”);break;
//case 65 : printf(“3\n”);break;//这个和case ‘A’是重复的,都写会报错
default: printf(“4\n”);break;
}
return 0;
}
4、当做整型使用:在-128~127范围内,可以当做整数来用
5、转义字符 \
\n 回车换行 10;
\t TAB 9;
\\ 一个反斜线字符 92;
\' 一个单引号字符 39;
\” 一个双引号字符 34;
\0 空字符 0;
小写转大写:
#include <stdio.h>
int main()
{
char upper(char);
char c = upper(‘A’);
printf(“%c\n”,c);
return 0;
}
char upper(char c)
{
if(c>= ‘a’ && c<=’z’)
{
returnc – (‘a’ - ‘A’);
}
return c;
}
---------------------- ASP.Net+Unity开发、.Net培训、期待与您交流! ----------------------