C语言基础概述(一)

C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。
最新的C语言标准是C18

第一个C语言程序:Hello world!

#include <stdio.h>
int main()
{
 printf("Hello World!");
 return 0;
}

输出:

Hello World!
title: 补充知识
collapse: open

xxxx.c:源文件;
xxxx.h:头文件;

分析C简单C语言结构

  1. 写出主函数(main函数)
int main()
{
	return 0;
}

那么什么是主函数?
主函数就是:main(),结构如上,注意:一个C程序有且仅有一个main函数,任何一个C程序总是从main函数开始执行,main函数后面的一对圆括号不能省略。C语言是从主函数的第一行开始执行的。相当于执行C语言的入口。

  1. 函数名、函数体、函数的返回类型

  2. 打印函数:printf

printf("Hello World!");

printf:库函数,在屏幕上打印信息。因为这个函数不是本程序里的,是引用的库函数的,所以需要在前面引用头文件<stdio.h>,这样就可以使用库函数里的函数了。
完整代码:

#include <stdio.h>
int main()
{
 printf("Hello World!");
 return 0;
}
  1. 运行!
title: 补充知识

`\n`:执行换行操作;

```C
printf("Hello World!\n");
```

C语言数据类型

数据类型用来说明数据的类型,确定了数据的解释方式,让计算机和程序员不会产生歧义

说 明字符型短整型整型长整型单精度浮点型双精度浮点型无类型
数据类型charshortintlongfloatdoublevoid
 char   ch = 'a';
数据类型 变量  字符
意义:给字符型的变量ch赋值为字符a。

上面用字符为例,整数的赋值结构也是一样的,不同的数据类型所分配的空间都是不一样的。为了节省内存空间。

title: 补充知识

1. 打印字符、数:
```C
printf("打印字符\n");
printf("%d\n",100);//打印一个整数100,%d:就代表要打印一个整数
```

2. `sizeof`:关键字————操作符————计算类型或者变量所占空间的大小
```C
printf("%d\n",sizeof(char));//打印出计算char的大小的结果
```

打印出各个数据类型的大小:

#include <stdio.h>
int main()
{
	printf("%d\n",sizeof(char));
	printf("%d\n",sizeof(short));
	printf("%d\n",sizeof(int));
	printf("%d\n",sizeof(long));
	printf("%d\n",sizeof(long long));
	printf("%d\n",sizeof(float));
	printf("%d\n",sizeof(double));
}

title: 补充知识

1. 计算机中单位:

**位**:计算机最小的数据单位,每一位只能是0或1;

**字节**(Byte):8个二进制构成一个字节,是存储空间的基本构成单位;

**KB**:1KB代表1024个字节;

等等



常量与变量

数据类型时用来创建变量的

常量: 固定的数据
变量: 可以改变的量

变量

  1. 创建一个变量:
#include <stdio.h>
int main()
{
	//创建一个变量
	//类型 变量的名称 = 0;
	//类型 变量的名称;
	//两种方式都可以创建变量,推荐第一种;
	int age = 20;
	double weight = 75.3;
	
	age = age + 1;
	printf("%d\n",age);
	printf("%if\n",weight);
	
	return 0;
}

运行结果:

title: 补充知识

- %d:打印整型
- %f:float
- %lf:double
- %c:字符

局部变量和全局变量

#include <stdio.h>

//全局变量:{}外部定义的
int b = 100
int a = 5
int main()
{
	//局部变量:{}内部定义的
	int a  = 10;
	pintf("%d\n",a)
	return 0;
}

当全局变量与局部变量名字冲突的情况下,局部优先;
以上代码运行结果:10

写一个代码求两个整数的和

#include <stdio.h>
int main()
{
 int a = 0;
 int b = 0;
 int sum = 0;
 scanf("%d %d",&a,&b);
 sum = a+b;
 printf("sum = %d\n",sum);
 return 0;
}

运行结果:

title: 补充知识:scanf函数

- 输入函数:`scanf`
```C
scanf("%d %d",&a,&b);
```
![](https://img-blog.csdnimg.cn/img_convert/cbd7aa5d7470b03cdb61abeb5c2cb6aa.png)

变量的作用域

#include <stdio.h>
int main()
{
	int a = 10;
	printf("%d\n",a)
	return 0;
	//a的作用域在这个{}内
}
//运行结果:10

作用域:通俗的讲哪里起作用哪里就是它的作用域

#include <stdio.h>
int main()
{
	{
	int a = 10;
	//a的作用域在这个{}内;
	}
	printf("%d\n",a)
	return 0;
}
//运行结果:报错,没有定义a

局部变量作用域:就是它所在的局部范围
全局变量作用域:整个工程

变量的生命周期

生命周期:指的变量的创建和销毁之间的时间段;
局部变量的生命周期:进入局部范围生命开始,出局部范围生命结束;
全局变量的生命周期:程序的生命周期;

常量

  • 字面常量
  • const修饰的常变量
  • #define定义的标识符常量
  • 枚举常量
  1. 字面常量
#include <stdio.h>
int main()
{
	//字面常量;
	10;
	12;
	3.12;
	"a";
	return 0;
}

  1. const修饰的常变量
#include <stdio.h>
int main()
{
	int a = 10;//变量
	const int a = 10;//前面加了const,指定这个变量不能改变,所以叫常变量,本质还是变量;
	return 0;

}

  1. #define定义的标识符常量
#include <stdio.h>

#define MAX 10000
int main()
{
	int a = MAX;
	printf("%d\n",a);
	return 0;
}

运行结果:10000

  1. 枚举常量:可以一一列举的常量
#include <stdio.h>
enum Sex
{
	//这种枚举类型的变量的未来可能取值;
	MALE;
	FEMALE;
	SECRET;
}
int main()
{
	enum Sex s = MALE;//值只能是MALE、FEMALE、SECRET中的一个;
	return 0 ;
}

字符串+转移字符+注释

字符串

字符串:就是一串字符——用“”括起来的一串字符

"字符串"
#include <stdio.h>

int main()
{
	char arr[] = "hello"
	
	return 0;
}

调式查看数组如下:

在字符串:hello后面隐藏放了一个字符"/0";
字符串在结尾的位置隐藏了一个/0的字符;
/0是字符串的结束标志;

title: 补充知识:数组

- 数组是一组相同类型的元素
- 创建一个数组,并初始化

```C
char arr[] = "hello";
//创建字符型的数组,[]没有表明数组大小,根据后面赋值来确定大小。赋值“hello”。
//相当于创建了一个["h","e","l","l","l","o","/0"]的数组;
```

由双引号""引起来的叫一串字符,单引号''引起来的叫一个字符;
对比:

#include <stdio.h>
int main()
{
	char arr1[] = "abc";
	char arr2[] = {'a','b','c'};
	
	printf("%s\n",arr1);
	printf("%s\n",arr2);
	return 0;
}

监控:arr1和arr2

可以看到arr2没有/0
查看打印结果

因为arr1/0是结束的标志,所以到/0,程序就知道结束了,而arr2没有结束标志,所以程序就不知道有没有结束,会继续打印剩下的。
修改arr2

char arr2[] = {'a','b','c','/0'};//手动添加结束标志/0

这样就行了。

title: 补充知识:strlen函数

- strlen函数:求字符串的长度
注意需要引用头文件:`#include <string.h>`


说明/0只是作为结束的标志

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

int main()
{
	char arr1[] = "abc";
	char arr2[] = {'a','b','c'};
	
	
	printf("%s\n",strlen(arr1));
	printf("%s\n",strlen(arr2));
	return 0;
}

转义字符

字符集(Character Set)为每个字符分配了唯一的编号,我们不妨将它称为编码值。在C语言中,一个字符除了可以用它的实体(也就是真正的字符)表示,还可以用编码值表示。这种使用编码值来间接地表示字符的方式称为转义字符(Escape Character);
转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。对于转义字符来说,只能使用八进制或者十六进制。

转义字符以\或者\x开头,以\开头表示后跟八进制形式的编码值,以\x开头表示后跟十六进制形式的编码值。对于转义字符来说,只能使用八进制或者十六进制。

字符 1、2、3、a、b、c 对应的 ASCII 码的八进制形式分别是 61、62、63、141、142、143,十六进制形式分别是 31、32、33、61、62、63。下面的例子演示了转义字符的用法:

char a = '\61';  //字符1
char b = '\141';  //字符a
char c = '\x31';  //字符1
char d = '\x61';  //字符a
char *str1 = "\x31\x32\x33\x61\x62\x63";  //字符串"123abc"
char *str2 = "\61\62\63\141\142\143";  //字符串"123abc"
char *str3 = "The string is: \61\62\63\x61\x62\x63"  //混用八进制和十六进制形式

转义字符既可以用于单个字符,也可以用于字符串,并且一个字符串中可以同时使用八进制形式和十六进制形式。

一个完整的例子:

#include <stdio.h>
int main()
{
	puts("\x68\164\164\x70://c.biancheng.\x6e\145\x74");
	return 0;
}

运行结果:
http://c.biancheng.net

转义字符的初衷是用于 ASCII 编码,所以它的取值范围有限:

  • 八进制形式的转义字符最多后跟三个数字,也即\ddd,最大取值是\177
  • 十六进制形式的转义字符最多后跟两个数字,也即\xdd,最大取值是\x7f

超出范围的转义字符的行为是未定义的,有的编译器会将编码值直接输出,有的编译器会报错。

对于 ASCII 编码,0~31(十进制)范围内的字符为控制字符,它们都是看不见的,不能在显示器上显示,甚至无法从键盘输入,只能用转义字符的形式来表示。不过,直接使用 ASCII 码记忆不方便,也不容易理解,所以,针对常用的控制字符,C语言又定义了简写方式,完整的列表如下:

转义字符意义ASCII码值(十进制)
\a响铃(BEL)007
\b退格(BS) ,将当前位置移到前一列008
\f换页(FF),将当前位置移到下页开头012
\n换行(LF) ,将当前位置移到下一行开头010
\r回车(CR) ,将当前位置移到本行开头013
\t水平制表(HT)009
\v垂直制表(VT)011
单引号039
"双引号034
\反斜杠092

\n\t是最常用的两个转义字符:

  • \n用来换行,让文本从下一行的开头输出,前面的章节中已经多次使用;
  • \t用来占位,一般相当于四个空格,或者 tab 键的功能。

单引号、双引号、反斜杠是特殊的字符,不能直接表示:

  • 单引号是字符类型的开头和结尾,要使用\'表示,也即'\''
  • 双引号是字符串的开头和结尾,要使用\"表示,也即"abc\"123"
  • 反斜杠是转义字符的开头,要使用\\表示,也即'\\',或者"abc\\123"

转义字符示例:

#include <stdio.h>
int main(){
	puts("C\tC++\tJava\n\"C\" first appeared!");    
	return 0;
}

运行结果:
C C++ Java
“C” first appeared!

注释

P16开始;

选择语句

举例:

#include <stdio.h>
int main()
{
	int input = 0;
	printf("加入光荣的进化吧!");
	printf("加入:1;不加入:0"\n);
	scanf("%d",&input);
	if (input == 1)
	{
		printf("机械飞升");
	}
	else
	{
		printf("人生苦短");
	}
	return 0;
}

以上中就要选择,不同的选择不同结果

循环语句

while循环


int line = 0
while(line <30000)
{
	line++;
}

line等于30000的时候就会跳出循环。

函数

函数是一段可以重复使用的代码,用来独立地完成某个功能,它可以接收用户传递的数据,也可以不接收。接收用户数据的函数在定义时要指明参数,不接收用户数据的不需要指明,根据这一点可以将函数分为有参函数和无参函数。
将代码段封装成函数的过程叫做函数定义

int Add(int x,int y)
{
	int z = 0;
	z = x+y;
	return z;
}//定义了一个函数
int main()
{
	int num1 = 0;
	int num2 = 0;
	scanf("%d%d",&num1,&num2);
	
	int sum = Add(num1,num2);//调用了一个函数;
	printf("%d\n",sum);
	
	return 0;
}

函数结构:

如果函数不接收用户传递的数据,那么定义时可以不带参数。如下所示:

dataType  functionName(){  
    //body  
}
  • dataType 是返回值类型,它可以是C语言中的任意数据类型,例如 int、float、char 等。
  • functionName 是函数名,它是标识符的一种,命名规则和标识符相同。函数名后面的括号( )不能少。
  • body 是函数体,它是函数需要执行的代码,是函数的主体部分。即使只有一个语句,函数体也要由{ }包围。
  • 如果有返回值,在函数体中使用 return 语句返回。return 出来的数据的类型要和 dataType 一样。

例如,定义一个函数,计算从 1 加到 100 的结果:

1.  int sum(){
2.      int i, sum=0;
3.      for(i=1; i<=100; i++){
4.          sum+=i;
5.      }
6.      return sum;
7.  }

累加结果保存在变量sum中,最后通过return语句返回。sum 是 int 型,返回值也是 int 类型,它们一一对应。

return是C语言中的一个关键字,只能用在函数中,用来返回处理结果。

将上面的代码补充完整:

1.  #include <stdio.h>

3.  int sum(){
4.      int i, sum=0;
5.      for(i=1; i<=100; i++){
6.          sum+=i;
7.      }
8.      return sum;
9.  }

11.  int main(){
12.      int a = sum();
13.      printf("The sum is %d\n", a);
14.      return 0;
15.  }

运行结果:
The sum is 5050

函数不能嵌套定义,main 也是一个函数定义,所以要将 sum 放在 main 外面。函数必须先定义后使用,所以 sum 要放在 main 前面。

注意:main 是函数定义,不是函数调用。当可执行文件加载到内存后,系统从 main 函数开始执行,也就是说,系统会调用我们定义的 main 函数。

无返回值函数

有的函数不需要返回值,或者返回值类型不确定(很少见),那么可以用 void 表示,例如:

1.  void hello(){
2.      printf ("Hello,world \n");
3.      //没有返回值就不需要 return 语句
4.  }

void是C语言中的一个关键字,表示“空类型”或“无类型”,绝大部分情况下也就意味着没有 return 语句。

C语言有参函数的定义

如果函数需要接收用户传递的数据,那么定义时就要带上参数。如下所示:

dataType  functionName( dataType1 param1, dataType2 param2 ... ){  
    //body  
}

dataType1 param1, dataType2 param2 ...是参数列表。函数可以只有一个参数,也可以有多个,多个参数之间由,分隔。参数本质上也是变量,定义时要指明类型和名称。与无参函数的定义相比,有参函数的定义仅仅是多了一个参数列表。

数据通过参数传递到函数内部进行处理,处理完成以后再通过返回值告知函数外部。

更改上面的例子,计算从 m 加到 n 的结果:

1.  int sum(int m, int n){
2.      int i, sum=0;
3.      for(i=m; i<=n; i++){
4.          sum+=i;
5.      }
6.      return sum;
7.  }

参数列表中给出的参数可以在函数体中使用,使用方式和普通变量一样。

调用 sum() 函数时,需要给它传递两份数据,一份传递给 m,一份传递给 n。你可以直接传递整数,例如:

int result = sum(1, 100);  //1传递给m,100传递给n

也可以传递变量:

int begin = 4;  
int end = 86;  
int result = sum(begin, end);  //begin传递给m,end传递给n

也可以整数和变量一起传递:

int num = 33;  
int result = sum(num, 80);  //num传递给m,80传递给n

函数定义时给出的参数称为形式参数,简称形参;函数调用时给出的参数(也就是传递的数据)称为实际参数,简称实参。函数调用时,将实参的值传递给形参,相当于一次赋值操作。

原则上讲,实参的类型和数目要与形参保持一致。如果能够进行自动类型转换,或者进行了强制类型转换,那么实参类型也可以不同于形参类型,例如将 int 类型的实参传递给 float 类型的形参就会发生自动类型转换。

将上面的代码补充完整:

1.  #include <stdio.h>

3.  int sum(int m, int n){
4.      int i, sum=0;
5.      for(i=m; i<=n; i++){
6.          sum+=i;
7.      }
8.      return sum;
9.  }

11.  int main(){
12.      int begin = 5, end = 86;
13.      int result = sum(begin, end);
14.      printf("The sum from %d to %d is %d\n", begin, end, result);
15.      return 0;
16.  }

运行结果:  
The sum from 5 to 86 is 3731  
  
定义 sum() 时,参数 m、n 的值都是未知的;调用 sum() 时,将 begin、end 的值分别传递给 m、n,这和给变量赋值的过程是一样的,它等价于:

m = begin;
n = end;

函数不能嵌套定义

数组

数组: 一组相同类型元素的集合

int arr[10] = {1,2,3,4,5,6,7,8,9,10};
char ch[5] = {'a','b','c'};//不完全初始化,剩余的默认为0;
数组的类型  数组名称[数组的大小] = {数组内的值}

数组用下标访问,打印1~10;

#include <stdio.h>
int main()
{
	int arr[10] = {1,2,3,4,5,6,7,8,9,10};
	int i = 0;
	
	while(i<10)
	{
		printf("%d",arr[i]);
		i++;
	}
}


数组的下标是从0开始的;

操作符

算术操作符:

+ - * / %
/ 除法操作符
% 取余操作符

移位操作符

^ | & ~ >> <<

移位操作符有左移<<和右移操作符>>,这里在移位时可有点东西了。

  1. 当使用左移运算符时,很简单,将数的二进制数向左移,左移多少位就在右边补多少位的0。
  2. 当使用右移运算符时,右移运算有两种方式:
  • 逻辑右移: 逻辑右移在右移后在左边补0
  • 算术右移: 算术右移在右移后在左边补符号位
  • 注意:移位运算符不能移动负数位。例如:n=n<<-1;这样是不允许的!
  1. &:按位与
  2. |:按位或
  3. ^:按位异或,该操作符有个特性就是一个数将另一个数异或两次之后得到的数还是原来的数。即就是异或同一个数两次相当于没异或。异或运算符是指: 参与运算的两个值,如果两个相应位相同,则结果为0,否则为1。即:0^0=0, 1^0=1, 0^1=1, 11=0,例如:1010000100010001=10110000

关系操作符

关系操作符均为双目运算符,其运算结果只有两种结果,即真(1)或者假(0)。这里注意不能用数学的思维来用这些操作符,一些容易犯的错误,如判断一个变量a是否在一定范围内。就不能写成10<a<20;这里编译器会先执行10<a;上面说过该表达式的值只有0和1,那么无论10和a的大小关系如何,10<a;的运算结果一定是小于20的,这与我们的预期不符!因此应该写成10<a&&a<20;这两个表达式运算结果完全不同。

逻辑操作符

首先区别于逻辑与和逻辑或操作符&&||,明确这是两种操作符!这几种操作符在使用中有一些规律,&&运算符中有一个为假,结果一定为假,且前面表达式为假时不再执行后面的表达式; 而||运算符结果有一个为真,其结果一定为真,且当前面条件为真时,后面的条件就不再执行和判断真假。

赋值操作符

+= -= = /= %= |= &= >>= <<=

  1. 简单赋值 = ,这个操作符很简单,就是用于给数据赋值,但很多初学者容易使用该赋值操作符给字符串赋值,这里注意不能使用该操作符给字符串赋值!
  2. 复合赋值 += -= = /= %= |= &= >>= <<= ,这些操作符均都是将操作符左边的数和右边的数进行运算后再赋值给左边的数。

单目操作符

a+b:有2个操作数,双目操作符;单目操作符:只有一个操作数;
C语言中:0为假,非0就是真

  1. 左操作符:在操作符在左边,-a+a!a
    -表示负数
    +表示正数

  2. sizeof求字节长度 ,计算的是字节,单位:字节;比如计算一个数组的元素个数。

int sz = sizeof(arr)/sizeof(arr[0]);
  1. *解引用,间接访问操作符

  2. & 取地址

  3. ~按位取反 ,二进制按位取反

    整数在内存中存储的是:补码

  4. !逻辑取反 ,真变假,假变真;

  5. (类型)强制类型转换操作符

int main()
{
	int a = (int)3.14;//把3.14float型转换成int型
	
	printf("%d\n",a);
	return 0;
}
  1. ++ - -累加累减操作符
  2. 右操作符:++ - -加加减减
int main() 
{
	int a = 3, b = 4, c;
	c = (a++) + (++b);//3+5 
	printf("%d %d %d\n", a, b, c); 
	return 0;
}

区别左操作符和右操作符的区别:左操作符是先操作后使用,而右操作符是先使用后操作
就是++aa++的区别。++a=4,a++=3,相当于a=3,然后输出,最后a+1,

条件操作符(三目操作符)

exp1 ? exp2 : exp3

exp1成立,exp2计算整个表达式的结构是:exp2的结果
exp1不成立,exp3计算整个表达式的结构是:exp3的结果

max = a>b ? a : b;

逗号表达式

逗号隔开的一串表达式;

int a = 0;
int b = 3;
int c = 5;
int d = (a = b+2,c = a-4,b=c+2);

逗号表达式,是从左向右依次计算的
整个表达式的结果是最后一个表达式的结果

下标引号操作符

函数调用操作符

关键字

关键字说明
auto声明自动变量
short声明短整型变量或函数
int声明整型变量或函数
long声明长整型变量或函数
float声明浮点型变量或函数
double声明双精度变量或函数
char声明字符型变量或函数
struct声明结构体变量或函数
union声明共用数据类型
enum声明枚举类型
typedef用以给数据类型取别名
const声明只读变量
unsigned声明无符号类型变量或函数
signed声明有符号类型变量或函数
extern声明变量是在其他文件正声明
register声明寄存器变量
static声明静态变量
volatile说明变量在程序执行中可被隐含地改变
void声明函数无返回值或无参数,声明无类型指针
if条件语句
else条件语句否定分支(与 if 连用)
switch用于开关语句
case开关语句分支
for一种循环语句
do循环语句的循环体
while循环语句的循环条件
goto无条件跳转语句
continue结束当前循环,开始下一轮循环
break跳出当前循环
default开关语句中的“其他”分支
sizeof计算数据类型长度
return子程序返回语句(可以带参数,也可不带参数)循环条件
  1. C语言提供的,不能创建关键字;
  2. 变量名不能是关键字;
  3. defineinclude不是关键字,是预处理指令;

auto-声明自动变量

int a = 10;//自动创建,自动销毁的-自动变量
//auto int a = 10;
//auto省略掉了

break- 跳出当前循环

register- 声明寄存器变量

register int num 100;//建议num的值存放在寄存器中

typedef-类型重定义

typedef unsigned int u_int;
//相当于取别名
int main()
{
	unsigned int num = 100;
	u_int num2 = 100;
	//上面两个创建的变量是一个意思
}

static- 静态的

  1. 修饰局部变量
  2. 修饰全局变量
  3. 修饰函数
void test()
{
	int a = 1;
	a++;
	printf("%d",a);
}
int main()
{
	int i = 0;
	while (i<0)
	{
		test();
		i++;
	}
	return 0;
}

运行结果:打印10个2;

加上static

void test()
{
	static int a = 1;
	a++;
	printf("%d",a);
}
int main()
{
	int i = 0;
	while (i<0)
	{
		test();
		i++;
	}
	return 0;
}

运行结果:2~11

static修饰局部变量,改变局部变量的生命周期(本质上是改变了变量的存储类型)

全局变量在整个工程都可以使用,只需要关键字extern声明一下;

static修饰全局变量,是的全局变量只能在本源文件里使用
全局变量,在其他源文件内部可以被使用,是因为全局变量具有外部链接属性;但是被static修饰之后,就变成了内部链接属性,其他源文件就不能链接到这个静态的全局变量了!

static修饰函数,是的函数只能在本源文件里使用函数,在其他源文件内部可以被使用,是因为函数具有外部链接属性;但是被static修饰之后,就变成了内部链接属性,其他源文件就不能链接到这个函数了!

常量和宏

#define定义常量和宏

//#define 预处理指令
//1. define定义常量
#define MAX 1000
int main()
{
	printf("%d\n",MAX);
	return 0;
}

//2.define定义宏
//宏:就是一些命令组织在一起,作为一个单独命令完成一个特定任务

#define ADD(X,Y) X+Y
int main()
{
	printf("%d\n",4*ADD(2,3));
	return 0;
}

运行结果:11;因为:4*ADD(2,3)实际上运行的是:4*2+3的运算;

指针

数据是存储在内存中的,

  1. 内存的编号
  • 32位地址: 32个地址线 ,物理线 通电,代表1/0;
  • 64位地址: 64个地址线;
    32位就有232个地址,64位就有264个地址;
    一个内存单元就是一个字节;
int main()
{
	int a = 10; //a在内存中要分配空间的 - 4个字节;
	printf("%p\n",&a);//%p专门用来打印地址的;
	
	int * pa = &a;//pa是用来存放地址的,在C语言中是指针变量
	//*说明pa是指针变量
	//int说明pa执行的对象是int类型的;
	
	return 0;
	
}
int main()
{	
	int a = 10;
	
	int* pa = &a;
	
	*pa = 20;//*解引用操作*pa就是通过pa里边的地址,找到a
	printf("%d\n",a);
	return 0;
}

指针大大小是相同的,指针是用来存放地址的,指针需要多大空间,取决于地址的存储需要多大空间。在32位机器上就是4字节,在64位机器上就是8字节;

结构体

结构体可以让C语言创建新的类型出来

//创建一个学生类型
struct Stu
{
	char name[20];//成员变量
	int age;
	double score;
};
struct Book
{
	char name[20];
	float price;
	char id[30];
};

int main()
{
	struct Stu s = {"张三",20,85.5};//利用类型,创建一个实例
	printf("%s %d %lf\n",s.name,s.age,s.score);//结构体变量.成员变量
	
	struct Stu * ps = &s;
	printf("%s %d %lf\n",(*ps).name,(*ps).age,(*ps).score);
	//或者:
	
	printf("%s %d %lf\n",*ps->name,*ps->age,*ps->score);//结构体的指针->成员变量;
	
	return 0;
}

版权声明:本文为m0_45851211原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。