int a
sizeof(a+1.0) 最后输出的字节数应该是8,a是整形,1.0是浮点型
所以sizeof会把其都变为浮点型,不会去做计算
sizeof(指针)计算指针大小的时候,指针一般是4个字节
sizeof()是计算所占空间的;
strlen()是字符串的长度;
库函数-------------------------------------------------------------------------------------------------------------------
memset 函数 是 memset(viod*ptr,int value,size_t num)
是指ptr所指向的空间的前num的位置设置为value这个数
ptr是指空间,num是指空间里的位置,value是在ptr的空间中 所占num个空间的指定的一个值
ptr是要填充的内存块
num是 要被设置(占有)的字节的个数
value是要设置的数
#include<stdio.h>
#include<string.h>
int main()
{
char arr[]="hello world" ; //hello word就是指num
memset(arr,'*',5); //arr是要被填充的 *是要去填充的 5是要填充的字节
printf("%s",arr); //value是个int 所以* 也是个整数 用ascll码来联系
return 0;
}
#include<stdio.h> //strcpy拷贝函数
#include<string.h>
int main()
{
char arr1[]="bit"; //打印时,bit后面有个\0,就是结束语句的意思,所以bit占了三个字节,
char arr2[20]="##########";// 不会出现 bit########的情况
strcpy(arr2,arr1);
printf("%s",arr1);
return 0;
}
自定义函数-------------------------------------------------------------------------------------------------------------
ret_type fun_name (paral,*)
ret_type 返回类型
fun_name 函数名
paral 函数参数
自定义的求和函数
#include<stdio.h> //Add函数
int Add(int x, int y) //Add是函数名 x,y是函数参数(x,y也叫做传参) int是返回类型
{ //{}是函数体
int z=0;
z=x+y;
return z;
}//---------------------------------------
int main()
{
int a=10;
int b=20;
int sum = Add(a,b);
printf("%d",sum);
return 0;
}
自定义的比大小函数
#include<stdio.h>
int get_max(int x,int y)
{ //第一步;写函数名get_max get_max( )
if(x>y) //第二步;定义参数类型 get_max(int a,int b)
return x; //第三步; 返回类型定义 int max=get_max(a,b)
else //这里的return x是指输出的时候就是让max=x
return y;
}
int main()
{
int a=20;
int b=30;
//第一步;写函数名get_max get_max( )
//第二步;传参 get_max(a, b)
//第三步; 返回类型定义 int max=get_max(a,b)
int max=get_max(a, b);
printf("max=%d",max);
return 0;
自定义的交换函数
#include<stdio.h>
void Swap(int *pa,int *pb) //为了接收主函数里的&a &b
{
int tmp=0;
tmp=*pa;
*pa=*pb;
*pb=tmp;
}
int main()
{
int a=10;
int b=20;
Swap(&a,&b);
printf("%d %d",a,b); //把地址传到swap里
return 0;
}
int a,int b和交换函数中所定义的变量 的空间不一样,所储存的地址不一样
所以要用指针
在主函数里面 Swap所传输的是a和b的地址,所以要用指针去进行地址的交换
a和b没有变,但是a和b中的地址变了 a的地址变成了b的地址 b的地址变成了a的地址
地址交换
还有一种说法 当实参传给形参时,形参其实是实参的一份临时拷贝,改变形参不会改变实参
(但是我还是有点不懂) 刚刚稍微懂了一点点,在后面的解释中
isprime自定义函数
isprime是判断是否为素数的函数,是素数输出1,不是素数输出0;int isprime(i),如果i是素数则 int isprime(i)==1;
指针变量
如char*p1=&a;指针变量就是用来存储地址的
函数的参数----------------------------------------------------------------------------------------------------------
函数的参数分为 实际参数 和 形式参数
实际参数是真实传给函数的参数,如常量,变量,表达式,函数 无论是什么形式,都必须有确定的值去传给形式参数
形式参数是指函数括号后面的变量
比如自定义比大小的函数 就是把int main()里面的实际参数,int a和int b传给int get_max(int x,int y)里面的形式参数 int x 和int y
实际参数可以是函数
#include<stdio.h>
int get_max(int x,int y)
{
if(x>y)
return x;
else if(y>x)
return y;
}
int main()
{
int a=10;
int b=20;
max=get_max(100,get_max(a,b));
printf("%d",max);
return 0;
}
像上图中的函数代码,int main()的实参里就有get_max()的函数
#include<stdio.h>
void Swap(int x,int y) //自定义的交换函数
{
int tmp=0;
x=tmp;
y=x;
tmp=y;
}//-----------------------------------------到这里只改变了x,y 对a,b没有影响?
int main()
{
int a=20;
int b=30;
Swap(a,b);
printf("%d %d",a,b);
return 0;
}
这个代码是不能运行的 因为x y 在调用时有了自己的空间,同时也有了和实参一模一样的内容(这里我还是不懂,为什么有了自己的空间就是有了和实参一模一样的内容)
形参和实参分别占用不同的内存块,所以对形参的改变不会影响实参
函数的调用-------------------------------------------------------------------------------------------------------------
函数的调用分为传值调用和传址调用
传值调用:形参和实参分别占用不同的内存块,所以对形参的改变不会影响实参(创建一个副本)
传址调用:是指函数外部创建的变量地址传递到函数参数,让函数外部和函数内部建立真正的联系,让函数内部直接操作函数外部(本身参与运算)
#include<stdio.h>
int fun(int *x, int y){
int tmp=0;
*x = 6;
y = 6;
}
int main()
{
int a = 1 , b = 1 ;
fun(&a,b);
printf("%d %d",a,b);
return 0;
}
看上面的代码,其中一个定义指针变量,而另一个只定义整形,
在主函数中的int a相当于是创建了一个a的文档,而fun ()函数中的int*x相当于是创建了一个关于a的快捷方式,如果a里面的内容改变,那么a的快捷方式里的内容也会发生改变,(因为他们的地址是一样的)所以主函数中的fun函数里的&a是把a的地址传过去了。
而主函数里的b则是相当于创建了一个b的文档,而fun ()函数中的int*y相当于是创建了一个关于b的副本,如果b里面的内容改变,那么b的副本里的内容是不会改变的(因为他们地址不一样)所以主函数中的fun函数里的b只是把数值传过去了,至于后面在fun()的函数里怎么变,是fun()函数的事儿,与主函数无关。
(刚刚才明白return x; 竟然是跳出这个函数,就像是上面的这个函数,
#include<stdio.h>
int fun(int *x, int y){ //int y=1
int tmp=0;
*x = 6;
y = 6;
(如果这里有一个return y;的话,是跳出这个fun()函数直接回到主函数里,然鹅,这和主函数里的b并没有什么太大的关系,这里再怎么return y也是返回的主函数里的b,也就是等于返回fun()函数里的形参,也就是等于1啦)
这里这样说,我觉得我明白了,从昨天晚上一直到现在,终于搞明白了,太不容易了
int main()
{
int a = 1 , b = 1 ;
fun(&a,b);
printf("%d %d",a,b);
return 0;
}
二分查找法(折半查找)------------------------------------------------------------------------------------------------
找一组数组中的其中一个数
#include<stdio.h>
int binary_search(int arr[],int k) //因为传过去的是地址,所以形参中arr
{ //本质上是一个指针去接收地址
int sz=sizeof(arr)/sizeof(arr[0]);//所以这一步就不对了 arr中的1 只占
int left=0; //4个字节,4/4=1;
int right=sz-1;
while(left<=right)
{
int mid=(left+right)/2;//中间元素的下标
if(arr[mid]<k)
{
left=mid+1;
}
else if(arr[mid]>k)
{
right=mid-1;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,10};
int k=7;
int ret=binary_search(arr,k); //这里的arr传到形参里的是数组中第一
if(ret==-1) // 个元素的地址 所以:看上面的注释
{
printf("找不到所找数字");
}
else
{
printf("找到了,数字的下标是%d",k);
}
return 0;
}
上面的这个代码,是不对的。如果进行调试的话会发现,在int binary_search()这个函数里的
int sz=sizeof(arr)/sizeof(arr[0]);这一步会发现,int sz=1 而我们的本意是让他=这个数组中所含有的元素个数。
int sz=1的原因是 主函数中在进行传参时int ret=binary_search(arr,k)中的arr所传递的是数组中的第一个元素的地址,所以形参中的 int binary_search(int arr[],int k)的arr相当于是一个指针,去接收数组中第一个元素的地址。
函数每执行一次,num数就加1 ————————————————————————————
#include<stdio.h>
int Add(int*p)
{
(*p)++; //++的优先级高于* *p是指地址中存放的内容++
return *p;
}
int main()
{
int num=0;
Add(&num);
printf("%d",num);
Add(&num);
printf("%d",num);
Add(&num);
printf("%d",num);
return 0;
}
该函数是要控制int num,这个是要改变函数外部变量,所以要用传址变量。注意:++的优先级高于*,所以*要打括号。而*p是指实参中&num的地址中的内容,num=0;*p也是从0开始的,所以可以改变实质。
#include<stdio.h>
int plus_number(int k)
{
k=k+1;
return k;
}
int main()
{
int num=2;
plus_number(num);
printf("%d",num);
plus_number(num);
printf("%d",num);
plus_number(num);
printf("%d",num);
return 0;
}
至于这个函数为啥不可以 我也不知道,先留着,等回来了问问。(我知道了,不会是最后我返回了k,k的结果一直是实参的拷贝,k一直等于2吧?就像上面那个比大小的题,虽然最后他们也是返回了实参的拷贝,但是根本就不用在里面做运算,实参的值是不需要去改变的。
#include<stdio.h>
int plus_number(int k)
{
int m=k+1; //像第一个函数一样引入一个变量行不行?
return m; //这个是把m的值传给num
}
int main()
{
int num=2;
num= plus_number(num);
printf("%d",num);
num=plus_number(num);
printf("%d",num);
num=plus_number(num);
printf("%d",num);
return 0;
} )
这个地方要让num=函数,返回m,
函数的嵌套——————————————————————————————————-----—
#include<stdio.h>
void one_line()
{
printf("hehe\n");
}
void three_line()
{
int i;
for(i=1;i<=3;i++)
{
one_line();
}
}
int main()
{
three_line();
return 0;
}
函数的链式
#include<stdio.h>
int main()
{
printf("%d",printf("%d",printf("%d",43)));
return 0;
}
结果为4321,因为printf的返回值是打印出的数值的字符串,先打印43,这是两个,所以变成了printf("%d",printf("%d",2));一步步打印出4321。
引用自己写的函数用“ ”,引用库函数用< >,如include “Add”(自定义函数) include<stdio.h>(库函数)
函数的递归
一个函数 调用自身的过程就叫递归,可以把一个大型复杂的问题转化为与原问题相似的规模较小的的问题,减少了程序的代码量(把大事化小)
比如下面是一个简单的递归死循环
#include<stdio.h>
int main()
{
printf("hehe\n");
main();
return 0;
}