一、函数
分为库函数和用户定义函数
面向过程是若干个函数组成
面向对象是由若干个对象组成
1.是否有返回值
2.带参函数和不带参函数
3.库函数
二、库函数介绍
以下库函数转自http://blog.csdn.net/candyliuxj/article/details/4793153
1).输入输出函数(<stdio.h>)
文件打开和关闭:
FILE *fopen(const char *filename, const char *mode);
int fclose(FILE * stream);
字符输入输出:
int fgetc(FILE *fp);
int fputc(int c, FILE *fp);
getc和putc与这两个函数类似,但通过宏定义实现。通常有下面定义:
#define getchar() getc(stdin)
#define putchar(c) putc(c, stdout)
int ungetc(int c, FILE* stream);//把字符 c 退回流 stream
格式化输入输出:
int scanf(const char *format, ...);
int printf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int fprintf(FILE *stream, const char *format, ...);
int sscanf(char *s, const char *format, ...);
int sprintf(char *s, const char *format, ...);
行式输入输出:
char *fgets(char *buffer, int n, FILE *stream);
int fputs(const char *buffer, FILE *stream);
char *gets(char *s);
int puts(const char *s);
直接输入输出:
size_t fread(void *pointer, size_t size, size_t num, FILE *stream);
size_t fwrite(const void *pointer, size_t size, size_t num, FILE *stream);
2)、数学函数(<math.h>)
三角函数:
三角函数 | sin | cos | tan |
反三角函数 | asin | acos | atan |
双曲函数 | sinh | cosh | tanh |
指数和对数函数:
以e为底的指数函数 | exp |
自然对数函数 | log |
以10为底的对数函数 | log10 |
其他函数:
平方根 | sqrt |
绝对值 | fabs |
乘幂,第一个参数作为底,第二个是指数 | double pow(double, double) |
实数的余数,两个参数分别是被除数和除数 | double fmod(double, double) |
注:所有上面未给出类型特征的函数都取一个参数,其参数与返回值都是double类型。
下面函数返回双精度值(包括函数ceil和floor)。在下表里,除其中有特别说明的参数之外,所有函数的其他参数都是double类型。
函数原型 | 意义解释 |
ceil(x) | 求出不小于x的最小整数(返回与这个整数对应的double值) |
floor(x) | 求出不大于x的最大整数(返回与这个整数对应的double值) |
atan2(y, x) | 求出 tan-1(y/x),其值的范围是[-pai,pai] |
ldexp(x, int n) | 求出x*2n |
frexp(x, int *exp) | 把 x分解为 y*2n, 是位于区间 [1/2,1)里的一个小数,作为函数结果返回,整数n 通过指针*exp返回(应提供一个int变量地址)。当x 为0时这两个结果的值都是0 |
modf(x, double *ip) | 把x分解为小数部分和整数部分,小数部分作为函数返回值,整数部分通过指针*ip返回。 |
3)、字符处理函数(<ctype.h>)
见下表:
int isalpha(c) | c是字母字符 |
int isdigit(c) | c是数字字符 |
int isalnum(c) | c是字母或数字字符 |
int isspace(c) | c是空格、制表符、换行符 |
int isupper(c) | c是大写字母 |
int islower(c) | c是小写字母 |
int iscntrl(c) | c是控制字符 |
int isprint(c) | c是可打印字符,包括空格 |
int isgraph(c) | c是可打印字符,不包括空格 |
int isxdigit(c) | c是十六进制数字字符 |
int ispunct(c) | c是标点符号 |
int tolower(int c) | 当c是大写字母时返回对应小写字母,否则返回c本身 |
int toupper(int c) | 当c是小写字母时返回对应大写字母,否则返回c本身 |
注:条件成立时这些函数返回非0值。最后两个转换函数对于非字母参数返回原字符。
4、字符串函数()
4.1)字符串函数
所有字符串函数列在下表里,函数描述采用如下约定:s、t表示 (char *)类型的参数,cs、ct表示(const char*)类型的参数(它们都应表示字符串)。n表示size_t类型的参数(size_t是一个无符号的整数类型),c是整型参数(在函数里转换到char):
函数原型 | 意义解释 |
size_t strlen(cs) | 求出cs的长度 |
char *strcpy(s,ct) | 把ct复制到s。要求s指定足够大的字符数组 |
char *strncpy(s,ct,n) | 把ct里的至多n个字符复制到s。要求s指定一个足够大的字符数组。如果ct里的字符不够n个,就在s里填充空字符。 |
char *strcat(s,ct) | 把ct里的字符复制到s里已有的字符串之后。s应指定一个保存着字符串,而且足够大的字符数组。 |
char *strncat(s,ct,n) | 把ct里的至多n个字符复制到s里已有的字符串之后。s应指定一个保存着字符串,而且足够大的字符数组。 |
int strcmp(cs,ct) | 比较字符串cs和ct的大小,在cs大于、等于、小于ct时分别返回正值、0、负值。 |
int strncmp(cs,ct,n) | 比较字符串cs和ct的大小,至多比较n个字符。在cs大于、等于、小于ct时分别返回正值、0、负值。 |
char *strchr(cs,c) | 在cs中查寻c并返回c第一个出现的位置,用指向这个位置的指针表示。当cs里没有c时返回值NULL |
char *strrchr(cs,c) | 在cs中查寻c并返回c最后一个出现的位置,没有时返回NULL |
size_t strspn(cs,ct) | 由cs起确定一段全由ct里的字符组成的序列,返回其长度 |
size_t strcspn(cs,ct) | 由cs起确定一段全由非ct里的字符组成的序列,返回其长度 |
char *strpbrk(cs,ct) | 在cs里查寻ct里的字符,返回第一个满足条件的字符出现的位置,没有时返回NULL |
char *strstr(cs,ct) | 在cs中查寻串ct(查询子串),返回ct作为cs的子串的第一个出现的位置,ct未出现在cs里时返回NULL |
char *strerror(n) | 返回与错误编号n相关的错误信息串(指向该错误信息串的指针) |
char *strtok(s,ct) | 在s中查寻由ct中的字符作为分隔符而形成的单词 |
5、字符串处理函数
<string.h>还有一组字符数组操作函数(存储区操作函数),名字都以mem开头,以某种高效方式实现。在下面原型中,参数s和t的类型是(void *),cs和ct的类型是(const void *),n的类型是size_t,c的类型是int(转换为unsigned char)。
函数原型 | 意义解释 |
void *memcpy(s,ct,n) | 从ct处复制n个字符到s处,返回s |
void *memmove(s,ct,n) | 从ct处复制n个字符到s处,返回s,这里的两个段允许重叠 |
int memcmp(cs,ct,n) | 比较由cs和ct开始的n个字符,返回值定义同strcmp |
void *memchr(cs,c,n) | 在n个字符的范围内查寻c在cs中的第一次出现,如果找到,返回该位置的指针值,否则返回NULL |
void *memset(s,c,n) | 将s的前n个字符设置为c,返回s
|
6、功能函数<stdlib.h>
随机数函数:
函数原型 | 意义解释 |
int rand(void) | 生成一个0到RAND_MAX的随机整数 |
void srand(unsigned seed) | 用seed为随后的随机数生成设置种子值 |
动态存储分配函数:
函数原型 | 意义解释 |
void *calloc(size_t n, size_t size) | 分配一块存储,其中足以存放n个大小为size的对象,并将所有字节用0字符填充。返回该存储块的地址。不能满足时返回NULL |
void *malloc(size_t size) | 分配一块足以存放大小为size的存储,返回该存储块的地址,不能满足时返回NULL |
void *realloc(void *p, size_t size) | 将p所指存储块调整为大小size,返回新块的地址。如能满足要求,新块的内容与原块一致;不能满足要求时返回NULL,此时原块不变 |
void free(void *p) | 释放以前分配的动态存储块 |
几个整数函数
几个简单的整数函数见下表,div_t和ldiv_t是两个预定义结构类型,用于存放整除时得到的商和余数。div_t类型的成分是int类型的quot和rem,ldiv_t类型的成分是long类型的quot和rem。
函数原型 | 意义解释 |
int abs(int n) | 求整数的绝对值 |
long labs(long n) | 求长整数的绝对值 |
div_t div(int n, int m) | 求n/m,商和余数分别存放到结果结构的对应成员里 |
ldiv_t ldiv(long n, long m) | 同上,参数为长整数 |
数值转换
函数原型 | 意义解释 |
double atof(const char *s) | 由串s构造一个双精度值 |
int atoi(const char *s) | 由串s构造一个整数值 |
long atol(const char *s) | 由串s构造一个长整数值 |
比较两者最大值
<span style="font-size:18px;">#include<stdio.h>
int compareNum(int num1 ,int num2){//形参
//形参只有在调用的时候才会分配空间,调用结束释放内存单元
//被调函数
return num1>num2?num1:num2;
}
int main(intargc,const char* argv[]) {
// insertcode here...
int num1 ,num2;
scanf("%d%d",&num1,&num2);
int max =compareNum(num1,num2);//实参
//此时main主调函数 compare为被调函数
printf("%d和 %d中的最大值是 %d!\n",num1,num2,max);
return 0;
}
</span>
三、函数应用代码练习
1). C6函数传递参数不一致的问题
<span style="font-size:18px;">#include<stdio.h>
int compareNum(int num1 ,int num2){//形参
//形参只有在调用的时候才会分配空间,
//被调函数
return num1 + num2;
}
int main(intargc,const char* argv[]) {
// insertcode here...
int max =compareNum('a','b');//实参// 97 +98
//此时main主调函数 compare为被调函数
printf("max = %d!\n",max);
return 0;
}</span>
2). 实参可以是表达式,整型变量
函数的嵌套使用
函数名不能与变量名重名
Return(x+y+z)/3.0f;
3).函数使用时
1.定义(实现)
2.再调用之前声明(告诉编译器函数已经存在)
注意间接声明的问题。
四.函数难点:递归函数
递归函数很耗资源,内存,所以尽量少用
调用本身的函数
递推阶段:问题规模缩小
回归迭代:迭代计算得到过程
F(n)=f(n-1)+2;
<span style="font-size:18px;">#include <stdio.h>
int countAge (intn){
int age =0;
if (n == 1) {
age = 10;
}
else
age =countAge(n -1) +2;
return age;
}
int main(intargc, const char* argv[]) {
int age =0;
age = countAge(5);
printf("age = %d \n",age);
return 0;
}
</span>
五.递归原理,堆栈操作
压栈操作
出栈操作 (迭代计算)
递归算阶乘
<span style="font-size:18px;">#include <stdio.h>
int fact (intn){
int num =0;
if (n == 1) {
num = 1;
}
else
num =fact(n -1)*n;
return num;
}
int main(intargc, const char* argv[]) {
printf(" %d! = %d\n",5,fact(5));
return 0;
}
</span>
2).求N次方递归
<span style="font-size:18px;">// main.c
// C6求N次方递归
//
// Created by CHINGWEI_MACPC on 15/10/17.
// Copyright © 2015年 itcast. All rights reserved.
//
#include <stdio.h>
int fact (intx,int y){
int result =0;
if (y == 1) {
result = x;
}
else
result =fact(x ,y-1)*x;
return result;
}
int main(intargc, const char* argv[]) {
printf(" %d^%d =%d \n",2,7,fact(2,7));
return 0;
}
</span>
六.Xcode运行原理
编译--->.o(目标文件)-->链接->.out执行
Unix命令
根目录 /
---- i 表示insert
输入内容后按escshitf + :输入wq!表示保存并退出
2).手动编译的方法
include不一定要卸载第一行
实质是把文件的内容插入该位置取代该命令行
/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include
3).清除缓存的方法
七.模块化编程
多文件编程 (比如一个.c和一个.h)
头文件名要和.c文件一样
八.进制问题
1010 = 10
1011= 11
1).进制练习
<span style="font-size:18px;">#include<stdio.h>
int main(intargc,constchar* argv[]) {
int num = 10 ;
printf(" %d的16进制是 %0x\n",num,num);
printf(" %d的八进制是%o\n",num,num);
int b = 0b00000000000000000000000000001101;
printf("0b00000000000000000000000000001101的十进制数是%d\n",b);
//c语言没有提供打印2进制的方法
return 0;
}</span>
余数倒序得到二进制数
7位然后高位补0刚好一个字节
2进制转换为16进制
二进制数四位并为一位16进制数
1.机器数和真值
机器数:计算机中二进制表示形式,计算机最高位存放符号位,正为0,负数为1
真值:机器数对应的真正数值称为机器数的真值
计算机内部是以补码形式储存
正数最高位为0,负数最高位为1
对于正数反码==补码==补码
对于负数反码==除符号位以外的各位取反 补码==反码+1
64位机器
Int类型占用4个字节,每个字节8位
2).进制练习2
// C4计算机存储值的形式
//
// Created by CHINGWEI_MACPC on 15/10/20.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
int main(intargc,constchar* argv[]) {
int b1 = 0b11111111111111111111111111111111;
printf("负数b1 = %d\n",b1);
int b2 = 0b00000000000000000000000000000011;
printf("正数b1 = %d\n",b2);
return 0;
}
负数b1 = -1
正数b1 = 3
3).原码补码概念
计算机没有减法,减一个数等于加一个负数
引入补码概念,
计算机能够做减法,减法的电路设计更简单。
1-1
原码进行计算 1 +(-1)
00000000000000000000000000000001
10000000000000000000000000000001
------------------------------------------------------
10000000000000000000000000000010
想加产生 - 2
1-1
反码进行运算
1+(-1)
000000000000000000000000000000001
111111111111111111111111111111110
---------------------------------------------------------
111111111111111111111111111111111 反码
反码转换为原码
100000000000000000000000000000000 -0数学中没有 -0的概念
1-1
1 +(-1)
补码进行运算
00000000000000000000000000000000(1)
11111111111111111111111111111111 (-1)
------------------------------------------------------
00000000000000000000000000000000 相加补码得0
九.位运算
<span style="font-size:18px;">printf("9 & 4 = %d\n",9&4);//有 0 为 0
printf("9 | 8 = %d\n",9|8);//有 1 为 1
printf("~9 = %d\n",~9);
/*
~9 ;
00000000 00000000 00000000 00001001
~
-------------------------------------
11111111 11111111 11111111 11110110得到补码
10000000 00000000 00000000 00001001 去发得到反码
10000000 00000000 00000000 00001010 得到原码-10
*/
printf("9 ^ 8 = %d\n",9^8);//相同为0不同为 1
//左移右移运算效率高
printf("8 << 2 = %d \n",8<<2);//左移相当于 *2 8乘以2的2次方
printf("8 >> 2 = %d \n",8>>2);//右移相当于 /2 8除以2的2次方
printf("8 << 2 = %d \n",8>>4);//结果为 0
//左移会改变一个数的正负性
printf("-1073741823<< 2 = %d\n",-1073741823<<2);
int b = 0b10000000000000000000000000000110;
/*
右移 0b10100000000000000000000000000001;
取反 0b11011111111111111111111111111110;
加一 0b11011111111111111111111111111111;
有点意外呢
*/
printf(" %d\n",0b11011111111111111111111111111111);
//
printf("-536870909 >> 2 = %d\n",b >>2);
return 0;
</span>
int c = 6 ;
int result = c&1;
printf("%d\n",result);
2).进制练习2
// C3二进制转换程序
//
<span style="font-size:18px;">// Created by CHINGWEI_MACPC on 15/10/20.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
int main(intargc,constchar* argv[]) {
int num = 12 , count = 0;
int num2 =num;
int arr[32];//定义一个数组来存储余数值
while (1) {
if (num2<1) {
break;
}
else{
num = num2%2;
num2 =num2/2;
arr[count]=num;
count++;
printf("%d",num);
}
}
printf("\n");
for (int i=count-1; i>=0; i--) {
printf("%d",arr[i]);
}
printf("\n");
return 0;
}
</span>
老师思路
#include<stdio.h>
//思路:
/*
1.先将需要转换的数字右移
2.每移动一位与 1相 &
*/
<span style="font-size:18px;">int covertTo2(intn ){
int len =sizeof(n)*8;//得到位数
for (int i = 0; i < len; i++) {
int x = n>>(31-i);
printf("%d",x&1);
}
return 0;
}
int main(intargc,constchar* argv[]) {
covertTo2(13);
printf("\n");
return 0;
}
</span>
// main.c
// 判断奇偶性
<span style="font-size:18px;">//
// Created by CHINGWEI_MACPC on 15/10/23.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
void parity(intn ){
if (n&1) {
printf("%d是奇数\n",n);
}
else{
printf("%d是偶数数\n",n);
}
}
int main(intargc,constchar* argv[]) {
parity(5);
return 0;
}</span>
// 交互两个数不定义先变量
<span style="font-size:18px;">//
// Created by CHINGWEI_MACPC on 15/10/23.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
int main(intargc,constchar* argv[]) {
//如果数比较大,可能溢出
int a = 5;
int b = 4;
printf("a = %d , b =%d\n",a,b);
printf("交换后\n");
a = a +b;
b = a -b;
a= a -b;
printf("a = %d , b =%d\n",a,b);
printf("\n");
//方法2异或的方法,相同为0不同为 1
int c = 5;
int d = 4;
printf("c = %d , d =%d\n",c,d);
printf("交换后\n");
c = c^d;
d = c^d;
c= c^d;
printf("c = %d , d =%d\n",c,d);
return 0;
}</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">// 18-获取变量地址
//
// Created by CHINGWEI_MACPC on 15/10/23.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
int main(intargc,constchar* argv[]) {
// insertcode here...
int a = 2 ,b = 3 ;
char ch = 'a';
printf("%p\n",&a);//0x7fff5fbff75c
printf("%p\n",&b);//0x7fff5fbff758
printf("%p\n",&ch);//0x7fff5fbff757
//计算机分配内存原则
//1.从高地址向低地址分配,先定义的变量是高地址,
//2.变量在内存中占用的存储单元中最小的地址值
//2.此地址值为变量的首地址,地址最小的地址15/10/23
return 0;
}</span>
<span style="font-size:18px;">
// main.c
// 查看变量在内存中1每一个字节
//
// Created by CHINGWEI_MACPC on 15/10/23.
// Copyright © 2015年 itcast. All rights reserved.
//
#include<stdio.h>
int main(intargc,constchar* argv[]) {
int num = 266 ;
//0000000000000000 00000000 00001010
char *p =#
printf("第1个字节的地址 :%p, 值 : %d\n",p,*p);
printf("第2个字节的地址 :%p, 值 : %d\n",p+1,*(p+1));
printf("第3个字节的地址 :%p, 值 : %d\n",p+2,*(p+2));
printf("第4个字节的地址 :%p, 值 : %d\n",p+3,*(p+3));
return 0;
}
</span>
<span style="font-size:18px;">
</span>
<span style="font-size:18px;">
</span>