C语言笔记

#include <stdio.h>

int main01()
{
	float pai = 3.14;
	int r;//r是圆的半径
	printf("输入半径");
	scanf_s("%d", &r);
	double c, s;//c是周长,s是面积
	c = pai * 2 * r;
	s = pai * r * r;
	printf("周长是%.2lf,面积是%.2lf", c, s);
	return 0;
}

//验证浮点型保留小数时会四舍五入
int main02()
{
	float a = 0.22;
	int b = 3;
	float c;
	c = a * b;
	printf("%.1f", c);
	return 0;
}

//if语句
int main03()
{
	int fenshu;
	printf("输入分数");
	scanf_s("%d", &fenshu);

	//if(表达式)如果表达式为真执行{}里的语句
	if (fenshu > 700)       //if语句的表达式后不用加;
	{
		printf("上清华");
	}
	return 0;
}


//if   else   连用
int main04()
{
	int fenshu;
	printf("输入分数");
	scanf_s("%d", &fenshu);
	if (fenshu > 700)
	{
		printf("上清华");
	}
	else
	{
		printf("上蓝翔");
	}
	return 0;

}




int main05()
{
	int fenshu;
	printf("输入分数");
	scanf_s("%d", &fenshu);
	if (fenshu > 700)
	{
		printf("上清华");
	}
	else if (fenshu > 650)
	{
		printf("上北大");
	}
	else
	{
		printf("上蓝翔");
	}
	return 0;

}





#include <stdio.h>
int main06()
{
	printf("FishC.com no \"fish\" ");
	return 0;
}



//火箭1.0
#include <stdio.h>
int main07()
{
	printf("         @\n        / \\\n        * *\n        * *\n        * *\n    * * * * * *\n  * * * * * * * *\n* * * * * * * * * *\n        * *\n        * *\n      * * * *\n    * * * * * *\n");
	return 0;
}


//火箭2.0
#include <stdio.h>
int main08()
{
	printf("\n\
            @\n\
           / \\\n\
           * *\n\
           * *\n\
           * *\n\
       * * * * * *\n\
     * * * * * * * *\n\
   * * * * * * * * * *\n\
           * *\n\
           * *\n\
	     * * * *\n\
       * * * * * *\n\ ");
	return 0;
}






#include <stdio.h>
int main09()
{
	int a, b;
	b = 3;
	a = b;
	b = b * 2;
	printf("a=%d\n", a);
	printf("b=%d", b);
	return 0;
}




#include <stdio.h>
int main10()
{
	float r, c, s;
	r = 5;
	c = 2 * 3.14 * r;
	s = 3.14 * r * r;
	printf("周长=%.2f,面积=%.2f", c, s);
	return 0;
}





#include <stdio.h>
int main11()
{
	printf("\n\
        打印五个字符 :F i s h C\n\
        前边用 填充 :      2015\n\
        前边用0填充 :0000002015\n\
        右对齐 ,保留两位 :    3.14\n\
        左对齐 , 保留三位 : 3.142\n\
        右对齐 , 指数形式 : 5.200000e+0.5\n\
        左对齐 , 指数形式 : 5.200000E+0.5\n");
	return 0;
}



#include <stdio.h>

#define Pi 3.14159
#define S(r) Pi*r*r
#define C(r) 2*Pi*r

int main12()
{
	int r = 5;
	printf("半径为%d的圆,面积是:%.2f周长是:%.2f",r,S(r),C(r));
	return 0;
}





#include <stdio.h>
#define fanqie 3.7
#define jielan 7
#define xiqin 1.3
#define kongxincai 8
#define yangcong 2.4
#define youcai 9
#define huanggua 6.3
#define bailuobo 0.5

int main13()
{
	float m,h,y ;
	m = (2*fanqie + 1 * kongxincai + 1 * youcai)*0.5;
	h = (3 * xiqin + 0.5 * yangcong + 5 * huanggua)*0.5;
	y = (10 * huanggua + 20 * bailuobo)*0.5;
	printf("小明需支付%.2f\n小红需支付%.2f\n小甲鱼需支付%.2f\n",m,h,y );
	return 0;
}






#include <stdio.h>
#include <math.h>
int main14()
{
	int a,b,c,d,e;
	a=pow(1, 2);
	b = pow(2, 3);
	c = pow(3, 4);
	d = pow(4, 5);
	e = pow(5, 6);
	int total =a + b + c + d + e;
	printf("%d",total);
	return 0;
}





#include <stdio.h>
#include <math.h>
int main15()
{
	unsigned long long sum=0;
	unsigned long long temp;
	unsigned long long weight;
	int i;

	for (i  = 0;  i< 64; i++)
	{
		temp = pow(2, i);
		sum = sum + temp;
	}
	printf("麦子的个数为:%llu", sum);
	return 0;
}





//switch语句
#include <stdio.h>
int main16()
{
	int a;
	scanf_s("%d", &a);

	switch (a)
	{
	case 1:
		printf("输入值1");
		break;
	case 2:
		printf("输入值2");
		break;
	default:
		printf("输入数据未知");
			break;
	}
	return 0;
}








//条件语句嵌套 if语句中再嵌套一个if
#include<stdio.h>
int main17()
{
	int a;
	printf("输入分数");
	scanf_s("%d", &a);
	if (a > 700)
	{
		printf("上清华");
		if (a > 720)
		{
			printf("学挖掘机");
		}
		else if (a > 710)
		{
			printf("学厨师");
		}
		else
		{
			printf("学计算机");
		}
	}
	else if (a > 600)
	{
		printf("上北大");
	}
	else
	{
		printf("上蓝翔");
	}


		return 0;
}


#include <stdio.h>
#include <math.h>
int main18()
{
	unsigned long long a,b;
	printf("输入一个十进制整数");
	scanf_s("%llud", &a);
	b = pow(a, 5);
	printf("输入数字的五次方是:%llud", b);
	return 0;
}



//sizeof运算符 sizeof(变量的名称)   sizeof(变量的类型)
#include <stdio.h>
int main19()
{
	int a;
	char b;
	float c;

	a = 123;
	b = 'k';
	c = 3.14;

	printf("size of int is %zd\n",sizeof(int));
	printf("size of a is %zd\n", sizeof(a));
	printf("size of char is %zd\n",sizeof(char));
	printf("size of b is %zd\n",sizeof(b));
	printf("size of float is %zd\n",sizeof(float));
	printf("size of c is %zd\n",sizeof(c));
	return 0;
}




//signed表示该变量是带符号位的
//unsigned表示该变量是不带符号位的(只能存放正数和零)
//cpu能读懂的最小单位是比特位,bit,b
//内存机构的最小寻址单位是字节,Byte,B
//约定俗成一字节=八比特    每个比特位只能存放二进制单位0和1
//signed类型的存储单元中,左边第一位表示符号位。如果该位为0表示是正数;如果为1是负数
//



#include <stdio.h>
int main20()
{
	float a;
	float b;
	printf("输入华氏度:");
	scanf_s("%f",&a);
	b = (a - 32) * 5 / 9;
	printf("转化为摄氏度是:%.2f",b);
	return 0;
}






#include <stdio.h>
#include <math.h>
int main21()
{
	float a,b,c,s,p;
	printf("输入三条边的长度");
	scanf_s("%f %f %f",&a,&b,&c);
	p = (a + b + c) / 2;
	s = sqrt(p * (p - a) * (p - b) * (p - c));
	if (a + b > c && a + c > b && b + c > a && a - b < c && a - c < b && b - c < a)
	{
		printf("面积是%.2f", s);
	}
	else
	{
		printf("数据输入错误,无法计算");
	}
		return 0;
}






//while    dowhile
//计算1+2+3+4+.....+100



//入口循环
#include <stdio.h>
int main22()
{
	int i = 1 ,sum = 0;//初始化计数器
	while (i <= 100)//循环条件
	{
		sum = sum + i;//更新计数器
		i = i + 1;//更新计数器
	}
	printf("结果为%d", sum);
	return 0;
}






#include <stdio.h>
int main23()
{
	printf("输入一行英文");
	int count = 0;
	while (getchar() != '\n')
	{
		count = count + 1;
	}
	printf("共输入%d个字符",count);
	return 0;
}


//do while后要有一个分号

//出口循环   循环体至少会被执行一次
#include <stdio.h>
int main24()
{
	int i = 1, sum = 0;
	do
	{
		sum = sum + i;
		i = i + 1;
	} while (i <= 100);
	printf("结果为%d", sum);
	return 0;
}



//循环的基本结构   初始化计数器    循环条件    更新计数器




#include <stdio.h>
int main25()
{
	int count = 1;
	for (count = 1; count <= 10; count++)
	{
		printf("test\n");
	}
	return 0;
}



//判断一个数是不是素数
#include<stdio.h>
int main26()
{
	int i, num;
	_Bool flag = 1;
	printf("输入一个数");
	scanf_s("%d", &num);

	for (i = 2; i <= num / 2; i++)
	{
		if (num % i == 0)//%表示num除以i的余数
		{
			flag = 0;
		}
	}
	if (flag)
	{
		printf("%d是素数\n",num);
	}
	else
	{
		printf("%d不是素数\n", num);
	}
	return 0;
}






//for(表达式1;表达式2;表达式3)
//表达式1,表达式2,表达式3可以按照需求进行省略(但分号不能省)





#include <stdio.h>
int main27()
{
	for( ; ; )//一直判断为真,一直循环.



	return 0;
}




//for语句表达式1和表达式3可以是一个简单的表达式,也可以是逗号表达式(即用逗号分隔多个表达式)


#include <stdio.h>
int main28()
{
	int i, j;

	for (i = 0, j = 10; i < j; i++,j--)
	{
		printf("%d\n", i);
	}


	return 0;
}




//c99允许在表达式1中定义变量





//循环嵌套    循环的顺序是先内后外


#include <stdio.h>
int main29()
{
	int i,j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 3; j++)
		{
			printf("i=%d,j=%d\n", i, j);
		}
	}


	return 0;
}








#include <stdio.h>
int main30()
{
	int i, j,result;

	for (i = 1; i < 10; i++)
	{
		for (j = 1; j < 10; j++)
		{
			printf("%d*%d=%-1d\n",i,j,result=i*j);
		}
	}


	return 0;
}


     


//复合赋值运算符
//例如 a=a+1可简化为a+=1
//自增自减运算符
//i=i+1可写成i=i++或i=++i
//i=i-1可写成i=i--或i=--i



//说明i++和++i的区别
#include <stdio.h>
int main31()
{
	int i=5, j;
	j = i++;
	printf("i=%d,j=%d\n",i,j);


	i = 5;
	j = ++i;
	printf("i=%d,j=%d",i,j);


	return 0;
}

//i++是先赋值后自增      ++i是先自增后赋值   自减运算符同理



/*条件运算符
语法:exp1?exp2:exp3;
exp1是条件表达式
如果结果为真,返回exp2
如果结果为假,返回exp3*/



/*if (a>b)
   max = a;
else          可以写成    max= a > b ? a : b            
   max = b;*/




//goto语句
// 语法: goto 标签;

#include <stdio.h>
int main32()
{
	int i = 5;
	while (i++)
	{
		if (i > 10)
		{
			goto A;
		}
	}

A:printf("here,i=%d",i);

	return 0;
}






#include <stdio.h>
int main33()
{
	int i, cost;
	printf("公斤  --  花费\n");
	for (i = 1,cost=23; i < 21; i++,cost+=14)
	{
		printf("  %2d  --    %3d\n", i, cost);
	}






	return 0;
}







/*对于没有预先确定执行
次数的循环(比如根据用户的输入内容决定是否进入下一轮循环),应
该使用 while 语句;对于指定执行次数的循环,for 语句更加合适。*/






//数组    类型 数组名[元素个数]
//访问数组中的数据  数组名[下标]
/*a[0]  访问数组a里的第一个元素
* b[1]  访问数组b里的第二个元素
* c[2]  访问数组c里的第三个元素
*/






//循环和数组的关系
 



#include <stdio.h>
#define NUM 10

int main34()
{
	int s[10];
	int i, sum = 0;

	for (i = 0; i < 10; i++)
	{
		printf(" 输入第%d位同学的成绩",i+1);
		scanf_s("%d", &s[i]);
		sum += s[i];
	}

	printf("平均成绩是%.2f",(double)sum/NUM);


	return 0;
}



/*数组的初始化
将数组中的所有元素初始化为0,可以写成
int a[10]={0};  事实上这里只是将第一个元素赋值为0

如果赋予不同的值,那么用逗号隔开即可
int a[10]={1,2,3,4,5,6,7,8,9,0};

还可以只给一部分元素赋值,未被赋值的元素自动初始化为0
int a[10]={1,2,3,4,5,6};

可以只给出各个元素的值,而不指定数组的长度(编译器会根据值的个数自动判断数组的长度)
int a[]={1,2,3,4,5,6,7,8,9,0};

c99中可以只给某些指定的元素进行初始化赋值,而未被赋值的元素会自动赋值为0
int a[10]={[3]=3,[5]=5,[8]=8};

sizeof(数组名)得到的是数组里数据占内存空间的大小  并不是数组中数据的个数

*/









/*字符数组
定义字符数组 char str[]="hello";
*/



#include <stdio.h>
#include <string.h>

int main35()
{
	char str[] = "one two";

	printf("sizeof str=%d\n", sizeof(str));//sizeof包括最后的\0的结束符
	printf("strlen str=%u\n", strlen(str));//strlen不包括最后的\0的结束符

	return 0;
}


/*字符串复制 strcpy(str1,str2)把str2复制到str1中
*/



#include <stdio.h>
#include <string.h>

int main36()
{
	char str1[] = "test one";
	char str2[] = "test fourA";
	char str3[20];

	strcpy_s(str2, 9,str1);//把str1复制到str2中    中间数字一定要比源字符串数大可以是strlen(str1)+1
	strcpy_s(str3, 16, "copy successful");

	printf("str1:%s\n",str1);
	printf("str2:%s\n", str2);
	printf("str3:%s\n",str3);

	return 0;
}


/*strncpy(受限)字符复制*/

#include <stdio.h>
#include <string.h>

int main37()
{
	char str1[] = "To be or not to be";
	char str2[30];

	strncpy_s(str2,30,str1,5);
	str2[5] = '\0';

	printf("str2:%s",str2);

	return 0;
}




/*strcat  strncat 连接字符串函数*/

#include <stdio.h>
#include <string.h>

int main38()
{
	char str1[100] = "To be ";
	char str2[100] = "or not to be";
	int len;

	len = strlen(str1) + strlen(str2)+1;

	strcat_s(str1,len,str2);
    

	printf("str1:%s\n",str1);

	return 0;
}




/*strcmp strncmp  比较字符串    用于比较两个字符串是否完全一致,若一致返回值为0,若存在差异根据情况返回大于0或小于0的值
原理:从第一个字符开始依次对比两个字符的ASCI码
*/


#include <stdio.h>
#include <string.h>

int main39()
{
	char str1[] = "test";
	char str2[] = "test";

	if (!strcmp(str1, str2))
	{
		printf("两个字符串完全一致");
	}
	else
	{
		printf("两个字符串存在差异");
	}

	return 0;
}


//strncmp 限制只对比前n个字符是否一致



#include <stdio.h>
#include <string.h>

int main40()
{
	char str1[] = "tesk";
	char str2[] = "test";

	if (!strncmp(str1,str2,3))
	{
		printf("两个字符串前3个字符完全一致");
	}
	else
	{
		printf("两个字符串的前三个字符存在差异");
	}

	return 0;
}








//二维数组
/*二维数组的定义
     类型  数组名[常量表达式][常量表达式]
	 int a[6][6]     6行6列
     char b[4][5]    4行5列
	 double c[6][3]  6行3列

	 二维数组的访问
	 数组名[下标][小标]
	 a[0][0]  访问a数组中的第一行第一列元素
	 同样需要注意越界访问的问题


	 注意  二维数组在内存中的存放形式也是线性的
*/


//二维数组的初始化

#include <stdio.h>
int main41()
{
	int a[3][4] = {  1,2,3,4 ,  5, 6, 7, 8 ,  9, 10, 11, 12  };

	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}


	return 0;
}


//为了更加直观可以用大括号将同一行的数据括起来


#include <stdio.h>
int main42()
{
	int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ",a[i][j]);
		}
		printf("\n");
	}
    
	return 0;
}






#include <stdio.h>
int main43()
{
	int a[3][4] = { 
		{1,2,3,4},
		{5,6,7,8},
		{9,10,11,12}//更直观
	};
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}

	return 0;
}







#include <stdio.h>
int main44()
{
	int a[3][4] = { {1},{3} ,{5} };//只给第一个赋值
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}

	return 0;
}







#include <stdio.h>
int main45()
{
	int a[3][4] = {0};//给整个数组赋值为0
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}

	return 0;
}




#include <stdio.h>
int main46()
{
	int a[3][4] = {[0][0]=1,[1][1]=2,[2][2]=3};//给特定的赋值其他的自动赋值为0
	int i, j;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%d ", a[i][j]);
		}
		printf("\n");
	}

	return 0;
}


//排序

#include <stdio.h>
int main47()
{
	int a[5];
	int i, j, t;

	printf("输入5个整数");
	for (i = 0; i < 5; i++)
	{
		scanf_s("%d", &a[i]);
	}


	for (j = 4; j > 0; j--)
	{
		for (i = 0; i < j; i++)
		{
			if (a[i] > a[i + 1])
			{
				t = a[i + 1];
				a[i + 1] = a[i];
				a[i] = t;
			}
		}
	}

	printf("从小到大排序为\n");
	for (i = 0; i < 5; i++)
	{
		printf("%d ", a[i]);
	}

	return 0;
}






//指针
#include <stdio.h>
int main48()
{
	char a = 'f';
	int f = 123;

	char *pa = &a;
	int* pb = &f;

	printf("a=%c\n",*pa);
	printf("f=%d\n",*pb);

	*pa = 'c';//这里的*不是定义指针,而是访问指针指向的地址中存放的数据
	*pb += 1;

	printf("now,a=%c\n", *pa);
	printf("now,f=%d\n", *pb);

	printf("sizeof pa=%d\n", sizeof(pa));
	printf("sizeof pb=%d\n", sizeof(pb));

	printf("the addr of a is:%p", pa);
	printf("the addr of b is:%p", pb);

	return 0;
}
//注意要避免访问未初始化的指针




//指针和数组
#include <stdio.h>
int main49()
{
	int a;
	int* p = &a;

	printf("输入一个整数");
	scanf_s("%d", &a);
	printf("a=%d\n", a);

	printf("重新输入一个整数");
	scanf_s("%d", p);//scnf_s函数加&就是为了获取&后变量的地址从而改变变量a对应的地址中存放的数据,又因为p中存放的本来就是a的地址,所以不用加&
	printf("a=%d", a);

	return 0;
}






#include <stdio.h>
int main50()
{
	char str[128];

	printf("输入abcdefg");
	scanf_s("%s", str,128);//str和指针一样在scnf_s后没有加&   说明str这个数组可能其实是一个地址

	printf("输入的字符是:%s", str);

	printf("str的地址是:%p\n", str);
	printf("str的地址是:%p\n", &str[0]);//两行打印的结果相同说明数组名其实就是数组第一个元素的地址

	return 0;
}


//结论:数组名是数组第一个元素的地址,本质上是一个地址,在scanf_s函数中不用加&

#include <stdio.h>
int main51()
{
	char a[] = "sun";
	int b[5] = { 1,2,3,4,5 };
	float c[5] = { 1.1,2.2,3.3,4.4,5.5 };
	double d[5] = { 1.1,2.2,3.3,4.4,5.5 };

	printf("a[0]->%p,a[1]->%p,a[2]->%p\n", &a[0], &a[1], &a[2]);
	printf("b[0]->%p,b[1]->%p,b[2]->%p\n", &b[0], &b[1], &b[2]);
	printf("c[0]->%p,c[1]->%p,c[2]->%p\n", &c[0], &c[1], &c[2]);
	printf("d[0]->%p,d[1]->%p,d[2]->%p\n", &d[0], &d[1], &d[2]);

	return 0;
}









/*用指针指向一个数组
char a[];
char *p;
p=a;
p=&a[0]
*/



//指针的运算
/*当指针指向数组元素的时候,我们可以对指针变量进行加减运算,这样做的意义相当于指向距离指针所在位置向前或向后第n个元素*/



#include <stdio.h>
int main52()
{
	char a[] = "sun";
	int b[5] = { 1,2,3,4,5 };
	float c[5] = { 1.1,2.2,3.3,4.4,5.5 };
	double d[5] = { 1.1,2.2,3.3,4.4,5.5 };

	char* p = a;

	printf("*p=%c,*(p+1)=%c,*(p+2)=%c\n", *p, *(p + 1), *(p + 2));

	return 0;
}




//需要强调的是:p+1并不是简单的将地址加1,而是指向数组的下一个元素

#include <stdio.h>
int main53()
{
	char a[] = "sun";
	int b[5] = { 1,2,3,4,5 };
	float c[5] = { 1.1,2.2,3.3,4.4,5.5 };
	double d[5] = { 1.1,2.2,3.3,4.4,5.5 };

	int* p = b;

	printf("*p=%d,*(p+1)=%d,*(p+2)=%d\n", *p, *(p + 1), *(p + 2));//因为int定义了整形变量所以这里的加1相当于加4


	return 0;
}



//可以直接用数组名运用指针法,不用定义指针
#include <stdio.h>
int main54()
{
	char a[] = "sun";
	int b[5] = { 1,2,3,4,5 };
	float c[5] = { 1.1,2.2,3.3,4.4,5.5 };
	double d[5] = { 1.1,2.2,3.3,4.4,5.5 };

	printf("*b=%d,*(b+1)=%d,*(b+2)=%d\n", *b, *(b + 1), *(b + 2));

	return 0;
}




//还可以对指针用下标法
#include <stdio.h>
#include <string.h>
int main55()
{
	char* str = "sun cheng kun";    //这里定义一个指针指向的不是数组是一个字符串,后面用下标法访问
	int i, length;

	length = strlen(str);

	for (i = 0; i < length; i++)
	{
		printf("%c", str[i]);
	}
	printf("\n");

	return 0;
}



//指针和数组只是关系比较密切,并不是相同的


/*
#include <stdio.h>
int main()
{
	char str[] = "to be or not to be";
	int count=0;

	while (*str++ != '\0')
	{
		count++;
	}

	printf("共有%d个字符", count);

	return 0;
}
*/


//左值lvalue指用于识别或者定位一个存储位置的标识符(注意:左值同时还必须是可改变的)       str这个数组名是不可改变的
#include <stdio.h>
int main56()
{
	char str[] = "to be or not to be";
	int count = 0;
	char* p = str;

	while (*p++ != '\0')
	{
		count++;
	}

	printf("共有%d个字符", count);

	return 0;
}

//由此可见指针和数组虽然都指向一个地址但是数组名是一个地址常量不可改变不是一个左值而指针可变是一个左值




//指针数组和数组指针
/*      int *p1[5];       int (*p2)[5];    
*        指针数组           数组指针
*/



//指针数组是数组    每个数组元素存放一个指针变量


#include <stdio.h>
int main57()
{
	int a = 1, b = 2, c = 3, d = 4, e = 5;
	int* p1[5] = { &a,&b,&c,&d,&e };
	int i=0;

	for (i = 0; i < 5; i++)
	{
		printf("%d\n", *p1[i]);
	}



	return 0;
}







#include <stdio.h>
int main58()
{
	char* p1[4] = {
		"云想衣裳花想容",
		"春风扶槛露华浓",
		"若非群玉山头见",
		"会向瑶台月下逢",
	};
	int i = 0;

	for (i = 0; i < 4; i++)
	{
		printf("%s\n", p1[i]);//%s后只能跟地址加*表达的是字符串所以不加*
	}


	return 0;
}




//数组指针
//数组指针是一个指针  指向的是一个数组

#include <stdio.h>
int main59()
{
	int temp[5] = { 1,2,3,4,5 };
	int(*p2)[5] = temp;       //  如果不加&并不是指向的整个数组的地址,而是指向了数组的第一个元素的地址              此句表示将temp的地址赋值给p2这个指针
	int i=0;

	for (i = 0; i < 5; i++)
	{
		printf("%d\n", *(*p2 + i));//数组指针存放的是数组每个元素的地址  所以内层的*p2代表取的是temp数组第一个元素的地址  外层的*是从指针所指向的地址中调用数据
	}

	return 0;
}




#include <stdio.h>
int main60()
{
	int array[4][5] = { 0 };

	printf("sizeof int:%d\n", sizeof(int));
	printf("array:%p\n", array);
	printf("array+1:%p", array + 1);

	return 0;
}
//array就是指向包含5个元素的数组的指针


#include <stdio.h>
int main61()
{
	int array[4][5] = { 0 };
	int i, j, k = 0;

	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 5; j++)
		{
			array[i][j] = k;
			k++;
		}
	}


	printf("*(array+1):%p\n", *(array + 1));
	printf("array[1]:%p\n", array[1]);
	printf("&array[1][0]:%p\n", &array[1][0]);
	printf("**(array+1):%d\n", **(array + 1));

	return 0;
}









/*

      *(array+i)=array[i]
	  *(*(array+i)+j)=array[i][j]
	  *(*(*(array+i)+j)+k)=array[i][j][k]
	  
*/



//数组名等效于一个指针    等效并不是等价








//void指针和NULL指针
/*
#include <stdio.h>
int main62()
{
	void a;



	return 0;
}
*/
//void是无类型  会报错

/*void指针是通用指针   可以指向任意类型的数据   
任何类型的指针都可以赋值给void指针
*/



#include <stdio.h>
int main63()
{
	int num = 1024;
	int* pi = &num;
	char* ps = "c++";
	void* pv;

	pv = pi;
	printf("pi:%p,pv:%p\n", pi, pv);

	pv = ps;
	printf("ps:%p,pv=%p\n", ps, pv);

	return 0;
}

//不能对void指针解引用
//void指针转为其他类型时务必要加上强制转换




#include <stdio.h>
int main64()
{
	int num = 1024;
	int* pi = &num;
	char* ps = "c++";
	void* pv;

	pv = pi;
	printf("pi:%p,pv:%p\n", pi, pv);
	printf("*pv:%d\n", *(int*)pv);//(int *)pv是将pv转为int类型的指针本质还是一个指针所以需要外层的*用来解引用

	pv = ps;
	printf("ps:%p,pv=%p\n", ps, pv);
	printf("*pv:%s\n", (char*)pv);//%s后加地址即可而(char*)p就是一个地址

	return 0;
}



//NULL指针
//NULL为空指针 不指向任何东西
//当一个指针不知道指向哪的时候就定义为空指针
//c语言中是不允许对NULL指针解引用的
/*
NULL不是NUL
NULL用于指针和对象表示控制,指向一个不被使用的地址
NUL表示'\0'是字符串的结尾
*/

//指向指针的指针



#include <stdio.h>
int main65()
{
	int num = 520;
	int* p = &num;
	int** pp = &p;

	printf("num:%d\n", num);
	printf("*p:%d\n", *p);
	printf("**p:%d\n", **pp);
	printf("&p:%p,pp:%p\n", &p,pp);
	printf("&num:%p,p:%p,*pp:%p\n", &num, p, *pp);



	return 0;
}



//指针数组和指向指针的指针

#include <stdio.h>
int main66()
{
	char* cBooks[] = {
		"c程序设计语言",
		"c专家编程",
		"c和指针",
		"c陷阱与缺陷",
		"c Primer Plus",
		"带你学c带你飞", };     //指针数组中的元素是指针,所以可以用指向指针的指针

	char** byFishc;
	char** jiayuloves[4];
	int i = 0;

	byFishc = &cBooks[5];
	jiayuloves[0] = &cBooks[0];//依旧是数组名是一个指针,用指向指针的指针指向数组
	jiayuloves[1] = &cBooks[1];//cBooks[1]是一个指针&获取了它的地址赋给jiayuloves[1]
	jiayuloves[2] = &cBooks[2];
	jiayuloves[3] = &cBooks[3];
	
	printf("Fishc出版的书有:%s\n", *byFishc);
	printf("小甲鱼喜欢的书有:\n");

	for (i = 0; i < 4; i++)
	{
		printf("%s\n", *jiayuloves[i]);
	}

	return 0;
}


//数组指针和二维数组
#include <stdio.h>
int main67()
{
	int array[10] = { 0,1,2,3,4,5,6,7,8,9 };
	int* p = &array;
	int i = 0;

	for (i = 0; i < 10; i++)
	{
		printf("%d\n", *(p + i));
	}


	return 0;
}




#include <stdio.h>
int main68()
{
	int array[3][4] = {
		{0,1,2,3},
		{4,5,6,7},
		{8,9,10,11},};
	int(*p)[4] = array;
	int i = 0;
	int j= 0;

	for (i = 0; i < 3; i++)
	{
		for (j = 0; j < 4; j++)
		{
			printf("%2d ", *(*(p + i) + j));
		}
	}


	return 0;




}


//常量和指针
//const关键字将变量变成只读而不可写




#include <stdio.h>
int main69()
{
	const float pi = 3.14;

	printf("%f", pi);

	//pi = 3.1415;会报错,说明const将变量变得和常量有一样的性质




	return 0;
}






//指向常量的指针

#include<stdio.h>
int main70()
{
	int num = 250;
	const int cnum = 880;
	const int* pc = &cnum;

	printf("cnum:%d,&cnum:%p\n", cnum, &cnum);
	printf("*pc:%d,pc:%p\n", *pc, pc);

	pc = &num;
	printf("num:%d,&num:%p\n", num, &num);
	printf("*pc:%d,pc:%p\n", *pc, pc);

	//*pc=1024;会报错    不能用指向常量的指针解引用改变变量的值

	num = 1024;
	printf("num:%d,&num:%p\n", num, &num);
	printf("*pc:%d,pc:%p\n", *pc, pc);

	return 0;
}


/*   指向常量的指针    const int *p
     指针可以修改为指向不同的常量
	 指针可以修改为指向不同的变量
	 可以通过解引用来读取指针指向的数据
	 不可以通过解引用修改指针指向的数据

	 以const int *p定义的指针还可以指向不同的量
*/



//若要让指针不可改变(指向不同的量)需用到常量指针   int* const p = &num;


#include <stdio.h>
int main71()
{
	int num = 250;
	const int cnum = 880;
	int* const p = &num;

	*p = 1024;
	printf("*p:%d", *p);//指针指向的数据可改变

	//p = &cnum; 会报错 因为此时 指针变量 已经转为了 指针常量

	return 0;
}


/*
       指向非常量的常量指针
	     指针自身不可被修改
		 指针指向的值可以被修改

       指向常量的常量指针  
	   指针自身不可被修改
	   指针指向的值也不可被修改
*/





/*#include <stdio.h>
int main()
{
	int num = 250;
	const int cnum = 880;
	const int* const p = &cnum;







	return 0;
}
*/



//指向"指向常量的常量指针"的指针











#include <stdio.h>

int a, b = 520;

void func();

void func()
{
	int b;

	a = 880;
	b = 120;

	printf("in func,a=%d,b=%d", a, b);
}

int main()
{
	printf("in main,a=%d,b=%d", a, b);
	func();
	printf("in main,a=%d,b=%d", a, b);

	return 0;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值