黑马程序员-②C语言查漏补缺总结 (下)

----- <a href="http://www.itheima.com" target="blank">ios培训</a>、<a href="http://www.itheima.com" target="blank">ios培训</a>、期待与您交流! ---------

变量的作用域

1.局部变量

1>定义:在函数内部定义的变量,称为局部变量。形式参数也属于局部变量。

2>作用域:局部变量只在定义它的函数内部有效,即局部变量只有在定义它的函数内部使用,其它函数不能使用它。

float(int a)
{int b ,c;
} //b,c在函数float有效
int main()
{int m,n;
return 0;
}m,n在main函数有效

2.全局变量

1>定义:在所有函数外部定义的变量,称为全局变量。

2>作用域:全局变量的作用范围是从定义变量的位置开始到源程序结束,即全局变量可以被在其定义位置之后的其它函数所共享。

int p = 1,q = 5;//p,q全局变量,整个程序都有效
float(int a)
{int b ,c;
}//b,c只在float函数中有效
int main()
{int m,n;
rerurn 0;
}m,n在main函数有效

 

局部变量的存储类型

变量的存储类型就是指变量存储在什么地方。有3个地方可以用于存储变量:普通内存、运行时堆栈、硬件寄存器。变量的存储类型决定了变量何时创建、何时销毁以及它的值能保持多久,也就是决定了变量的生命周期。

* C语言根据变量的存储类型的不同,可以把变量分为:自动变量、静态变量、寄存器变量。

1.自动变量(auto变量)

  1.定义:自动变量是存储在堆栈中的。

  2.哪些是自动变量:被关键字auto修饰的局部变量都是自动变量,但是极少使用这个关键字,基本上是废的,因为所有的局部变量在默认情况下都是自动变量。

  3.生命周期:在程序执行到声明自动变量的代码块(函数)时,自动变量才被创建;当自动变量所在的代码块(函数)执行完毕后,这些自动变量就会自行销毁。如果一个函数被重复调用,这些自动变量每次都会重新创建。

2.静态变量(static变量)

  1. 定义:静态变量是存储在静态内存中的,也就是不属于堆栈。

  2. 哪些是静态变量:

·          所有的全局变量都是静态变量

·          被关键字static修饰的局部变量也是静态变量

  3. 生命周期:静态变量在程序运行之前创建,在程序的整个运行期间始终存在,直到程序结束。

3.寄存器变量(registe变量

  1. 定义:存储在硬件寄存器中的变量,称为寄存器变量。寄存器变量比存储在内存中的变量访问效率更高(默认情况下,自动变量和静态变量都是放在内存中的)

  2. 哪些变量是寄存器变量:

·          被关键字register修饰的自动变量都是寄存器变量

·          只有自动变量才可以是寄存器变量,全局变量和静态局部变量不行

·          寄存器变量只限于int、char和指针类型变量使用

  3. 生命周期:因为寄存器变量本身就是自动变量,所以函数中的寄存器变量在调用该函数时占用寄存器中存放的值,当函数结束时释放寄存器,变量消失。

  4. 使用注意:

·          由于计算机中寄存器数目有限,不能使用太多的寄存器变量。如果寄存器使用饱和时,程序将寄存器变量自动转换为自动变量处理

·          为了提高运算速度,一般会将一些频繁使用的自动变量定义为寄存器变量,这样程序尽可能地为它分配寄存器存放,而不用内存

全局变量的存储类别

1. 在一个文件内扩展外部变量的作用域

   1.如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件结束

   2.关键字extern对变量作“外部变量声明”,表示把该外部变量的作用域扩展到此位置

2. 将外部变量的作用域扩展到其它文件

3. 将外部变量的作用域限制在本文件中

file.c              file2.c
static int A;       extern A;
int main()          void fun(int n)
{                   {
……                 A = A*n  // 出错
}                    }
   这种加上static声明,只能用于本文件的外部变量称为静态外部变量
结构体

定义结构体类型

struct 结构体名
    {成员列表};

定义结构体变量的3种方式

 1> 先定义类型,再定义变量(分开定义)

 struct Student
 {
 int age;
 };
 struct Student stu;
 2> 定义类型的同时定义变量
 struct Student
 {
 int age;
 } stu;
 struct Student stu2;
 3> 定义类型的同时定义变量(省略了类型名称)
 struct
 {
 int age;
 } st;

结构体类型的作用域

  定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
  定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)

结构体注意点
  1.不允许对结构体本身递归定义
  2.结构体内可以包含别的结构体
  3.定义结构体类型,只是说明了该类型的组成情况,并没有给它分配存储空间,就像系统不为int类型本身分配空间一样。只有当定义属于结构体类型的变量时,系统才会分配存储空间给该变量
  4.结构体变量占用的内存空间是其成员所占内存之和,而且各成员在内存中按定义的顺序依次排列

结构体和数组
  数组:只能由多个相同类型的数据构成
  结构体:可以由多个不同类型的数据构成

指向结构体的指针
  每个结构体变量都有自己的存储空间和地址,因此指针也可以指向结构体变量
  结构体指针变量的定义形式:struct 结构体名称 *指针变量名
  有了指向结构体的指针,那么就有3种访问结构体成员的方式
1. 结构体变量名.成员名
2. (*指针变量名).成员名
3. 指针变量名->成员名

枚举类型
声明形式

enum [枚举名]{枚举元素列表};
enum Sex { Man, Woman, Unkown};


预处理指令
 1.所有的预处理指令都是以#开头
 2.预处理指令分3种: 宏定义,条件编译,文件包含
 3.预处理指令在代码翻译成0和1之前执行
 4.预处理的位置是随便写的
 5.预处理指令的作用域:从编写指令的那一行开始,一直到文件结尾,可以用#undef取消宏定义的作用
 6.宏名一般用大写或者以k开头,变量名一般用小写

一、不带参数的宏定义
1.一般形式
 #define 宏名 字符串 
 比如#define ABC 10
 右边的字符串也可以省略,比如#define ABC
2.作用
它的作用是在编译预处理时,将源程序中所有"宏名"替换成右边的"字符串",常用来定义常量。
接下来写个程序根据圆的半径计算周长
3.使用习惯与注意
1> 宏名一般用大写字母,以便与变量名区别开来,但用小写也没有语法错误
2> 对程序中用双引号扩起来的字符串内的字符,不进行宏的替换操作。
3> 在编译预处理用字符串替换宏名时,不作语法检查,只是简单的字符串替换。只有在编译的时候才对已经展开宏名的源程序进行语法检查
4> 宏名的有效范围是从定义位置到文件结束。如果需要终止宏定义的作用域,可以用#undef命令
5> 定义一个宏时可以引用已经定义的宏名

二、带参数的宏定义
1.一般形式
#define 宏名(参数列表) 字符串
2.作用
在编译预处理时,将源程序中所有宏名替换成字符串,并且将字符串中的参数 用宏名右边参数列表中的参数替换
3.使用注意
1> 宏名和参数列表之间不能有空格,否则空格后面的所有字符串都作为替换的字符串
2> 带参数的宏在展开时,只作简单的字符和参数的替换,不进行任何计算操作。所以在定义宏时,一般用一个小括号括住字符串的参数。
3> 计算结果最好也用括号括起来

宏定义与函数的区别
从整个使用过程可以发现,带参数的宏定义,在源程序中出现的形式与函数很像。但是两者是有本质区别的:
1> 宏定义不涉及存储空间的分配、参数类型匹配、参数传递、返回值问题
2> 函数调用在程序运行时执行,而宏替换只在编译预处理阶段进行。所以带参数的宏比函数具有更高的执行效率

利用条件编译防止头文件多次包含

#ifndef LISI_H
#define LISI_H
int sum(int a, int b);
#endif
typedef声明

1.简单地用一个新的类型名代替原有的类型名

typedef int Integer;//指定Integer为类型名,作用域int相同
typedef float Real;//指定Real为类型名,作用域float相同
2.命名一个简单地类型名代替复杂的类型表示方法

typedef struct
{int month;
int day;
int year;
}Date;//类型名Date代表上面的一个结构体类型
Date birthday;//定义结构体变量birthday
利用以上知识完成一个小程序

/*找出多个字符串中的最大公共子字符串*/
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#define N 6    //输入的字符串个数

//返回string字符串中从第start字符开始后length个字符
char * string(char * string,int start,int length)
{
	char *string3;
	int i,j=0;
	string3=(char *)malloc(100);
	for(i=start;i<start+length;i++)
	{
		string3[j]=*(string+i);
		j++;
		
	}
	string3[j]='\0';
	return string3;
}
//将第一个字符串与最短的字符串交换
void swap(char (*pStr)[100],int i)
{
    char temp[100];
    strcpy(temp,pStr);
    strcpy(pStr,pStr+i);
    strcpy(pStr+i,temp);
}

int main()
{
	
    char str[N][100];//定义二维字符数组
	int i,min=0,len,len0;
	int minlen,j,k,maxlen=0;
	char * maxStr;
    char * tmpStr;
	char (* pStr)[100];
	printf("请输入%d个字符串:\n",N);
	for(i=0;i<N;i++)//输入N字符串
		gets (str[i]);
    pStr=str;
	minlen=strlen(str[0]);//把第一个字符串的长度赋给minlen
    //找出输入的字符串中长度最小的串,并把最小串序号记在min中
    for(i=0;i<N;i++)
	{
		len=strlen(str[i]);
		if(len<minlen)
		{
			minlen=len;
			min=i;
		}
	}
    swap(pStr,min);
	len0=strlen(str[0]);//把长度最小的串的长度赋给len0
	//对字符串数组中第一个子串,求出其可能的子串值,如果剩余子串长度小于maxlen则不用去求了,for循环中给出了限制
	for(i = 0; i < len0 && maxlen <= len0 - i-1; ++i)
    {
        for(j = 1; j <= len0-i; ++j)
        {
            tmpStr=string(str[0],i,j);
            //将子串tmpStr与参与匹配的字符串比较,判断tmpStr是否为剩余串的子串,如果不是则break出循环
            for(k = 1; k < N; ++k)
            {
                if(strstr(str[k],tmpStr))
                    continue;
                else
                    break;
            }
            if(k == N)//说明子串tmpStr是其他参与匹配的子串的子串
            {
                if(strlen(tmpStr)>maxlen)//tmpStr如果是当前最大的子串,则记录下来
                {
                    maxlen = strlen(tmpStr);
                    maxStr = tmpStr;
                }
            }
        }
    }
	printf("最长子字符串为:\n");
	puts(maxStr);//输出maxStr
    return 0;
}

                
【6层】一字型框架办公楼(含建筑结构图、计算书) 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
深度学习是机器学习的一个子领域,它基于人工神经网络的研究,特别是利用多层次的神经网络来进行学习和模式识别。深度学习模型能够学习数据的高层次特征,这些特征对于图像和语音识别、自然语言处理、医学图像分析等应用至关重要。以下是深度学习的一些关键概念和组成部分: 1. **神经网络(Neural Networks)**:深度学习的基础是人工神经网络,它是由多个层组成的网络结构,包括输入层、隐藏层和输出层。每个层由多个神经元组成,神经元之间通过权重连接。 2. **前馈神经网络(Feedforward Neural Networks)**:这是最常见的神经网络类型,信息从输入层流向隐藏层,最终到达输出层。 3. **卷积神经网络(Convolutional Neural Networks, CNNs)**:这种网络特别适合处理具有网格结构的数据,如图像。它们使用卷积层来提取图像的特征。 4. **循环神经网络(Recurrent Neural Networks, RNNs)**:这种网络能够处理序列数据,如时间序列或自然语言,因为它们具有记忆功能,能够捕捉数据中的时间依赖性。 5. **长短期记忆网络(Long Short-Term Memory, LSTM)**:LSTM 是一种特殊的 RNN,它能够学习长期依赖关系,非常适合复杂的序列预测任务。 6. **生成对抗网络(Generative Adversarial Networks, GANs)**:由两个网络组成,一个生成器和一个判别器,它们相互竞争,生成器生成数据,判别器评估数据的真实性。 7. **深度学习框架**:如 TensorFlow、Keras、PyTorch 等,这些框架提供了构建、训练和部署深度学习模型的工具和库。 8. **激活函数(Activation Functions)**:如 ReLU、Sigmoid、Tanh 等,它们在神经网络中用于添加非线性,使得网络能够学习复杂的函数。 9. **损失函数(Loss Functions)**:用于评估模型的预测与真实值之间的差异,常见的损失函数包括均方误差(MSE)、交叉熵(Cross-Entropy)等。 10. **优化算法(Optimization Algorithms)**:如梯度下降(Gradient Descent)、随机梯度下降(SGD)、Adam 等,用于更新网络权重,以最小化损失函数。 11. **正则化(Regularization)**:技术如 Dropout、L1/L2 正则化等,用于防止模型过拟合。 12. **迁移学习(Transfer Learning)**:利用在一个任务上训练好的模型来提高另一个相关任务的性能。 深度学习在许多领域都取得了显著的成就,但它也面临着一些挑战,如对大量数据的依赖、模型的解释性差、计算资源消耗大等。研究人员正在不断探索新的方法来解决这些问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值