标签:消失 处理 ret 进一步 下标 ack std 预处理 括号
————————————————————————————————————————————
getchar /putchar 输入输出
语法:
c = getchar(); // 获取控制台输入
putchar(c); //输出
————————————————————————————————————————————
EOF,End Of File,文件尾标志。 从数值上来看,就是整数-1
linux:在输入回车换行后的空行位置,按 ctrl+d (先按ctrl键,不放,再按d键)
windows:在输入回车换行后的空行位置,按 ctrl+z,再回车确认
————————————————————————————————————————————
参数传值调用
在C语言中,被调函数不能直接修改主调函数中变量的值,而只能修改函数私有的临时副本的值
必要时,也能够修改主调函数中的变量。需要向被调用函数提供待设置值的变量的地址(指针)。被调用函数则需要将对应的参数声明为指针类型,并通过它间接访问变量。
如果是数组参数,当把数组名用作参数时,传递给函数的值是数组起始元素的位置或地址,并不复制数组元素的本身。在被调函数中,可以通过数组下标访问或修改数组元素的值。
————————————————————————————————————————————
变量
作用域:
仅在定义它的函数内;
初始化:
不自动赋初值,使用前需要赋值;
值的保持:
随函数的引用而存在和消失,不保持值;
优势:
解决函数单独编译的协调;与变量初始化有关;外部变量的值是永久的;解决数据共享;
作用域:
整个程序;
初始化:
0
值的保持:
永久保持
特点:
举例:
作用域:
仅在定义它的函数内;
初始化:
0;
值的保持:
当函数执行完,返回调用点时,该变量并不撤销,再次调用时,其值将继续存在;
特点:
采用静态存贮分配(由编译程序在编译时分配,而一般的自动变量和函数形参均采用动态存贮分配,即在运行时分配空间);
优势:
可以实现数据隐藏
作用域:
定义它的文件(该文件的私有变量),其他文件上的函数不允许访问;
初始化:
0;
特点:
————————————————————————————————————————————
常量
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
enum 枚举常量
不同枚举中的名字必须互不相同,同一枚举中不同的名字可以是用相同的值;相对#define来说,优势在于常量值可以自动生成
举例:
/*
week是新的数据类型,源于int,此时:
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2
THURSDAY = 3
FRIDAY = 4
SATURDAY = 5
SUNDAY = 6
*/
/*
MONDAY = 1
TUESDAY = 2
WEDNESDAY = 3
THURSDAY = 4
FRIDAY = 5
SATURDAY = 6
SUNDAY = 7
*/
/*
BELL = ‘\a‘,
BACKSPACE = ‘\b‘,
TAB = ‘\t‘,
NEWLINE = ‘n‘,
VTAB = ‘\v‘,
RETURN = ‘\r‘
*/
————————————————————————————————————————————
关键字
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const //限定符,通过 const 对变量进行限定后,无法修改其值,数组同理。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
register //请求编译器尽可能的将变量存在CPU内部寄存器中,而不是通过内存寻址访问,以提高效率。
————————————————————————————————————————————
数组
// 调用数组a[i]的值时也可以写成 *(a+i) 的形式,编译的过程实际上先将其转换成 *(a+i) 再求值。所以 a[i] 与 *(a+i) 是等价的,一个通过数组和下表实现的表达式可以通过指针可偏移量实现。注意:指针是一个变量, p=a或p++是合法的,但数组名不是变量,不可以执行上面的操作。
————————————————————————————————————————————
指针
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
地址运算符 & 只能应用于内存中的对象(变量与数组元素)。它不能作用于表达式/常量/register类型的变量。
指针只能指向某种特定类型的对象(例外情况:指向void类型的指针可以存放指向任何类型的指针,但它不能间接引用其自身)。
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
指针传递
语法:
swap(a,b);
void swap(int *p,int *q)
特点:
举例:
#include <stdio.h>
void pointer(int *p)
{
printf("\nthe p is %p , addr is %d, *p is %d", p , &p, *p);
//Line 2 指针p传入方法pointer中:在新的方法中生成了一个p的拷贝p1,新的地址 6356752,但值和指向的内存块数据没变
*p = 12;
printf("\nthe p is %p , addr is %d, *p is %d", p , &p, *p);
//Line 3 p1改变了其所指向的内存块的值为12,内存块 00F0FF2C 的值变成了22
int a = 11;
p = &a;
printf("\nthe p is %p , addr is %d, *p is %d", p , &p, *p);
//Line 4 p1的值指向a,即p1指向a 内存块 0060FEFC,此时p1与p分别指向不同的内存块了,不会互相影响
}
int main()
{
int b = 22;
int *p = &b;
printf("\nthe p is %p , addr is %d, *p is %d", p , &p, *p);
//Line 1 *p指向b的地址:获得了p(内存块数据)&p(地址)*p(值)
pointer(p);
printf("\nthe p is %p , addr is %d, *p is %d", p , &p, *p);
//Line 5 方法结束,调用方法结束后,p地址仍是调用前的地址,地址和值没变(改变的仅仅是p的拷贝p1),但是p所指向的内存块数据被p1所改变了,故*p为12
}
输出:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
其他传递方式(来源参考他人)
语法:
swap(&a , &b);
void swap(int *a , int *b)
// 传入的是变量a的地址 &a,函数接收到的是传入地址的值
// 使用指针方式修改指向内存块的值,传入的是 a、b变量地址的拷贝。
注意:函数的值传递的方式是
swap(a , b);
void swap(int a , int b)
语法:
swap(a,b);
void swap(int &p,int &q)
// 使用引用方式,传入的是变量a、b,而不是拷贝,地址不变。
举例:
#include <stdio.h>
void swap(int *a , int *b)
//方法一:传值方式
{
printf("\n\n /*** Method 1 ***/");
printf("\n &a addr : %d , &b addr: %d", &a, &b);
printf("\n a memory : %d , b memory: %d", a, b);
printf("\n *a : %d , *b : %d", *a, *b);
int temp = *a;
*a = *b;
*b = temp;
}
void swap(int &a , int &b)
//方法二:传引用方式
{
printf("\n\n /*** Method 2 ***/");
printf("\n &a addr : %d , &b addr: %d", &a , &b);
int temp = a;
a = b;
b = temp;
}
int main(int argc, char const *argv[])
{
int a = 3 , b = 5;
printf(" &a addr : %d , &b addr: %d", &a , &b);
printf("\n a : %d , b : %d", a , b);
swap(&a , &b); //方法一
printf("\n &a addr : %d , &b addr: %d", &a, &b);
printf("\n a : %d , b : %d", a , b);
swap(a , b); //方法二
printf("\n a : %d , b : %d\n", a , b);
return 0;
}
输出:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*ip自增
语法:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
指针间赋值
语法: iq = ip;
/* 如果iq和ip同样是指向整型的指针,则将ip中的值copy到iq中,iq也将指向ip所指向的对象 */
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
参数指针
语法:double atof(char *);
/* atof的参数时一个指向char类型的指针*/
————————————————————————————————————————————
数组指针和指针数组
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
数组指针 //指向数组的指针
定义:int (*a)[4] //表示指向数组a的指针
举例:
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[10];
int *p, i;
for (i = 0; i < 10; ++i)
{
scanf("%d", &a[i]);
}
for (p = &a[0]; p < (a + 10); p++)
//p+i = a+i = &a[i] 这三者意思相同,所以循环结构使用 p < (a + 10),等价于 i < 10
{
printf("%d ", *p);
}
return 0;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
指针数组 //用于存储指针的数组
定义:int* a[4]; //表示a中的元素都为int型指针
————————————————————————————————————————————
预处理器
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
文件包含 #include "文件名" 或 #include <文件名>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
两个预处理语句 #ifdef 和 #ifndef
用法:
#ifndef HDR
#define HDR
/* hdr.h文件的内容在这里*/
#endif
/* 用来测试某个名字是否已经定义,等价于 */
#if !defined(HDR)
#define HDR
#endif
举例:
/* 测试SYSTEM变量后确定包含某个文件 */
#if SYSTEM == SYSV
#define HDR "sysv.h"
#elif SYSTEM == BSD
#define HDR "bsd.h"
#elif SYSTEM == MSDOS
#define HDR "msdos.h"
#else
#define HDR "default.h"
#endif
#include HDR
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
宏替换
用法:较长的替换文本可以在待续的行末尾加上反斜杠符
举例:
/* 该句为无限循环定义了一个新名字forever */
/* 形参A和B每次出现都将被替换成对应的实际参数,不过要适当使用括号来规范计算次序的正确性 */
/* 当使用时dprintf(x/y);时被扩展为 printf("x/y" "= %g\n",x/y); */
/*预处理器运算符## 为宏定义提供了连接实际参数的手段*/
/* 在调用paste(name,1)时,将建立记好 name1*/
int getchar(void){...}
用法:通过#undef 取消名字的宏定义,这样可以保证后续的调用是函数调用,而不是宏调用
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
标签:消失 处理 ret 进一步 下标 ack std 预处理 括号
原文地址:http://www.cnblogs.com/hughdong/p/6710256.html