C和指针(一)
预处理指令
预处理器用库函数头文件的内容替换掉相对应的#include
指令语句。
使用stdio.h
头文件可以使我们访问标准I/O库中的函数。
另一种预处理指令是#define ,当这个名字以后出现在源文件的任何地方时,它就会被替换为定义的值。
c
int read_column_numbers ( int columns [ ] , int max );
void rearrange ( char *output, char const *input , int n_columns, int const columns[] );
这些声明称为函数原型 。它们告诉编译器这些以后将在源文件中定义的函数的特征,这样,这些函数被调用时,编译器就能对它们进行准确性的检查。每个原型以一个类型名为开头,表示函数返回值的类型。跟在返回类型后面的是函数的名字, 再后面是函数期望接受的参数。所以,函数read_column_numbers
返回一个整数,接受两个类型分别是整数数组和整形标量的参数。
rearrange
函数接受4个参数,其中第一个和第二个参数都是指针 。指针指定一个存储于计算机内存中的值的地址。第2个和第4个参数被声明为const
,这表示函数将不会修改函数调用者所传递的这两个参数。关键字void
表示函数并不返回参数,在其他语言里,这种无返回的函数被称为过程。
main 函数
int main( void )
main是程序执行的起点。
在C语言中,数组参数是以引用形式进行传递的,也就是传址调用,而标量和常量则是按值传递的。
所有传递给函数的参数都是按值传递的。
如今软件开销的最大之处并非在于编写,而是在于维护。
常用printf格式代码:
格式 | 含义 |
---|---|
%d | 以十进制形式打印一个整型值 |
%o | 以八进制形式打印一个整型值 |
%s | 以十六进制形式打印一个整型值 |
%g | 打印一个浮点值 |
%c | 打印一个字符 |
%s | 打印一个字符串 |
scanf
函数中所有标量参数的前面必须加上一个"&"符号,数组参数前面不需要加上"&"符号,但是数组参数中如果加上了下标引用,也就是说实际参数是数组中某个特定元素,那么它的前面也必须加上"&"符号。
c
scanf ( "%d", &columns[num] )
常用scanf格式码:
格式 | 含义 |
---|---|
%d | 读取一个整型值 int |
%ld | 读取一个长整型值 long |
%f | 读取一个实型值(浮点数) float |
%lf | 读取一个双精度实型值 double |
%c | 读取一个字符 char |
%s | 从输入中读取一个字符串 char型数组 |
&&
是"逻辑与"操作符,&&操作符两边的表达式为真时,整个表达式才为真,如果左边的表达式为假,右边的表达式便不再进行求值。
=
赋值操作不是比较操作。
return语句就是函数向调用它的表达式返回一个值。
c
C语言的for语句:for ( col = 0; col , n_columns; col += 2) {
初始部分, 测试部分, 调整部分
执行: 程序必须载入到内存中。执行程序代码时,将使用一个运行时堆栈(stack),它用于存储函数的局部变量和返回地址。程序同时可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程中将一直保留它们的值。
基本数据类型:整型家族包括字符、短整型、整型和长整型,分为有符号和无符号。
整型值互相之间的大小规则:长整型至少和整型一样长,整型至少和短整型一样长。
格式 | 含义 |
---|---|
char | 0到127 |
signed char | -127到127 |
unsigned char | 0到256 |
short int | -32767到32767 |
unsigned short int | 0到65535 |
int | -32767到32767 |
unsigned int | 0到65535 |
long int | -2147483647到2147483647 |
unsigned long int | 0到4294967295 |
short int 至少16位,long int 至少32位。
常量及变量
整型字面值
字面值 是字面值常量的缩写,它指定了自身的值,并且不允许发生改变。 命名常量 (声明为const的变量)与普通变量的区别在于,被初始化后,它的值便不能改变。
在整数字面值后面添加字符L
或l
,使整数被解释为long整数值
,字符U
或u
则用于把数值指定为unsigned整型值
。如果在一个字面值后面添加UL
,则解释为unsigned long整型值
。
十六进制以0x开头,八进制以0开头。
字符常量 int类型。 是一个用单引号包围起来的单个字符(或字符转义序列或三字母词)如:'M' '\n' '\377'
浮点数字面值在缺省情况下都是double类型的,除非它的后面跟一个L或l表示是一个long double类型的值,或者跟一个F或f表示它是一个float类型的值。
指针:
变量存储于计算机的内存中,每个变量都占据一个特定的位置。每个内存位置都由地址唯一确定并引用。
字符串常量是用一对双引号包围一串字符,"Hello" "\aWarning!\a" "" 即便是空字符串也存在作为终止符的NUL符号。
基本声明:
变量声明的基本形式是: 说明符(一个或多个) 声明表达式列表
说明符包含了关键字,用于描述被声明的标识符的基本类型。说明符也可以用于改变标识符的缺省存储类型和作用域。
c
Int I; char j, l, l;
初始化 是在变量名后跟一个等号(赋值号),后面是想要赋给变量的值。 Int j = 15;
声明简单数组 int values[ 20 ] ; 声明了一个整型数组,数组包含20个整型元素。数组的下标是从0开始的,最后一个元素的下标是元素的数目减1.
声明指针 int a ; 这条语句表示表达式a产生的结果类型是int。知道了*操作符执行的是间接访问操作以后,我们可以推断a是一个指向int的指针。
【 间接访问操作只对指针变量才是合法的。指针指向结果值。对指针进行间接访问操作可以获得这个结果值。】
int* b, c, d; 错误 星号实际上是表达式*b的一部分,只对这个标识符有用。b是一个指针,但其余两个变量只是普通的整型。要声明三个指针,正确语句如下: int *b, *c, *d;
在声明指针变量时,你也可以为它指定初始值。Char *message = "Hello world!"; 这条语句把message声明为一个指向字符的指针,用于字符串常量中第一个字符的地址对该指针进行初始化。 前面一个声明相当于是:
char *message; message = " Hello world! ";
隐式声明:
C语言中有几种声明,它的类型名可以省略。函数如果不显式地声明返回值的类型,它就默认返回整型。
typedef
: 允许为各种数据类型定义新名字。
char *ptr ; 把变量ptr声明为一个指向字符的指针。 => typedef char *ptr ; 把标识符ptr作为指向字符的指针类型的新名字。 可以在下面的声明中使用这个新名字ptr a; 声明a是一个指向字符的指针。
应该使用typedef
而不是#define
来创建新的类型名。因为后者无法正确地处理指针类型。
#define d_ptr_to_char char * d_ptr_to_char a ,b ;
正确地声明了a ,但是b却被声明为一个字符。在定义复杂的类型名字时,如函数指针或指向数组的指针,使用typedef更为合适。
常量:
常量和变量完全一样,只是它们的值不能被修改。 如: int const a; const int a; 都可以赋值 int const a = 15;