C语言一些需要注意的点

前言

重新看了下《C程序设计语言》这本书,有了一些新的收获。

关于变量

程序块(就是两个花括号之间)可以声明和初始化变量,这些变量是只限于花括号内的局部变量,花括号外并不能引用它们。

#include <stdio.h>

int main()
{
	extern int add(int a, int b);
	int a = 1,b = 2;
	if(1)
	{
		int a = 2;
		int c = 3;
		printf("%d", a);
	}
	//printf("%d", c);
}

执行程序,输出 a 的结果为 2 ,如果注释掉 printf("%d", c); ,程序会报“未声明标识符‘c’”的错误。

关于extern

extern 是用来声明外部变量的,以下两种写法等效。

#include <stdio.h>

//int add(int a,int b);
int main()
{
	extern int add(int a, int b);
	int a = 1,b = 2;
	a = add(a, b);
	printf("%d", a);
}


int add(int a, int b)
{
	a = a + b;
	return a;
}
#include <stdio.h>

int add(int a,int b);
int main()
{
	int a = 1,b = 2;
	a = add(a, b);
	printf("%d", a);
}


int add(int a, int b)
{
	a = a + b;
	return a;
}

关于 include

有两种用法:

#include "文件名"
#include <文件名>

无论是哪种形式,include 所在的行都会被替换为由文件名指定的文件的内容。如果使用 “”,则在源文件所在的位置查找该文件;如果使用 <>,则根据相应的规则查找文件。

关于命令行参数

最简单的例子是程序 echo 。在 Linux 上执行命令:

echo hello, world

会有如下结果
C语言一些需要注意的点

这里 hello,world 被当成了参数传递给了 echo 程序。事实上,main 函数是有形式参数的。

void main(int argc,char *argv[])

参数 argc 的值标识运行程序时命令行中参数的数目;参数 argv 是一个指向字符串数组的指针,其中每个字符对应一个参数。按照 C 语言约定,argv[0] 的值时启动该程序的程序名,因此 argc 的值至少为 1。如果 argc 的值为 1,说明程序名后面没有命令行参数。在上面的例子中,argc 的值为 3,argv[0]、argv[1] 和 argv[2] 的值分别为“echo”、“hello,”、“world”。
并要求 argv[argc] 也就是 argv[3] 的值必须为一个空指针。

关于函数指针

函数指针就是指向函数的指针,它可以被当作参数调用,例子如下:

#include <stdio.h>

int add(int a, int b);
int sub(int a, int b);
int Operate(int (*operate)(int,int));

int main()
{
	printf("%d\n", Operate(add));
	printf("%d\n", Operate(sub));
}

int Operate(int (*operate)(int ,int))
{
	int a = 1, b = 2;
	return operate(a, b);
}

int add(int a, int b)
{
	a = a + b;
	return a;
}

int sub(int a, int b)
{
	a = a - b;
	return a;
}      

关于 system

命令执行函数 system(char *s) 执行包含在字符串 s 中的命令,然后继续执行当前程序。s 的内容很大程度上于所用的操作系统有关。
在 linux 上编译以下程序并运行

#include<stdio.h>
#include<stdlib.h>

int main()
{
    system("date");
    return 0;
}

C语言一些需要注意的点

可以看到结果是一致的。

关于文件描述符

在 UNIX 系统中,所有的外围设备(包括键盘和显示器)都被看作是文件系统中的文件,因此,所有的输入、输出都要通过读文件或者写文件完成。也就是说,通过一个单一的接口就可以处理外围设备和程序之间的所有通信。
通常情况下,在都或者写文件之前,必须先将这个意图通知系统,该过程称为打开文件。如果是写一个文件,则可能需要先创建该文件,也可能需要丢弃该文件中原先已存在的内容。系统检查你的权力(该文件是否存在?是否有访问它的权限?),如果一切正常,操作系统将向程序返回一个小的非负整数,该整数称为文件描述符。任何时候对文件的输入/输出都是通过文件描述符标识文件,而不是通过文件名标识文件。(文件描述符类似于标准库中的文件指针或 MS-DOS 中的文件句柄。)系统负责维护已打开文件的所有信息,用户程序只能通过文件描述符引用文件。
因为大多数的输入/输出是通过键盘和显示器来实现的,为了方便起见,UNIX 对此做了特别的安排。当命令解释程序(即“shell”)运行一个程序的时候,它将打开三个文件,对应的文件描述符分别为 0、1、2 ,依次表示标准输入、标准输出和标准错误。如果程序从文件 0 中毒,对 1 和 2 写,就可以进行输入/输出而不必关心打开文件的问题。

关于流

流(stream)是与磁盘或其他外围设备关联的数据的源或者目的地。尽管在某些系统中(如在著名的 UNIX 系统中),文本流和二进制流是相同的,但标准库仍然提供了这两种类型的流,文本流是由文本行组成的序列,每一行包含 0 个或者多个字符,并以 '\n' 结尾。在某些环境中。可能需要将文本流转换为其他表示形式(例如把 '\n' 映射成回车字符和换行符),或者从其他表示形式转换为文本流。二进制流是由未经处理的字节构成的序列,这些字节记录着内部数据,并具有一下性质:如果在同一系统中写入二进制流,然后再读取该二进制流,则读出和写入的内容完全相同。
打开一个流,将把该流与一个文件或设备连接起来,关闭流将断开这种连接。打开一个文件将返回一个指向 FILE 类型对象的指针,该指针记录了控制该流的所有必要信息。

内容来源

《C程序设计语言》

上一篇:xxxx (二):DLL远程注入


下一篇:C,C++中如何向main(int argc , char argv[])传递参数