C语言初级概念区分

一、C输入输出函数

1.1 sprintf()     stdio.h

        sprintf()函数的功能非常强大:效率比一些字符串操作函数要高;可以将想要的结果输出到指定的字符串中,也可作为缓冲区,而printf只能输出到命令行上。

函数功能:格式化字符串,将格式化的数据写入字符串中。

函数原型int sprintf(char *buffer, const char *format, [argument]...)

参数:

(1)buffer:是char类型的指针,指向写入的字符串指针;

(2)format:格式化字符串,即在程序中想要的格式;

(3)argument:可选参数,可以为任意类型的数据;

        函数返回值:buffer指向的字符串的长度;

用处:

(1)格式化数字字符串:在这点上sprintf和printf的用法一样,只是打印到的位置不同而已,前者打印给buffer字符串,后者打印给标准输出,所以sprintf也可以用来将整型转化为字符串,比itoa效率高且如此地简便~比如:sprintf(buffer, "%d", 123456);执行后buffer即指向字符串“123456”

sprintf(sendline, "$%2.2f %c %2.2f %c %2.2f!", gnrmc.Latitude, gnrmc.Latitude_, gnrmc.Longitude, gnrmc.Longitude_, gnrmc.Height);

输出sendline时候,$22.00空格E22.00空格E0.00!

(2)连接字符:

(a)连接以'\0'结束的字符串:

#include<stdio.h>  
int main()  
{  
    char buffer[10];  
    char *a = "1234";  
    char *b = "5678";  
    sprintf(buffer, "%s%s", a, b);  
    printf("%s\n", buffer);  
    return 0;  
}  

(b)连接结尾没有'\0'的字符数组或字符串缓冲区:  注意这里加了格式控制符

#include<stdio.h>
int main()
{
	char a[] = {'1', '2', '3', '4'};
	char b[] = {'5', '6', '7', '8'};
	char buffer[10];
	sprintf(buffer, "%.4s%.4s", a, b);
	printf("%s\n", buffer);
	return 0;
}

 

 (c)如果我们想动态获取要处理的字符缓冲区长度,则将上面sprintf改为:sprintf(buffer, "%.*s%.*s", sizeof(a), a, sizeof(b), b);即可

1.2 sscanf()

sscanf的作用:从一个字符串中读进于指定格式相符的数据。利用它可以从字符串中取出整数、浮点数和字符串。

sscanf和scanf的区别:scanf是以键盘作为输入源,sscanf是以字符串作为输入源。

int sscanf(const char *str, const char *format,......);

sscanf()会将参数str的字符串根据参数format字符串来转换格式并格式化数据。转换后的结果存于对应的参数内。                成功则返回参数数目,失败则返回0

作用:

1. 取指定长度的字符串

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("12345","%4s",str);
	printf("%s\n",str);
	return 0;
}

2. 格式化时间

#include<stdio.h>
#include<string.h>
int main()
{
	int year, month, day, hour, minute, second;
	sscanf("2013/02/13 14:55:34","%d/%d/%d %d:%d:%d",&year, &month, &day, &hour, &minute, &second);
	printf("time=%d-%d-%d %d:%d:%d\n", year, month, day, hour, minute, second);
	return 0;
}

 3. 读入字符串

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("12345","%s",str);
	printf("%s\n",str);
	return 0;
}

4. %*d和%*s加了(*)表示跳过此数据不读入(也就是不把此数据读入参数中)

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("1234abcd","%*d%s",str);
	printf("%s\n",str);
	return 0;
}

5.  取到指定字符为止的字符串。如例子所示,遇到‘+’为止的字符串。

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("1234+abc","%[^+]",str);
	printf("%s\n",str);
	return 0;
}

6. 取到指定字符集为止的字符串。如遇到小写字母为止的字符串。

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("1234+abc1234","%[^a-z]",str);
	printf("%s\n",str);
	return 0;
}

7. 取仅包含指定字符集的字符串。(取仅包含数字和小写字母的字符串,是取得连续的字符串)。

#include<stdio.h>
#include<string.h>
int main()
{
	char str[100];
	sscanf("123456abcdefBFRGTY7890","%[1-9a-z]",str);
	printf("%s\n",str);
	return 0;
}

1.3 printf输入输出格式及格式控制字符

二、U32、U16、U8等

typedef unsigned int u32;//无符号整型
typedef unsigned short u16;
typedef unsigned char u8;

注意:使用时不要超出数据长度

三、extern等关键字  extern 和const和static的区别

        extern放在变量或者函数之前,表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。

        extern用在变量声明中常常有这样一个作用,在*.c文件中声明了一个全局的变量,这个全局的变量如果要被引用,就放在*.h中并用extern来声明。

         extern "C" void fun(int a, int b);则告诉编译器在编译fun这个函数名时按着C的规则去翻译相应的函数名而不是C++的。

        当extern不与"C"在一起修饰变量或函数时,如在头文件中: extern int g_Int; 它的作用就是声明函数或全局变量的作用范围的关键字,其声明的函数和变量可以在本模块活其他模块中使用,记住它是一个声明不是定义!也就是说B模块(编译单元)要是引用模块(编译单元)A中定义的全局变量或函数时,它只要包含A模块的头文件即可,在编译阶段,模块B虽然找不到该函数或变量,但它不会报错,它会在连接时从模块A生成的目标代码中找到此函数。

四、头文件、.C的写法

4.1 头文件    要注意的时当你在调用时头文件要这样写:#include"hacker.h"

变量定义:用于为变量分配存储空间,还可为变量指定初始值。程序中,变量有且仅有一个定义。

变量声明:用于向程序表明变量的类型和名字。

                定义也是声明,extern声明不是定义

        在一个程序中,变量只能定义一次,却可以声明多次。

int a;和int a=0;都是定义。extern int a;算是声明

在.h文件中定义
extern int err ;
extern const char* device_name;		
//配置一个数据缓冲区用来缓冲数据
extern char* buffer;
extern int buffer_frames;	//每次从声卡获取的样本数量
extern int frame_byte;			//一帧PCM数据的大小
extern unsigned int rate ;
.c文件中定义
int err=0;
const char* device_name = "hw:0";//default
int buffer_frames = 1024;
int frame_byte = 0;
unsigned int rate = AUDIO_RATE_SET;
snd_pcm_t* capture_handle;
snd_pcm_hw_params_t* hw_params;

头文件里面放的自然就是关于函数,变量,类的“声明”了。记着,是“声明”,不是“定义”。

#ifndef _XX_头文件.H
#define _XX_头文件.H
int A;
#endif

    那么,很糟糕的是,这里的int A是个全局变量的定义,所以如果这个头文件被多次引用的话,你的A会被重复定义
    显然语法上错了。只不过有了这个#ifndef的条件编译,所以能保证你的头文件只被引用一次,不过也许还是会岔子,但若多个c文件包含这个头文件时还是会出错的,因为宏名有效范围仅限于本c源文件,所以在这多个c文件编译时是不会出错的,但在链接时就会报错,说你多处定义了同一个变量,

函数的声明

宏定义

变量的声明

能在头文件中写形如:extern int a;和void f();的句子。这些才是声明。

//#ifendif防止多次包含一个文件
#ifndef HACKER_H_
#define HACKER_H_ 

#endif     //防止文件被重复包含 

五、指针、函数、常量、数组的关系

六、sizeof测指针字符串、strlen、\0、结构体大小、字节对齐等关系   大小端问题

windows操作系统,32位机中,未测试,     Linux操作系统,64位机中,貌似Windows  long是8字节

char:    1个字节                        char:    1个字节

short:   2个字节                        ​​​​​​​short:   2个字节

int:       4个字节                        int:       4个字节

long:    4个字节                        long:    8个字节

long、short只能修饰int数据类型                unsigned可修饰任意数据类型,不影响数据所占字节数,但是会影响数据的表示长度

sizeof(int)=4,        sizeof(char)=1,
sizeof(float)=4,      sizeof(double)=8
unsigned int     u32的占用内存大小:4	
unsigned short   u16的占用内存大小:2	
unsigned char    u8的占用内存大小:1	
64位Linux系统中,一个指针的大小是8个字节

6.1 sizeof

6.2 strlen

strlen:测试长度不包括\0

6.3 结构体大小、字节对齐

不同系统下的C语言类型长度

 许多计算机系统对基本数据类型合法地址做出了一些限制,要求某种类型对象的地址必须是某个值K(通常是2,4或8)的倍数。这种对齐限制简化了形成处理器和存储器系统之间的接口的硬件设计。对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的.

需要字节对齐的根本原因在于CPU访问数据的效率问题。例如,假设一个处理器总是从存储器中取出8个字节,则地址必须为8的倍数。如果我们能保证将所有的double类型数据的地址对齐成8的倍数,那么就可以用一个存储器操作来读或者写值了。否则,我们可能需要执行两次存储器访问,因为对象可能被分放在两个8字节存储块中。
另外,假设一个整型变量的地址不是自然对齐,比如为0x00000002,则CPU如果取它的值的话需要访问两次内存,第一次取从0x00000002-0x00000003的一个short,第二次取从0x00000004-0x00000005的一个short然后组合得到所要的数据;如果变量在0x00000003地址上的话则要访问三次内存,第一次为char,第二次为short,第三次为char,然后组合得到整型数据。而如果变量在自然对齐位置上,则只要一次就可以取出数据。
先让我们看编译器是按照什么样的原则进行对齐的:

1.  数据类型自身的对齐值:为指定平台上基本类型的长度。对于char型数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4,单位字节。
2. 结构体或者类的自身对齐值:其成员中自身对齐值最大的那个值。
3. 指定对齐值:#pragma pack (value)时的指定对齐值value。
4. 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个值。

对于标准数据类型,它的地址只要是它的长度的整数倍就行了,而非标准数据类型按下面的原则对齐:
数组 :按照基本数据类型对齐,第一个对齐了后面的自然也就对齐了。
联合 :按其包含的长度最大的数据类型对齐。
结构体: 结构体中每个数据类型都要对齐。

结构体对齐规则:

1) 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。

 2) 结构体的自身对齐值:其成员中自身对齐值最大的那个值。

 3) 指定对齐值:#pragma pack (value)时的指定对齐值value。默认是4。

 4) 数据成员、结构体的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。

字节对齐的规则总结_gaoyi221119的博客-CSDN博客_字节对齐规则

这篇文章把字节对齐以及字节对齐的计算方式写的很详细

七、端口、IP、DNS、域名、防火墙、固定IP、默认网关等等

八、字符串处理

1. strcpy函数    将2复制到1中,并覆盖原始字符串

原型:strcpy(str1,str2);

功能:将字符串str2复制到字符串str1中,并覆盖str1原始字符串,可以用来为字符串变量赋值

返回:str1

2.strncpy函数

原型:strncpy(str1,str2,n);

功能:将字符串str2中的前n个字符复制到字符串str1的前n个字符中

返回:str1

1)不会清除str1中全部字符串,只会改变前n个字符串,

2)n不能大于字符串str1、str2的长度

3)但是如果使用strncpy_s便会清除str1中的全部字符串

3.strcat函数   拼接两个字符串

原型:strcat(str1,str2);

功能:将字符串str2添加到字符串str1的尾部,也就是拼接两个字符串

返回:str1

4.strncat函数

原型:strncat(str1,str2,n);

功能:将字符串str2的前n个字符添加到字符串str1的尾部

返回:str1

注意:拼接之后的长度不能超过字符串数组str1的长度

5.strlen函数

原型:strlen(str1);

功能:计算字符串str1的长度

返回:一个int值

注意:字符串的长度不包括字符'\0'

6. 字符串转数字atoi、atof、atol函数

atoi(str);    //字符串转换到int整型

atof(str);    //字符串转换到double浮点数

atol(str);    //字符串转换到long整形

九、Http、TCP、UDP区别

9.1 Http

HTTP协议格式详解(总结)_近未来-CSDN博客_http

        超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。

        HTTP 是应用层协议,HTTP 用的是下层的 TCP协议,而 TCP 是保证可靠性的。
TCP 为了保证可靠性,所以 TCP 是面向连接的。

        HTTP是基于客户/服务器模式,且面向连接的。典型的HTTP事务处理有如下的过程:

(1)客户与服务器建立连接;

(2)客户向服务器提出请求;

(3)服务器接受请求,并根据请求返回相应的文件作为应答;

(4)客户与服务器关闭连接。

十、注释、函数名、变量名规则

十一、C++程序占用内存

1.程序代码区

2.常量

3.堆区:new malloc

4.栈区:局部变量,函数参数,由编译器自动分配释放

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_42475191

谢谢老板

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值