C语言基础(初识C语言)

        学习一门编程语言是一条艰辛与快乐共存的一条路,如今选择了这条路,就应该一直走下去,了解C语言的基础知识,要先对C语言有一个大概的认识,下面我介绍一下C语言的基础。

一、什么是C语言。

        C 语言是一门通用 计算机编程语言 ,广泛应用于底层开发。 C 语言的设计目标是提供一种能以简易的方式 编译 、处理低级 存储器 、产生少量的 机器码 以及不需要任何运行环境支持便能运行的编程语言。
        尽管C 语言提供了许多低级处理的功能,但仍然保持着良好跨平台的特性,以一个标准规格写出的 C语言程序可在许多电脑平台上进行编译,甚至包含一些嵌入式 处理器 (单片机或称 MCU )以及超级电脑等作业平台。
        二十世纪八十年代,为了避免各开发厂商用的C 语言语法产生差异,由 美国国家标准局 C 语言制 定了一套完整的美国国家标准语法,称为 ANSI C ,作为 C 语言最初的标准。 [1] 目前 2011 12 8 日,国际标准化组织(ISO )和国际电工委员会( IEC )发布的 C11 标准 C 语言的第三个官方标准,也是C 语言的最新标准,该标准更好的支持了汉字函数名和汉字标识符,一定程度上实现了汉字编程。
        C语言是一门面向过程的计算机编程语言,与 C++ Java 等面向对象的编程语言有所不同。
其编译器主要有 Clang GCC WIN-TC SUBLIME MSVC Turbo C 等。
二、C语言编程代码的基本格式。
        
#include <stdio.h>
int main()
{
    printf("Hello\n");
    printf("Just do it!\n");
    return 0; 
}

       打印结果:

有\n(这是换行操作符,下面会介绍)

无\n

        2.1 #include <stdio.h> 每一个C语言程序代码都含有的一个头文件,其中include 称为文件包含命令,其意义是把尖括号<>或引号""内指定的文件包含到本程序中,成为本程序的一部分。被包含的文件通常是由系统提供的,其扩展名为.h,而stdio为standard input output的缩写,意为“标准输入输出” ,在程序中为固定格式,输入上去就行。

       2.2 int main()main函数是程序的入口 ,一个工程中main函数有且仅有一个,是C语言main函数的一种声明方式,在int main()下有一对{},在其中输入代码。

       2.3 printf表示要输出的结果,其结果放入("  ")中的双引号内,如果需要特别打印某一种字符类型,一般格式为(“需要打印的数据类型\n”,需要输出的变量蓝色部分表示固定的格式。绿色部分表示需要打印相应内容时输入的不同的东西,\n表示换行,可有可无,只是打印出的结果格式不同不影响打印内容,具体需要打印的类型见后边。

       2.4 return 0返回值为0,先不做深入了解,记作固定的格式,打上去就行。

注:每一个语句后面需要打上一个英文输入下的分号  ;

三、数据类型

char              字符数据类型
short            短整型
int                整形
long              长整型
long long      更长的整形
float              单精度浮点数( 有效数字8位,表示范围:-3.40E+38~3.40E+38
double          双精度浮点数( 有效数字16位,表示范围:-1.79E+308~-1.79E+308
注:每一种类型的空间大小不同
各种数据类型的空间大小:
#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));
    printf("%d\n", sizeof(long double));
    return 0; 
}

        代码中%d打印的是整型,sizeof()用于打印数据类型的大小。

打印结果:

         其中数字大小表示各种数据类型的空间大小,单位为字节(byte)1GB=1024MB 1MB=1024KB 1KB=1024byte     1字节=8位       其中位:是二进制数据中的一个位(bit)简写为b,音译为比特,是计算机存储数据的最小单位。

四、常量与变量

常量: 不变的值, C 语言中用 常量 的概念来表示,在生活中的有些值是不变的(比如:圆周率,性别,身份证号码,血型等等)。
变量: 变的值, C 语言中用 变量 来表示(比如:年龄,体重,薪资)。
         4.1 定义变量的方法
int age = 150;
float weight = 45.5f;
char ch = 'w';

        选择需要定义变量的类型(int、char、float等),给变量相应的变量名字(自己灵活定义即可,最好方便自己记忆,比如需要对年龄赋值时,变量名用age),用 = 进行赋值,将值放在等号后面,并习惯性的打上分号。

        4.2 变量的分类

全局变量:定义在int main()以外,对整个代码有效

局部变量:定义在某一个范围内用{ }括起来的区域,当出了该范围则无效,如果全局变量和局部变量一起存在,则局部变量优先。

#include <stdio.h>
int b = 2020;            //全局变量
int main()
{
    int b = 2021;        //局部变量
    
    int c = 2022;        //局部变量
    printf("b = %d\n", b);
    return 0;
 }

打印结果:

4.3 变量的使用

        我们以计算两个数字的和为例

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0; 
}

      随机输入两个数字  

 

        代码中先定义需要输入的两个数字整型int num1=0;int num 2=0;其中赋一个初始值0,在定义一个变量来存放需要输出的值int sum=0;均放上初始值0;先输出一个提示语输入两个操作数:>用scanf(“%d %d”,&num1,&num2)来寻找变量num1和num2的地址,达到对变量随时赋值的目的,sum=num1+num2定义算法,即求两个数的和,并将结果用变量sum来承接,最后用printf来输出sum的值。

4.4 变量的作用域和生命周期
        1.作用域 是程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效,可用
的,而限定这个名字的可用性的代码范围就是这个名字的作用域。
                1. 局部变量的作用域是变量所在的局部范围。
                2. 全局变量的作用域是整个工程。
        2.生命周期 变量的生命周期指的是变量的创建到变量的销毁之间的一个时间段
                1. 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束。
                2. 全局变量的生命周期是:整个程序的生命周期。

4.5 常量

C语言中的常量和变量的定义的形式有所差异

        1.字面常量:即已知的值

        2.const 修饰的常变量:对所赋值的变量有固定作用,后续不能改变

#include <stdio.h>
int main()
{
	const int num = 4;
	printf("%d\n", num);
	int num = 8;//此处对num再赋值已经无效了
	printf("%d\n", num);
	return 0;
}

         其中const修饰的常变量,对赋值的sum有固定作用,后面再对num赋值则无效,虽然对num固定赋值了,但num的本质任然是变量,只是具有了常量的性质,验证如下:

#include <stdio.h>
int main()
{
	const int n = 10;
	int arr[n] = { 0 };//数组[]中需要的是一个常量,虽然const修饰的n有常属性,但是他的本质是一个变量所以有错误
	return 0;
}

所以没有输出结果:

        

        3.#define 定义的标识符常量 :定义的标识符不占内存,只是一个临时的符号,预编译后这个符号就不存在了。例如:对MAX的赋值,在main函数外定义。

#include <stdio.h>

#define MAX 10
int main()
{
	int arr[MAX]={0};
	printf(" %d\n", MAX);
	return 0;
}

 

        4.枚举常量:需要一一列举出来,需要用到枚举关键字enum,放在枚举里边的叫枚举常量    

#include<stdio.h>
enum people
{
	KID,
	MAN,
	WOMAN,
};                //其中KID,MAN,WOMAN,叫做枚举常量
int main()
{
	printf("%d\n", KID);
	printf("%d\n", MAN);
	printf("%d\n", WOMAN);
	return 0;
}

五、字符串+转义字符+注释

        5.1 字符串: 这种由双引号(Double Quote )引起来的一串字符称为字符串字面值( String Literal),或者简称字符串。比如第一个代码中的 "Just do it!\n"
#include <stdio.h>
int main()
{
    printf("Hello\n");
    printf("Just do it!\n");
    return 0; 
}
        5.2 转义字符:转义字符是以“\”为开头的字符,后面跟一个或几个字符,其意思是将反斜杠“\”后面的字符转变成为另外的意思。
转义字符 释义
\0 结束标志
\?
在书写连续多个问号时使用,防止他们被解析成三字母词
\'
用于表示字符常量 '
\"
用于表示一个字符串内部的双引号
\\
用于表示一个反斜杠,防止它被解释为一个转义序列符。
\a
警告字符,蜂鸣
\b
退格符
\f
进纸符
\n
换行
\r
回车
\t
水平制表符
\v
垂直制表符
\ddd
ddd 表示 1~3 个八进制的数字。 如: \130 
\xdd
dd 表示 2 个十六进制数字。 如: \x30         

        1.先给大家介绍一下结束标志\0

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

打印结果:

         字符串放在数组里面时,末尾会默认输入一个 \0,也就是说在数组char arr1 [ ]={"bit"}中,其实放入的内容有‘b’,‘i’,‘t’,‘\0’,所以打印完bit后就结束了,然而在数组char arr2 [ ]={‘b’,‘i’,‘t’}这种单独的字符时,末尾是不会默认输入\0 的,所以在打印完bit以后并没有结束打印,而是打印了一些随机值。故出现一些“烫烫烫烫烫烫烫烫烫烫烫烫烫烫蘠it”,如果手动在末尾输入 \0 时,就手动给了一个结束标志,如数组char arr3 [ ]={‘b’,‘i’,‘t’,‘\0’},打印完bit遇到了\0,那么就结束打印。

       

        2.转义字符 \? :在书写连续多个问号时使用,防止他们被解析成三字母词,三字母词存在于老一版的编译器中。

#include<stdio.h>
int main()
{
	printf("(are you ok\?\?)\n");//   \?在书写连续多个问号时使用,防止他们被解析成三字母词
	return 0;
}

打印结果:

  

        3.转义字符 \' 与 \" :只是单纯的为了输出单引号和双引号

#include<stdio.h>
int main()
{
	printf("\'");
	printf("\"");
	return 0;
}
打印结果:
        4.转义字符 \t :水平制表符,输出结果相当于一个按一次Tab健所拉开的距离
#include<stdio.h>
int main()
{
	printf("a\ta");
	return 0;
}

输出结果:

              其中两个字母a之间的间隔就是 \t 所拉开的一个Tab的距离
        5.转义字符\ddd和\xdd: ddd 表示 1~3个八进制的数字。 如: \130 ,
                                        
                                                dd 表示 2 个十六进制数字。 如: \x30
                                               打印时输出的是对应表示的进制转化为十进制后,十进制对应ASCII码表对应的字符。
#include<stdio.h>
int main()
{
	printf("\101\n");
	printf("\x42");
	return 0;
}

输出结果:

        其中八进制\101转化为十进制表示的数是65,十六进制\x42转化为十进制表示的数是66

          6.转义字符 \\: 用于表示一个反斜杠,防止它被解释为一个转义序列符,相当于将已经用 \ 转义的字符取消,如同双重否定是肯定的效果。而 \\ 在代码中还有一个最常用的用法,用来解释代码意思,方便理解相应代码的功能,也方便他人阅读。
#include<stdio.h>
int main()
{
	printf("c:\\test\41\test.c");       
	return 0;
}

输出结果:

          其中\t叫作水平制表符相当于以一个tab健的一个空格位置,为防止\t被识别成转义字符,规定\\为反斜杠,防止他被解释为一个转义字符,与双重否定是肯定的意思差不多,八进制数\41转化为十进制是33,对应的ASCII码字符为!,其它字符没有转义字符,就直接打印出来

        7.转义字符\a:警告字符,蜂鸣

#include<stdio.h>
int main()
{
	printf("\a");
	return 0;
}

         打印的时候会响一声“叮咚”

        8.转义字符\b:退格符

#include<stdio.h>
int main()
{
	printf("abcdef\b\b\b\b");
	return 0;
}

打印结果:

         \b表示向后退格,退到相应位置时,相应的字符将无法打印,在退格的时候有叠加效果,如上代码中一共输入4个\b,相应向后退4格,在输入的abcdef中倒数第四位c将无法打印

        9.转义字符\f:换页,将当前位置移到下一页的开头,在使用打印机时会直接换页,在编译器中表现不明显

        10.转义字符\v:垂直制表符,也用于打印时

        11.转义字符\r:回车,将当前位置移到本行的开头,并覆盖打印

#include<stdio.h>
int main()
{
	printf("abcdef\r");
	return 0;
}

打印结果:

        5.3 注释:1. 代码中有不需要的代码可以直接删除,也可以注释掉

                        2. 代码中有些代码比较难懂,可以加一下注释文字
        注释有两种风格:
                        C语言风格的注释 /*xxxxxx*/
                        缺陷:不能嵌套注释
                        C++风格的注释 //xxxxxxxx
                        可以注释一行也可以注释多行

以使用函数计算两个数的和为例:

#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>

int Add(int x, int y)
{
	return x + y;
}
/*C语言风格注释
int Sub(int x, int y)
{
    return x-y;
}
*/
int main()
{
	int a = 0;
	int b = 0;					//C++注释风格
	scanf("%d%d", &a, &b);		//用scanf取a,b的地址,能够随机赋值计算
	printf("sum=%d\n", Add(a, b));  //调用Add函数,完成加法
	return 0;
}

打印结果:

 

六、 选择语句:用if语句、switch case语句实现

        如果好好学习,就能找到好工作
        如果不学习,找不到好工作
        这就是选择!
例如用if语句实现:
#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
int main()
{
	int num = 0;
	printf("学习编程\n");
	printf("你能够坚持吗?(0不能/1能)");//>:为提示符
	scanf("%d", &num);
	if (1==num)
		printf("好工作,高薪资");
	else
		printf("平淡的生活");
	return 0;
}

七、循环语句:用while语句、for语句、do ... while语句实现

        有些事必须一直做,比如学习,应该日复一日

例如用while实现连续输入1-100的数字:

#include<stdio.h>
int main()						//代码功能:输出1-100的数字
{
	int a = 1;
	//int b = 0;
	while (a < 101)
	{
		printf(" %d", a );
		a += 1;			
	}
	return 0;
}

打印结果:

 八、函数:是简化代码,代码复用。

        8.1 库函数:当我们描述的基础功能,它们不是业务性的代码。我们在开发的过程中每个程序员都可能用的到,为了支持可移植性和提高程序的效率,所以C语言的基础库中提供了一系列类似的库函数,方便程序员进行软件开发。如:

        1. 我们知道在我们学习 C 语言编程的时候,总是在一个代码编写完成之后迫不及待的想知道结果,想 把这个结果打印到我们的屏幕上看看。这个时候我们会频繁的使用一个功能:将信息按照一定的格 式打印到屏幕上(printf )。
        2. 在编程的过程中我们会频繁的做一些字符串的拷贝工作( strcpy )。
        3. 在编程是我们也计算,总是会计算 n k 次方这样的运算( pow )。
        如果想了解更多C语言的更多库函数可以去C++官网查看:
        C++官网(英文版): cppreference.com
         C++官网(中文版): cppreference.com
对库函数简单的分类:
                                        1. IO函数
                                        2.字符串操作函数
                                        3.字符操作函数
                                        4.内存操作函数
                                        5.时间/日期函数
                                        6.数学函数
                                        7.其他库函数
:但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。

        8.2 自定义函数:如果库函数能干所有的事情,那就不需要程序员了, 所有更加重要的是自定义函数自定义函数和库函数一样,有函数名,返回值类型和函数参数。 但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间。

例如计算两个数的和:

#include <stdio.h>
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = num1 + num2;
    printf("sum = %d\n", sum);
    return 0; 
}

利用函数计算两个数的和:

#include <stdio.h>
int Add(int x, int y) 
{
   int z = x+y;
   return z; 
}
int main()
{
    int num1 = 0;
    int num2 = 0;
    int sum = 0;
    printf("输入两个操作数:>");
    scanf("%d %d", &num1, &num2);
    sum = Add(num1, num2);
    printf("sum = %d\n", sum);
    return 0;
}

        直接调用自己定义的函数int Add(int x, int y),就不需要重复的去敲代码,需要求两个数的和时直接调用函数就行了。

九、数组

        9.1 定义:一组相同类型元素的集合

                例:要存储1-10的数字,怎么存储?

int arr[10] = {1,2,3,4,5,6,7,8,9,10};//定义一个整形数组,最多放10个元素
         9.2 数组的下标: C 语言规定,数组的每个元素都有一个下标,下标是从 0 开始的。
数组可以通过下标来访问的。
                
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
//如果数组10个元素,下标的范围是0-9

数组中各值对应的下标:

打印数组里面的数值:

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

 打印结果:

 十、操作符:算术操作符、移位操作符、位操作符、赋值操作符

        10.1 算术操作符:+        -        *(乘号)        /(除号)        %(取余)

        1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
        2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
        3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
	int a = 0;
	int b = 1;        //对b赋的初始值不能为0,因为在后面要作为除数
	int c = (-8 + 22) * a - 10 + b / 2;
	int d = a % b;
	scanf("%d%d", &a, &b);
	printf("计算结果=%d\n", c);
	printf("取余=%d\n", d);
	return 0;
}

打印结果:

         10.2 移位操作符:        <<左移操作符        >>右移操作符

        1.移位操作符的操作数只能是整数
        2.针对的是十进制转化为二进制后,对二进制的数值进行移位,
        3.左移操作符,左边舍去右边补零
        4.对于移位运算符,不要移动负数位,这个是标准未定义的

int main()
{
	int a = 1;//int型有4个字节32个比特位转化为二进制00000000000000000000000000000001  转化为十进制就为1
	int b=a << 2;                               //00000000000000000000000000000100  转化为十进制就为4
    int b=a<<-1;//错误的移位
	printf("%d", b);
	return 0;
}

打印结果:

        移位操作符是针对二进制数进行移位,例如上述代码中int类型4个字节=4x8=32位,将对应的整数先转化为32位的二进制数,在对二进制数进行移位,移位遵循——左移操作符时,左边舍去右边补零;右移操作符时,右边舍去左边补零。最后再将移位后的二进制数转化为十进制数打印出来。

        10.3 位操作符:     &按位与    |按位或    ^按位异或(均是对二进制进行)

#include<stdio.h>

int main()
{
	int a = 1;			//0001
	int b = 2;			//0010
	printf("%d\n", a & b);			//0000
	printf("%d\n", a | b);			//0011
	printf("%d\n", a ^ b);			//0011     相同为0不同为1
	return 0;
}


打印结果:

         10.4 赋值操作符:=        +=         -=         *=         /=         &=         ^=          |=            >>=   <<=                

        赋值操作符是一个很棒的操作符,他可以让你得到一个你之前不满意的值。也就是你可以给自己重新赋值。
        10.5 单目操作符:
操作符 作用
逻辑反操作
- 负值
+ 正值
& 取地址
sizeof 操作数类型长度(以字节为单位)
~ 对一个数的二进制按位取反
-- 前置、后置--
++ 前置、后置++
* 间接访问操作费(解引用操作法)
(类型) 强制类型转换

                前五个操作符在前面已经介绍了,我向大家介绍后面五种就行

        1.对一个数的二进制按位取反~:~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0,例:十六进制9对应:0x00000009   当取反时~9对应:0xfffffff6

#include<stdio.h>
main()
{
	int a = 0;
	printf("%x", ~a);
}

打印结果:

        2.前置、后置++:前置++作用是先进行运算再赋值,而后置++为先先复制后运算

前置++:

#include <stdio.h>
main()
{
	int i = 2;
	int a=++i;
	int b = i;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
}

打印结果:

         代码中我们先给 i 一个初始值2,用b来反应 i 最终的值。前置++是先对2进行+1运算,然后将加上1后的值3赋给变量a,故a的值为3,经过运算和赋值后 i 的值变为3,故将i变化后的值3赋给b,故b的值为3

后置++:

#include <stdio.h>
main()
{
	int i = 2;
	int a = i++;
	int b = i;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
}

打印结果:

         代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。后置++是先 i 的值2先赋给a,然后对 i 加1,则a的值为2,经过赋值和运算后 i 的值变为3,故将 i 变化后的值3赋给b,故b的值为3。

        3.前置、后置--:

前置--:

#include <stdio.h>
main()
{
	int i = 2;
	int a = --i;
	int b = i;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
}

打印结果:

         代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。前置--是先对2进行-1运算,然后将减去1后的值1赋给变量a,故a的值为1,经过运算和赋值后 i 的值变为1,故将 i 变化后的值1赋给b,故b的值为1

后置--:

#include <stdio.h>
main()
{
	int i = 2;
	int a = i--;
	int b = i;
	printf("a=%d\n", a);
	printf("b=%d\n", b);
}

打印结果:

        代码中我们先给 i 一个初始值2,用b来反映 i 最终的值。后置--是先 i 的值2先赋给a,然后对 i 减1,则a的值为2,经过赋值和运算后 i 的值变为1,故将 i 变化后的值1赋给b,故b的值为1。

        4.间接访问操作费(解引用操作法) *:该操作符常用于指针

#include<stdio.h>
int main()
{
	int a = 10;
	int* p= &a;
	*p =20;
	printf("%d\n", a);
	return 0;
}

 打印结果:

         想要了解此代码需要先了解指针的概念,可先往下翻,初步了解指针。代码中*p=20;其中的*就是解引用操作符,意思是通过p中存放的地址,找到p所指向的对象,而*p就是p所指向的对象,其代表的就是变量a。

        5.强制类型转换(类型):

#include<stdio.h>
int main()
{
	double a = 3.14;
	printf("%d\n", (int)a);
	return 0;
}

打印结果:

         原本定义的变量是double型,在(类型)的强制转换下,将变量a转换为int类型,使用该操作符时,将需呀转化的类型放入括号内,将需要转化的变量紧放其后切只对一个变量有效,如果在()后有两个变量,则只对紧跟的第一个变量有效该转换只能在该语句生效,并且在其他地方,变量a仍然是double类型。

        10.6 关系操作符:
> 大于
>= 大于等于
< 小于
<= 小于等于
!= 用来测试“不相等”
== 用来测试“相等”

        10.7 逻辑操作符:
&& 逻辑与
|| 逻辑或

        10.8 条件操作符: exp1 ? exp2 : exp3
        10.9 逗号表达式: exp1 , exp2 , exp3,......expN
        10.10. 下标引用、函数调用和结构成员:         []         ()         .          ->

十一、常见关键字:C语言提供了丰富的关键字,这些关键字都是语言本身预先设定好的,用户自己是不能创造关键字的。

auto           break            case           char           const            continue           default           do          ​ double         else           enum           extern         float           for            goto           if            int            long           register             return            short           signed                 sizeof           static         struct   switch           typedef        union           unsigned           void           volatile           while
十二、#define 定义常量和宏
        12.1 #define 定义常量
#include(stdio.h)
#define c 100
int main()
{
	printf("%d\n", c);
	int d = 100;
	printf("%d", d);
	return 0;
}

打印结果:

         12.2 #define 定义宏:

#include<stdio.h>
#define add(x,y)(x)+(y)    //宏名  参数 宏体
int main()
{
	int a = 10;
	int b = 20;
	int c = add(a, b);    //替换成int c=((a)+(b))
	printf("%d", c);
	return 0;
}

打印结果:

 十三、 指针

        13.1 想了解指针需要先了解一下内存:内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

        内存单元有相对应的编号,这一个编号就是地址,这个地址也叫做指针,也就是说地址就是指针,用来储存地址的变量叫指针变量。

        如何取出变量的地址呢?就要用到前面介绍的取地址符&

#include <stdio.h>
int main()
{
 int num = 10;
 &num;//取出num的地址。注:这里num的4个字节,每个字节都有地址,取出的是第一个字节的地址(较小的地址)
 printf("%p\n", &num);//打印地址,%p是以地址的形式打印
 return 0;
 }

        &num的作用就是取出创建的变量num的地址

内存
一个字节 0xFFFFFFFF
一个字节 0xFFFFFFFE
一个字节 0xFFFFFFFD
0x0012FF47
0x0012FF46
0x0012FF45
0x0012FF44
一个字节 0x00000002
一个字节 0x00000001
一个字节 0x00000000

        变量num的类型是int类型,其大小为4个字节,红色的部分为num的地址,打印的地址就是读取到num的第一个地址。

        变量取出来后如果需要储存,就需要定义指针变量:

int num = 10;
int* p=&num;            //int说明指针变量p所指的变量num是一个整形

指针的具体使用:

#include<stdio.h>
int main()
{
	int a = 10;
	int* p= &a;
	*p =20;
	printf("%d\n", a);
	return 0;
}

打印结果:

        定义一个整型的变量a=10,用&a取出变量a的地址并放入指针变量p中,指针变量p的类型(也就是a的类型)是整型,用解引用符找到p变量的指向对象(a),并对指向对象重新赋值20,打印a的结果时发现打印的就是第二次赋值的20。
        13.2 指针变量的大小,用到前面所介绍的sizeof
#include<stdio.h>
int main()
{
    printf("%d\n", sizeof(char *));
    printf("%d\n", sizeof(short *));
    printf("%d\n", sizeof(int *));
    printf("%d\n", sizeof(double *));
    return 0; 
}

打印结果:

         结论:指针大小在32位平台是4个字节,64位平台是8个字节。

十四、结构体:结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂类型。
比如描述学生,学生包含: 名字+年龄+性别+学号 这几项信息。 这里只能使用结构体来描述了,具体就是把单一的类型组合在一起。
#include<stdio.h>
struct xs				//定义结构体类型要用struct,这个类型名叫xs(自己定义)
{
	char name[20];   //叫做结构体成员,其中要放的是字符串,需要将字符串放到字符串数组里面  
	int age ;
	char sex[10];
	char id[15];
};
void project(struct xs* dy)   //自定义函数project,将s的地址赋给dy,*dy表示的是s
{
	printf("%s %d %s %s\n", (*dy).name, (*dy).age, (*dy).sex, (*dy).id);			
	printf("%s %d %s %s\n", dy->name, dy->age, dy->sex, dy->id);
}
int main()
{
	struct xs s = { "张三", 21 ," 男 ","20209999" };//s为创建的结构体变量,访问其对象时,需要加.这个操作符
	printf("%s %d %s %s\n", s.name, s.age, s.sex, s.id);
	project(&s);           //自定义函数,取s的地址给自定义的函数
	return 0;
}

打印结果:

         上面展示了结构体的三种打印方式,其中放在project()函数里面的是利用指针打印,外面的那一种是直接打印不用创建指针。在函数内的打印方式和外面的那一种差别不大。

函数外:打印时填入需要打印的类型,最后在后面写上   结构体变量(s).字符串的变量名(name、age、sex、id)   这种格式打印

函数内:将结构体变量名用指针来代替,只是改变的形式,但没改变本质,最后将操作符“.”改成  “->”就行

猜你喜欢

转载自blog.csdn.net/m0_64616721/article/details/124147903