Linux-c入门基础知识小结

C语言:

1:数据类型  int short char long ....

2:运算符    +  -   *   /   %   +=   ++   --   -+   /=   *=

3:九大控制流语句 
	1 if
	2 for
	3 while
	4 do... while()
	5 break
	6 switch case
	7 continue
	8 return 
	9 go to
3:数组

4:函数

5:指针

6:数组 指针 函数之间的关系

7:宏定义     #define a(x,y)  x>y?x:y;

数据类型

	1、整形数:

		没有小数点的:

		short :有符号短整型  signed short int   2个字节

		int:有符号整形 signed int  4个字节

		最高位为符号为: 0:正数  1:负数

		unsigned int:无符号整形 (一定是正数),取值范围是有符号整形正数范围的两倍

		long: 有符号长整形 signed long int     4个字节

		long long                             8个字节


		有小数点的(浮点数)

			flaot        4个字节  (单精度)

			double       8个字节  (双精度)

		字符型:

				char     1个字节

				char xxx= 'S';

				ascii

		数据类型变量的定义、初始化、赋值


		变量的定义:
				定义一个整形类型的变量a   int a;

				赋值 a                    a = 10;

										  a = 0x00ff0000;

										  a = 011;


		int:可以存放 十进制 %d    十六进制  %x  八进制 %o    二进制




	2、类型转换:
			低精度转成高精度,数据不会丢失
			高精度转成低精度,数据会丢失

			低精度                                                  高精度
			char | short --> int --> long --> long long -->float -->double

			自动转换

					挡在赋值运算或者混合运算时候,会数据类型会自动转换

					赋值运算:等于号右边的类型自动变成等于号左边的类型

					混合运算:低精度自动高精度的类型


			强制转换

					int a =10;

					long b = (long)a;

					printf("%f\n",(float)a);

1)基本数据类型
int short char long double float
(32bit)内存中占用的字节数 4 2 1 4 8 4
(64bit)内存中占用的字节数 4 2 1 8 8 4

采用一个操作符sizeof来进行计算。
#include <stdio.h>

int main(void)
{
	printf("sizeof(int): %d\n", sizeof(int));
	return 0;
}

编写的程序只是人类所能识别的一些操作。
机器只识别二进制编码。
需要将C语言转化为二进制编码,让机器能够识别并完成相应的操作。
编译生成可执行的程序命令:
					gcc hello.c -o hello
		
需要编译器:GCC来完成。
一共4个步骤:预处理、编译、汇编和链接
预处理:展开头文件,将头文件中的信息导入要预处理的文件。
		宏定义的替换。
		条件编译:如果#if 0,则#endif前,#if 0后面的代码不参与编译。
	
编译:将C语言程序编程汇编语言。
汇编:将汇编程序变成机器识别的二进制编码。
链接:将生成的二进制编码链接相应的库生成可执行程序。

执行可执行程序:./hello
gec@ubuntu:/mnt/hgfs/share$ ./hello
One
hello world!
The number is 3
gec@ubuntu:/mnt/hgfs/share$ 

2)变量
变量:存储空间的分配。确定空间的大小和存储的数据类型。
	  这一块空间中存储的数据是可以改变。(存储空间内的数据可变化的量)。
变量的命名规则:以字母,下划线开头,由数字,字母,下划线组成。
变量名保留的规则:《C语言变量名保留关键字》
32个关键字,每个关键字都有不同的含义:
	1)非常见类:auto, register, voliate, goto
	2)存储相关:const, extern,auto
	3)数据类型:int,char,float
	4)逻辑控制:if, else, for, while
	5)特殊用途:sizeof, typedef

int i;
char j;

	1)int类型数据。(存放一些整型的数值)
	2)char类型数据。
		1)存储一些整型的数据。
			1个字节的数据能存储多大的数值?
			1byte = 8bit
			
			0000 0000   -------> 0
			0000 0001   -------> 1
			0000 0010   -------> 2
			……
			1111 1111   -------> 2的8次方-1 =256 --->0~255 
		
		char i = 255;
		printf("i = %d\n", i);
		
		gec@ubuntu:/mnt/hgfs/share$ gcc char.c -o char
		gec@ubuntu:/mnt/hgfs/share$ ./char
		i = -1
		gec@ubuntu:/mnt/hgfs/share$ 
		
		数值的零界问题。--->数据溢出
		进制:二进制,八进制,十进制,十六进制。
		二进制:机器能够识别的进制。(B)只包含0,1
		八进制:0~7。(O)
		十进制:人类看得懂的所有数字数据。(D)0~9
		十六进制:编程经常使用的一种进制。(X)0~9, A~F
		
		原码,反码,补码。
		所有的数据在计算机中都是以补码形式进行存储。
		1)正数:正数的原码,反码,补码一致。
		2)负数:
				负数的原码:255           ----->   1 111 1111(最高位默认为符号位) 
				负数的反码:符号位不变,其它位取反 1 000 0000  (符号位:1  负数  0 正数)
				负数的补码:反码+1       ----->   1 000 0001  ----> -1
				
		2)字符编码:ASCII
			字符:'a' ,  'b'
			字符串:"a", "b"
			"a"与'a'的区别?
				字符:存储1个字节单位的数值。a-->97
				字符'0'~字符'9'ASCII
				字符'A'~字符'Z'ASCII
				字符'a'~字符'z'ASCII
				
				字符串:存储多个字符。
				"a"--->存储2个字节的数据('a' 和 '\0')
		
		3)转义字符
			'\n' --->换行
			'\t' --->tab
			……
				
		
3)修饰类型
	1)有符号与无符号类型。
	int a;(默认是有符号的类型)
	unsigned int a;
	在于取值的范围不同。
	char类型占用1个字节。(0~255)
	char a;(-128~127);
	unsigned char a;(0~255);
	
	原码,反码,补码相关知识点。---->计算机存储数据
	
	2)自动类型(局部变量)和静态类型(全局变量)
	自动类型(局部变量):程序运行的时候占用空间(auto 关键字(系统默认添加,不需要自己填写))
	静态类型(全局变量):程序编译的时候占用空间。
	显示静态变量:static关键修饰的变量-->程序编译的时候占用空间。
			例如:static int a = 100;
	用途;
		局部变量,适合在函数体中重复调用,记录历史数据,提高访问的安全性。
		全局变量:适用于本文件的私有调用(不能够在其他文件中使用这个变量)。
					如果在定义的时候未初始化,系统会自动的初始化为0。
		显示静态变量:运用于函数,使用语本文件的私有保护。
	
	3)寄存器类型(register)
	特点:资源少,运算的速度,无地址(不需要地址操作)
	数据初始化: 关键字 类型 变量名 = 数值。
	例如:register int e = 5;
			
4)运算符
	1)取反(按位):~
	举例:1000 0101 ---> 0111 1010
	练习:十进制数12取反后的数值是多少?
		笔算数值是多少?再用代码进行验证。
	    12   十进制-----> 0000 1100   二进制
               			  ~0000 1100 ---> 1111 0011存储在计算机中。(补码)
						  
			显示数值的时候是以原码来显示的。
			-13 ---> 1000 1101 原码
					 1111 0010 反码
					 1111 0011 补码						
			
			13  ---> 0000 1101 (补码,原码,反码)
			
		练习:	
			进制    原码      反码(~)
			B     0101 0101
			O       0125
			D        85
			X       0x55
	2)自增自减运算符(++,--)
		自加运算符
		1)
		int sn = 1;
		printf("sn = %d\n", sn++);//现赋值,在自加
				
		2)
		int sn = 1;
		printf("sn = %d\n", ++sn);//先自加,在赋值		
			
		自减运算符
		1)
		int sn = 1;
		printf("sn = %d\n", sn--);//现赋值,在自减
				
		2)
		int sn = 1;
		printf("sn = %d\n", --sn);//先自减,在赋值

		错误的编程方式:
			5++;(常量不可自加)
		
	3)取非运算符(逻辑  真与假) !
	计算机对真假的判定:0为假   非零为真
	
	判断一个数是否为真或假:
	int data = 0;
	printf("data = %d\n", !!data);
	
	4)取模或取整运算符(%  /)
	取模运算: 整数%整数
	取整运算: 整数/整数
				123%10 = 12 --- 3
	举例:
			int a, b;
			a = 123%10;
			printf("a= %d\n", a);
			b = 123/10;
			printf("b= %d\n", b);
	练习:
	输入一个大于10000的整数,分别提取出万位,千位,百位,十位,个位的数值。
			
	5)移位运算 << >>
	左移:(最右边的数填零,做左边的数舍去)
		char data = 0x1;   ----> 0000 0001
		data << 1;         ---->  0000 0010
		
	右移:(最右边的位数舍去,最左边的数值符号位补充
		char data = 0x2;   ----> 0000 0010 	
	    data >> 1;         ----> 0000 0010
		
	具体:
		颜色:三原色所构成(RGB--->Red,Green,Blue)
		黄色:R-->255 G--->255, B--->128
		显示BMP格式的图片,1个像素占用3个字节。(每一个字节占用1个比例色素)
		1byte = 8bit
		1个BMP图片的像素 = 3byte = 24bit
		BGR:1000 0000 1111 1111 1111 1111  B
		
			                     0x80ffff  H黄色
			8421码来进行数值的转化:
			1   0  0  0  ---> 0x8
			8   4  2  1
			0000 ~ 1111
			
			二进制      十六进制
			0000  ---->   0
			0001  ---->   1
			0010  ---->   2
			0011  ---->   3
			1000  ---->   8
			1001  ---->   9
			1010  ---->   a
			……				

	0x80ffff << 8,变成 0xffff00
	1000 0000 1111 1111 1111 1111  <<8
       ------>1111 1111 1111 1111 0000 0000
	   ------>0xffff00
	
	6)位操作:与&   或|  异或^
		1)按位与&:当两个数都为真,结果才为真。(清零)
						0100 1010
					&	1010 0111
		        ------------------------
				        0000 0010
						
			按位或|:只要有1个为真,结果就为真。(置1)
								0100 1010
							|	1010 0111
						------------------------
								1110 1111			
	
			异或^:  相同为假,不同为真。
								0100 1010
							^	1010 0111
						------------------------
								1110 1101	
			异或操作一般应用于金融IT领域,对数据进行加密操作的时候。
			加密后的数据 + 密钥  --->原始数据
			原始数据     + 密钥  --->加密后的数据		
	练习:	
		有一个数值为0101 0111,将该数值的第五位清零,并将第六位置1。
		char data = 0x57;
		data = data & ~(0x1<<5);
		       0101 0111
			&  1110 1111
			--------------
			   0100 0111
			
		~(0x1<<5):1110 1111
		0x1<<5--> 0000 0001<<5 --> 0001 0000  ---> 1110 1111
		
		data = data | (0x1<<6);
		       0101 0111
			|  0010 0000
			--------------
			   0111	0111		
			   
		0x1<<6--> 0000 0001<<6 --> 0010 0000
		
	练习:
		编译一个程序,实现两个数的置换。
		int a =10; //0000 1010
		int b =20; //0001 0100
		
		通过一个简单的算法实现
		int a存储int b中的值。
		int b存储int a中的值。 
		
		a = a^b;
				0000 1010  a
			^   0001 0100  b
		-----------------
                0001 1110  mid		
		
		b = b^a;
				0001 0100  b
			^   0001 1110  mid
		-----------------
                0000 1010  b-->						
		
		a = a^b;
				0001 1110  mid(a)
			^   0000 1010  b-->
			-----------------------
				0001 0100  
		
		int a =10; //0000 1010
		int b =20; //0001 0100
		
		异或之后的结果:
		a = 0001 0100
		b = 0000 1010
	
	7)三目运算符
	一般格式:表达式1 ?  表达式2 : 表达式3
	
	表达式1:一般为逻辑判断(非真即假)
	表达式2:若表达式1为真,则执行表达式2中的内容。
	表达式3:若表达式1为假,则执行表达式3中的内容。
	
	例子,两个数比大小,通过三目运算符来比大小。
	int a =3;
	int b =4;
	
	写法一:
	if(a>b)
	{
		printf("a>b");
	}
	else{
		printf("a<b");
	}
	
	写法二:
	(a>b) ? printf("a>b"); : printf("a<b");
	
4)3种基本结构的学习(顺序结构,选择分支,循环结构)
	1)顺序结构
	2)选择分支结构(if-else, switch-case)
		1)if(表达式1)//做逻辑判断
		   {
				表达式2;//如果表达式1为真。
				……
		   }
		   else
		   {
				表达式3;//如果表达式1为假。
				……			   
		   }
		   练习:判断一个数是奇数还是偶数。
		   
		2)if-else的嵌套
		   if(表达式1)//做逻辑判断
		   {
				if(表达式4)
				{
				
				
				}
				else{
				
									
				}
				表达式2;//如果表达式1为真。
				……
		   }
		   else
		   {
				表达式3;//如果表达式1为假。
				……			   
		   }
		3)switch-case
		switch(选择变量)//选择变量可以是数字,单个字符
		{
			case 1:
					表达式1;
					break;
			case '\n':
					表达式2;
					break;
			……
			defalut:
					break;
		}
			
	3)循环结构(for, while,do-while,goto)
		1)for(表达式1; 表达式2; 表达式3)
		   {
				表达式4;
				……			 	
		   }
		   表达式1:初始化循环变量。
		   表达式2:进入表达式4的条件。(进行逻辑判断)
		   表达式3:处理循环变量。
		   
		举例:编写一个程序,打印1~10。
		int i;
		for(i=0; i<11; i++)
		{
			printf("%d ", i);
		}
		
		2)while(逻辑判断)
		  {
			表达式1;//如果为真,则执行表达式1中的内容。
			……
		  }
		  
		 3)do-while
			do{
			   表达式1;	
			}while(逻辑判断);
			
			do-while与while的区别:
				1)while只有进行逻辑判断为真之后才能表达式1中的内容。
				   do-while第一次进入的时候就执行表达式1中的内容。
							执行之后在进行判断。
		  4)goto
				一般一般用于出错处理。
			loop:
					
			
					goto loop;
			
5)函数的定义,函数的调用,函数的声明。
	函数的定义:
		返回值类型 函数名(形参列表)
		{
			表达式;
			return 返回值;			
		}
		返回值类型:C语言常见的数据类型。(int, float, 数组,结构体类型,结构体指针类型)
		函数名:函数的名字。命名不能使用关键字来命名。
		形参列表:传递数据的接口。(类型1 变量名1,类型2 变量名2)
		return:程序中遇到return就结束return所包含的函数。
		返回值:根据返回值类型来经行数值的返回。
	函数的声明:返回值类型 函数名(类型1 变量名1,类型2 变量名2);
	函数的调用:函数名(变量名1,变量名2);
	
	两个数做加法,来封装一个函数。
	int add(int a, int b)
	{
		return a+b;
	}

一: \n换行符需要注意的地方:

示例代码:

		 while(1)
		 {
		 	sleep(1);

		 	printf("HELLO WORLD");

		 }

		 A:会打印  B:不会打印


printf能打印的条件总结

	1:printf是遇到/n 打印

	2:printf 和 sancf配合 可以打印

	3:printf对应的函数退出时 可以打印

	4:当内存里面的标准输出缓存区满时,可以打印 (需要等待)

二、scanf的返回值:

	计算键盘输入的有效数据个数

	键盘输入 int   scanf("%d",&xxx);

			long   scanf("%ld",&xxx);

			char  scanf("%c",&xxx);

三:getchar: 键盘接受字符(char),一个字符是一个字节

例子: 

		char ch;

		ch = getchar();//getchar函数的返回值就是你键盘输入的字符


练习:

		1:利用getchar函数,编写一份实现清空缓存区的代码

		2:利用sacnf和getchar,实现键盘输入年龄数字,,判断改年龄是否大于100,如果大于100.则打印你是妖怪吗?,如果户用输入的数据不正常,需要实现能重新输入的功能。


		不正常的数据:  a  19abcdfs   13 23

=================================================================================================================

1、函数的定义 封装 调用 (声明)

1.1、函数的定义(函数不能嵌套定义)


main函数:

正常:	char main()       int:整形 函数的返回值类型      函数的返回值与函数的返回值类型要一致 
		{								


			return 's';
		}		

自己自定义一个函数(给函数取名字)						


	练习:
			自己定义一个函数,实现判断键盘输入的数是不是偶数,如果是则返回1,如果不是则返回-1;

			check_num();

1.2:函数的封装 (实现函数的功能)


1.3:函数的调用 (使用某个函数)

	函数是在函数里面被调用的,函数可以嵌套调用


	调用者:main (main只能做调用者,不能做被调用者)

	被调用者: check_num

2、全局变量、局部变量

全局变量是在函数外面,默认初始化的值为0。
局部变量是在函数里面的,只属于该函数的。(定义局部变量时,最好给他赋值)


练习:

		1、利用函数的嵌套调用  编写实现 求5的 阶乘的代码   1x2x3x4x5x6


		2、修改之前的显示时间的代码,封装成三个函数,分别计算时、分、秒

			第一种修改:
						不能用传参 和返回值

			第二种修改:

						只用用传参和返回值

			第三种:

						只能用返回值   static:静态变量:只初始化一次

3、控制流语句

int num =0;
for(num=10;num<19 ; num++)

嵌套的for循环

	for(int a=56; a<65; a++)  9
	{

		for(int b=86; b>68; b--) 18   9 *18
		{
			printf("HELLO WORLD\n");
		}
	}

for(; ;)    while(1)
{			{


}			}


for(; ; );  while(1);//堵塞

一、控制流语句的练习:

1:键盘输入一个数,然后颠倒打印出来。例如:输入 564  输出 465

2:计算 1+2+3+....+100的和,并且输出

补充:运算符

1:算术运算符    +   -   *   /  %(取余数) += -= /= *=  %= ++ -- 

2:逻辑运算符   &&  ||  !

练习:持续键盘输入一个年号,判断是闰年还是平年。

	闰年: 只能被4整除并且不能被100整除     或者只能被400整除

3:    > >= < <= == !=

4:三目运算符(唯一一个三目运算符)  

条件语句?变量1:变量2   
条件语句?执行语句1:执行语句2
练习:运用三目运算符,把两个整形变量的值互换。

二、
1、

	switch(变量)
	{
		case 情况1: 执行语句;break;
		case 情况2: 执行语句;break;
		case 情况3: 执行语句;break;
		case 情况4: 执行语句;break;
		case 情况5: 执行语句;break;
		default:执行语句

	}

2、 先执行,再判断,至少执行一次

	 do
	{

	}while();


	用do  while(),键盘输入一个数,打印出这个数的范围内所有能被5整除的数。

3、goto

练习:使用goto 实现死循环打印helloworld

int num=0;

loop:
	printf("HELLO WROLD\n");
	if(num++ == 3) goto others;

goto loop;
others:

		。。。。。。。

=================================================================================================================================

三、数组

数组的特点:
			1:他可以存放一个或多个同一种类型的数据

			2:通过数组下标来访问数组里面的成员数据  数组下标的范围是 0 ~ 数组的长度-1   a[10]

			3:数组下标可以越界 ,编译不会出错,但是运行的时候有可能出错

			4:数组里面每个元素的地址是连续的  首先:如何打印变量的在内存里面的地址


		例子:定义一个能够存放 10个整形数据的数组   int array[10];


		练习:

				1: 定义一个能够存放10变量的整形数组,里面的数据自己随机赋值,找出里面最大的数


				2: 定义一个能够存放10变量的整形数组,把里面的数据从大到小重新排列

				a[4] = {33, 55 ,44,4}

					第一次判断  33 和 55   33 和 44    33 和 4
					第二次:    55   44    55   4

					最后一次    44   4


					左边 和  右边判断 

					0 ~ 2    1 ~ 4

					int i,j;
					int max=0;
					for(i=0; i<M-1; i++)//左边
					{

						for(j=i+i; j<M; j++)//右边
						{
							//互换位置

							if(array[i]<array[j])
							{
								max = array[i];
								array[i] = array[j];
								array[j] = max;
							}
						}
					}

1、打印hello world的代码:

	#include <stdio.h>

	int main()
	{

		printf("HELLO WORLD\n");
		reutrn 0;
	}


#include 是 预编译命令 在编译之前把include后面加的文件,包含进.c文件里面

预处理编译命令(头文件包含、宏定义的展开): gcc -E hello.c -o hello.i 

编译汇编(检查语法):                    gcc -S hello.i  -o hello.s

										gcc -c hello.s -o hello.o

链接(链接程序运行时所需要的库)           gcc  hello.o   -o   hello

2、C语言中的函数:

			函数分为两种:主函数(调用者)、子函数(被调用者)

			传参:函数之间,传递数据

					实参: 属于调用者的局部变量

					形参: 属于被调用的局部变量  ,是用来存放调用者传递过来的数据 ,形参和实参的类型一定要一致


			int fun(int j)//自己自定义一个函数
			{
				printf("This a fun\n");
				printf("main函数传过来的数据是:%d\n",j);
				return 0;
			}


			int main()
			{
				int a =110;  //a是实参
				fun(a);

				return 0;
			}


			练习:

				在main里面键盘输入一个数,把这个数传给fun函数,让fun函数判断传过来的数是不是偶数。

		C语言编程模块化(多个文件):

		模块化:按功能分类

		例子:打印HELLO WORLD

		main.c          写main函数

		hello.c         打印hello

		world.c         打印world

		helloworld.h    声明 打印hello和world的函数


数组:

	数组不能动态定义


	int n;

	scanf("%d",&n);

	int array[n];

======================

	数组没有赋值的元素,默认会赋值为0.
	int array[3] = {2};

	array[2] = ??;

======================

	数组名是数组首元素的地址,但是有时候他也表示的是整个数组

1:自己自定义一个存放10个随机整数的数组,把里面所有偶数打印出来


2:自己自定义一个存放10个随机整数的数组,把里面的偶数拿出来存放到另外的数组里面

======================

字符数组:

	char array[] = “中国”;//定义一个空的数组

	char array[5] = {'0','2','s','w','\0'};

	char array[5] = "02sw"


	printf("%c\n",array[2]);

	printf("%s\n",array);



	练习: 通过循环,把数组里面的每个字符打印出来


	Linux     中文编码 UTF-8    一个中文占3个字节

	windows   中文编码  GB2312  一个中文占2个字节

如何定义一个字符串存放在数组里面? char arrray[] = “dfasfhjfkash”;

	字符串数组默认最后的一个字节是什么数据?  \0



	练习:字符数组元素的遍历,实现的功能有一下参见的几点:

		1:字符去重复(相邻两个相同的字符)

		2:搜索里面个有没有某个字符,出现的个数是几次


		字符串操作函数:
					
					bzero(首地址,要清除的长度);
					memset(首地址,想要改成的字符,要清除的长度);
					整形数组:    0    -1
					字符: 任意字符
					
					strlen :计算字符串的长度
					strcat(数组1,数组2); :把数组2拼接带数组1后面
					strcpy(数组1,数组2);   把数组2复制到数组1里面
					strcmp(数组1,数组2);   判断两个字符串相不相等

					等于0: 想等
					小于0: 数组1<数组2
					大于0: 数组1>数组2

指针:

1:怎么定义一个指针变量                                  int a=10; 整形变量
	指针变量用来存放指针(指针就是变量地址)

	指针变量要和存放的变量地址的类型要一致

	整形的指针变量: int *  变量名
	字符的指针变量: char * 变量名

	int  A;
	char B;

	int  *a = &B;//指针变量初始化

	A 是什么? 整形变量                                 *a 就等于 A
	&A是什么? 整形变量A的地址                           a 就等于 &A
	a:是什么? 指针变量a,这个a里面存放的是整形变量A的地址  a 就等于 &A
	&a是什么? 指针变量a的地址
	*a是什么? 整形变量的数据                            *a 就等于 A

	char *b

2:指针变量是用来干嘛?


2:指针   (指针就是变量地址)

一、

指针变量用来存放地址的

如何定义一个整形指针变量: int *p = NULL;


野指针怎么样出现?就是在定义指针变量的时候,没有自己赋值一个地址给他,那么系统就会随机给他一个地址。

避免野指针: int *p = NULL;

野指针:这个指针变量存放的地址是不合法的。



给指针变量赋值地址的做法:

	1:初始化:

		int a=10;
		int *p = &a;

	2:赋值:

		int a 10;
		int *p =NULL;
		p = &a;

===================================================================================================

   1、指针变量的传参

2、指针变量作为函数的返回值

	练习:

		定义一个函数,返回值

3、

		char *A[] = "dhfakhdflsa";
		char *p = &(A[0]);

		printf("%c",*p);


		1:让指针变量p存放数组首元素的地址    &(A[0]); A;



		2:让指针变量p存放的是数组的首地址,那指针变量P要是一个数组指针 &A

		练习:

			1、通过指针实现 键盘输入一个字符,在一个字符串里面搜索有没有该字符,有则把这个字符变成' '


			2、编写一份实现类似strcpy函数功能的代码



			在32位系统上,char *p ;   指针变量占__4 _字节,指针占__1__字节.

		补充:数组本来就是个一级指针

				int A[5] = {2,44,66,77,3,2};

				A[3];

				*(A+3)

				*(A+1)
				*(A++)  错
				int a[4] = {1,4,6,7};

(*(&a))[1]   等于 4   a[1]       int a = 10;    *(&a)   a

*((*(&a))+1) 等于 4

*(a+1)

1、int a[4] = {1,4,6,7};
   以(*(&a))[1]为例子:


   &a:数组的首地址

  *(&a):数组名、数组a、数组的首元素的地址

  (*(&a))[3]:数组a下标为3的元素

  *((*(&a))+1):通过数组首元素的地址往下移动一个位置,得到数组第二个元素的地址,在解引用获取到

  				数组第二个元素的数据

 *((*(&a))+1):_____________。

============================================================================================

 一、
 	函数与指针的关系


 	1:指针函数:指针函数他是一个函数,然后其返回值为指针类型

 	int* fun()
 		{
 			int a;
 			//int *p =&a;

 			return p;//return &a;
 		}


 		例子:自己自定义一个指针函数,该函数返回值为一个指向字符数组首元素的地址的指针变脸


 	2:函数指针:函数指针他是一个指针,指向一个函数的


 二、数组与指针的关系

 	数组指针:数组指着他是一个指针,指向一个数组

 	int array[4] = {1,44,56,77};

 	int (*p)[4] = &array; //定义一个数组指针指向 array  p就是存放数组的地址

 	printf("%d\n",(*p)[2]);

 	printf("%d\n",*((*p)+2));

 	练习: 利用刚学的数组指针为函数的形参进行传参。



 	指针数组:他是一个数组,存放多个指针变量

 	int a=19,b=11,c=112;

 	int * array[3] = {&a,&b,&c};//定义一个指针数组

一、结构体

	int a ;整形

	int a[10];整形数组

1、结构体数据类型怎么定义?   特点:可以存放多种多个数据类型

	struct a
	{
		int  b;   4
		char c;   1
		long long d;   8
	};

2、上面定义的结构体在内存中的大小是?

	Linux下,计算结构体的大小的规则:

		32位系统安装不了64编译器,64位系统可以安装32位编译器

	32位编译器:

		1:以内存中4个字节对齐

		2:计算出来的总大小要是里面最大的数据类型的倍数(倍数对大为4)


	64位编译器:

			1:以内存中8个字节对齐

			2:计算出来的总大小要是里面最大的数据类型的倍数




3、计算结构体的大小的规则,是以编译器的位数决定的,和系统的位数无关

	32位:gcc 4.6.3    32位的编译器以 4个字节对齐

	64位:gcc 5.4.0    32位的编译器以 8个字节对齐



4、typedef与结构体的一起用


	typedef struct my_struct
	{
		int a;
	}S_m,*P_S_m;


	S_m:

		struct my_struct 等于  S_m

		


		struct my_struct A;

		S_m A;

	P_S_m:

		P_S_m  等于 struct my_struct *

		struct my_struct *B;

		P_S_m B;


5、结构体传参


	typedef struct  A
	{
		int b;
	}a;


	int fun(a st,int b)
	{
		printf("%d----%d\n",st.b,b);
		return 0;
	}


	int main()
	{
		a st;

		st.b =110;

		fun(st,st.b);
		
		return 0;
	}


6、结构体指针传参


	typedef struct  A
	{
		int b;
	}a,*p_a;


	int fun(p_a st,int b)
	{
		printf("%d====%d\n",st->b,b);

		return 0;
	}


	int main()
	{
		p_a st = (p_a)malloc(sizeof(a));
		st->b = 110;
		
		fun(st,st->b);

		free(st);

		return 0;
	}

一、结构体数组

1.1
	概念: 他是一个数组,里面可以存放一个或多个结构体,但是这些结构体是同一种类型的结构体

1.2
	结构体数组怎么定义?

		1、定义一个结构体的类型

		struct A
		{
			int  a;
			char b;
		}

		2、定义一个结构体的数组,以及使用它

			struct A st[5];

			st[0].a = 10;
			st[1].a = 11;

			printf("%d----%d\n",st[0].a,st[1].b);

1.3、练习:

		自己定义一个结构体数组,里面存放的结构体类型设计成存放学生的基本信息(学号、性别、年龄),把5个学生的基本信息打印出来。


1.4、结构体数组指针


	正常定义一个结构体数组指针

		typedef struct A
		{
			int  a;
		} S_A,*P_S_A,(*P_S_A_R)[];


		int main()
		{
			struct A *st_array_p[] = (struct A (*)[]) malloc(sizeof(struct A)*2);

			scanf("%d",&(*st_array_p)[1].a));

			printf("%d\n",(*st_array_p)[1].a));

			return 0;
		}


		用typedef定义一个结构体数组指针


		int main()
		{
			//st_array_p是一个数组指针变量,存放的肯定是数组的地址
			//*st_array_p获取到数组,也就是表示数组名,也就是数组的首元素地址
			P_S_A_R st_array_p[] = (P_S_A_R ) malloc(sizeof(S_A)*2);

			scanf("%d",&(*st_array_p)[1].a)); //(*st_array_p)[1] 数组里面下标位1的元素(结构体)

			scanf("%d",&((*st_array_p)+1)->a);   int a[2]; &a a &(a[0])


			printf("%d\n",(*st_array_p)[1].a));

			return 0;
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux嵌入式开发是指在嵌入式系统中使用Linux操作系统进行开发。Linux操作系统具有开放性、可定制性、模块化等特点,使得它成为了嵌入式系统开发中最流行的操作系统之一。 本教程将以树莓派作为开发板,介绍Linux嵌入式开发的基础知识和实践。 准备工作: 1. 树莓派开发板 2. SD卡 3. 电脑 4. USB转串口工具 5. HDMI显示器和键盘(可选) 步骤1:安装Linux系统 1. 下载Raspberry Pi官方提供的系统镜像,可以从官网上下载:https://www.raspberrypi.org/downloads/ 2. 解压镜像文件,并将其写入SD卡中。可以使用Rufus等工具进行写入。 3. 将SD卡插入树莓派,连接电源和USB转串口工具。 步骤2:连接串口 1. 在电脑上安装串口调试工具,如SecureCRT、Putty等。 2. 打开串口调试工具,设置串口号和波特率,连接树莓派。 3. 在串口调试工具中输入用户名和密码登录树莓派。 步骤3:配置网络 1. 使用ifconfig命令查看树莓派的IP地址。 2. 在电脑上打开SSH客户端,如SecureCRT、Putty等。 3. 输入树莓派的IP地址和用户名、密码,即可在电脑上远程登录树莓派。 步骤4:开发环境搭建 1. 安装开发工具链,如gcc、g++等。 2. 安装调试工具,如gdb。 3. 安装版本控制工具,如git。 4. 安装构建工具,如make。 步骤5:开发应用程序 1. 创建一个简单的C程序,如Hello World。 2. 使用gcc编译程序,生成可执行文件。 3. 在树莓派上运行可执行文件,验证程序是否正常运行。 总结: 本教程介绍了Linux嵌入式开发的基础知识和实践。通过学习本教程,您可以了解Linux操作系统在嵌入式系统中的应用,学习如何使用树莓派进行开发,掌握基本的开发工具和技巧。希望本教程能够对您有所帮助。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值