[关闭]
@Sakura-W 2015-12-13T13:45:09.000000Z 字数 2761 阅读 2026

C语言进阶

程序设计语言


一、数据类型

1.数据类型概述

(1)C语言是有类型语言:
C语言变量必须先定义,并且确定类型。但对类型的安全检查并不足够。
(2)C语言之后:
C++,Java:更加强调类型,对类型的检查更加严格。
Javascript、Python、PHP:不看重类型,甚至不需要申明类型。
(3)早期的语言强调类型,面向底层的语言强调类型。
(4)C语言类型分类:
整数:char、short、int、long、long long
浮点数:float、double、long double
逻辑:bool
指针
自定义类型
表达数的范围:char<short<int<float<double

2.整数类型

(1)各种整数类型:
char:占一个字节
short:占两个字节
int:字节长度取决于机器字长和编译器(一个寄存器的大小)
long:字节长度取决于机器字长和编译器
long long:占8个字节
(2)整数的内部表达:
计算机内部一切都是二进制的。
加法运算:二进制补码算法。
(3)整数的范围:
int:-128-127(-2^7~2^7-1)
(4)整数的输入和输出:

%d:用于char、short、int

%ld:用于long和long long

(5)整数类型的选择:
没有特别的需要,就用int类型

3.浮点数

float与double
(1)浮点数运算不精确:

float a = 1.234f;
float b = 2.345f;
float c = a + b;
c != 3.579//实际上C比这个数稍微小一点

(2)浮点数选择:
没有特殊需要,就用double

4.逻辑类型

(1)逻辑类型:
#include <stdbool.h>包含这个头文件就可以使用true,bool false等。
C语言实际上不存在truefalse类型的值,用printf作输出是不能输出true,只能输出1
(2)逻辑运算:
逻辑非:
逻辑与:&&
逻辑或:||
优先级:!> && >||

5.类型转换与条件运算

(1)自动类型转换:
当运算符两边出现不一致的类型时,会自动转换成较大的类型(能表达的数的范围更大)

char->short->->int->long->long long
int->float->double

对于printf来说:任何小于int的类型会被转换成int,float会被转换为double
scanf不会,如果要输入short,需要%hd
(2)强制类型转换:
(类型值)变量

(int)10.2
(short)32768

强制类型转换的优先级高于四则运算
(3)条件和逗号运算:
条件表达式:

count = (count > 20)? count - 10:count + 10;//赋值运算

逗号运算:

int = (3 + 4,5 + 6);

逗号运算优先级最低。逗号使得逗号后面的表达式取代前面的表达式。逗号表达式一般用于for语句中。

二、指针

1.指针的基础知识

(1)指针就是地址。把定义变量时为该变量分配的起始地址称为该变量的地址。
(2)指针变量的定义:
类型标识符 *指针变量名int *p
(3)基本操作:
1)&-取地址运算符:如&i,取变量i的地址
2)*-间接访问运算符:如*p表示取指针变量p指向的变量
3)指针变量作为函数的参数:

void swap(int *p1,int *p2)

2.指针与数组

(1)指针与一维数组
1)一维数组的指针
在C语言中,数组名就是数组的首地址,一维数组的数组名就是数组中第一个元素的地址
&a[0]+1不是简单地加1,而是使得指针指向下一个数组元素。
2)指向一维数组元素的指针变量

p = &a[0]//或者p = a;
那么*(p +1) == *(a + 1)
而*(a + 1) 可以写成a[i],*(p + 1)可以写成a[i]
所以p[i] == a[i]

3)一维数组元素的地址作为函数参数
使用数组名作为函数参数时,实际上传递的是数组的首地址
(2)指针与二维数组
1)二维数组的指针
&a[i][j] = (a[i] + j) = (*(a+1)+j,对应的a[i][j] = *(*(a + i) + j)
2)指向二维数组元素的指针变量
二维数组的指针变量和一维数组的指针变量是一样的
3)指向一维数组的指针变量

int (*p)[n]

(*p)表示一个指针变量p,[n]表示指针变量指向的是一个由n个元素组成的一维数组,int表示这个一维数组的类型是整型。p++不是简单地加1,而是加由n个元素组成的一维数组的长度,即指向下一行组成的一维数组。

3.指针与字符串

(1)用字符指针访问字符串
字符串是由若干个字符组成的字符序列,以'\0'作为字符串的结束标志。字符串一般存储在字符数组中,对字符串进行访问时可以逐个访问数组元素中的字符,也可以用指针访问字符串。
字符指针变量和字符数组都可以处理字符串,但有以下区别:
1)字符指针变量存放的是一个字符串的首地址,并不是存放字符串本身,而字符数组中可以存放字符串
2)字符数组中赋字符串和字符指针变量中赋字符串首地址的区别:
字符数组和字符指针变量都可以初始化:

char a[] = "Hello";
char *p = "Hello";

数组不可以用语句直接赋字符串,而字符指针变量可以

char a[10];
a = "Hello";//这种方式不行
char *p;
p = "Hello";//这种方式可以

字符指针变量的值可以改变,数组名不能改变

char *p = "Hello";
p = p + 2;

4.指针数组和指向指针的指针

(1)指针数组
1)定义形式:
类型标识符 *数组名[数组元素个数]
char *c[6]//该数组是字符指针型数组,数组的每个元素都指向一个字符型数据
2)指针数组作为main函数的形参:

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

argc存放程序执行时的参数个数,argv为指针数组,存放各参数字符串的首地址
(2)指向指针的指针
定义形式:类型标识符 **指针变量名
char **p//定义p是一个指向字符型指针的指针变量

5.指针与函数

(1)指针作为函数的返回值
格式:类型名 *函数名(形参表)

int *fun(int a,int b)

//函数前面的int *表示这个函数返回值是一个int型的指针
(2)指向函数的指针
函数包括一组指令序列,也是存储在某一段内存中,这段内存的起始地址称为函数的入口地址,通过函数名就可以得到这一地址。
函数的入口地址就是函数的指针,可以通过指针找到函数。
定义格式:类型名 (*指针变量名)(形参列表)

int fun(int x,int y){
    return x*y;
}
int (*p)(int x,int y)//定义函数指针,这个函数有两个整型变量,切返回值为整型
p = fun//将fun函数的入口地址赋给指针变量p

指向函数的指针变量也可以作为函数的参数,此时,当指向函数的指针变量每次指向不同函数时,就调用不同的函数来完成不同的功能,这也是指向函数指针变量的主要用途。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注