H:/1218/00_引用_main.cpp
//
// main.cpp
// 06-引用
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
/*
引用是变量的别名
引用无独立的内存空间,与被引用的变量共用内存空间,而指针有自己的8字节空间
引用只能在定义的时候初始化一次,其后不可再更改,而指针可以
引用为可以为空,而指针可以
引用++就是被引用的变量的++
函数返回引用,但是不可以返回局部变量的引用,因为函数调完,局部变量就被释放了
引用可以作为函数的形参,修改了引用形参,能影响外面实参变量的值
如果要在函数内部修改外面实参的值,尽量使用引用作为形参,
不要使用指针作为函数形参,原因如下:
引用不占用额外的存储空间
使用引用修改实参显得更自然、易懂
*/
#include
using namespace std;
// 下面的引用是错误的,函数不能返回局部变量的引用
int & sum(int a, int b)
{
int temp = a + b; // 21
return temp;
}
int main(int argc, const char * argv[])
{
int a = 10;
int &af = a;
int *p = &a;
// 引用++ 就是被引用的变量a++
af++;
// 指针++ 是指针指向下一个4字节的内存空间
p++;
// sizeof(引用) 就是被引用变量的所占空间字节数
sizeof(af);
// sizeof(指针) 在64位环境下,指针永远为8字节
sizeof(p);
cout << a << endl;
// int n = sum(10, 11);
//
// int &f = sum(10, 11);
// // f 和 temp共享存储空间
//
//
// cout << f << endl;
// cout << n << endl;
// 指针可以为空,即不指向任何地址空间,p的值是0x0
int *p = NULL;
// 引用不能为空,它无自己空间,必须在定义时就绑定被引用的变量,且以后都不可以更改
int ⁡
return 0;
}
// 函数可以返回全局变量的引用,使用函数可以写在运算符的左边
int age = 10;
int & test()
{
return age;
}
// 函数可以返回全局变量的引用,使用函数可以写在运算符的左边
double heights[] = {10.9, 18.7, 28.9, 67.44};
double & setHeights(int i)
{
return heights[i];
}
void testRef5()
{
cout << heights[0] << endl;
setHeights(2) = 20.7;
cout << heights[0] << endl;
// heights[0] = 20.7;
// setHeights(0, 20.7);
// test() = 30;
//
//
// cout << age << endl;
}
// 虽然通过指针可以交换外部两个变量,但是要占额外的地址空间
void my_swap(int *x, int *y)
{
int temp = *x;
*x = *y;
*y = temp;
}
// 而通过引用交换两个变量的值,不需要占额外的内存空间
void my_swap(int &x, int &y)
{
int temp = x;
x = y;
y = temp;
}
void testRef4()
{
int a = 10;
int b = 20;
my_swap(a, b);
cout << "a=" << a << ", b=" << b << endl;
}
void testRef3()
{
double d = 10.5;
const double &df = d;
d = 30;
cout << df << endl;
/*
int temp = 10.5;
const int &df = temp;
*/
// int &df = d;
}
void testRef2()
{
int a = 10;
int b = 20;
// int &f; 这种写法是错误的,引用必须定义时绑定变量,且始终如一
// 一个引用只能在定义的时候确定所引用的变量
// 以后都不能再改变所引用的变量
int &af = a;
// 将变量b的值给了af,也就是给了a
af = b;
// cout << a << endl;
cout << "&af=" << &af << ", &b=" << &b << endl;
}
void testRef()
{
int a = 10;
// af就是一个引用。引用着变量a
// af就相当于a的别名
int &af = a;
// int &bf = a; 跟下面的代码是等价的
int &bf = af;
cout << "af=" << &af << ", bf=" << &bf << endl;
}
H:/1218/01_HelloWorld_main.cpp
//
// main.cpp
// 01-第一个C++程序
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
//
// C++自带的标准头文件都是没有.h的
// 就相当于C语言的
#include
// 提前使用命名空间std
using namespace std;
int main(int argc, const char * argv[])
{
// cin 接收键盘的输入,后面直接跟变量,而非地址
int age;
double height;
char name[10];
cout << "请输入年龄:";
cin >> age;
cout << "请输入身高:";
cin >> height;
cout << "请输入姓名:";
cin >> name;
cout << "My age is " << age << ", height is " << height <<
", name is " << name << endl;
// printf("请输入年龄:");
// scanf("%d", &age);
//
// printf("请输入身高:");
// scanf("%lf", &height);
//
// printf("请输入姓名:");
// scanf("%s", name);
//
// printf("My age is %d, height is %f, name is %s\n", age, height, name);
return 0;
}
void testCout()
{
// 在控制台输出一些信息
// 相当于C语言的printf函数
// 相当于OC的NSLog
// std::cout << "Hello, World!\n";
// endl : end line
// 运算符重载
// std::cout << "My age is 20" << ", height is 1.78" << std::endl;
int age = 20;
double height = 1.89;
char name[10] = "jack";
cout << "My age is " << age << ", height is " << height << ", name is "
<< name << std::endl;
// printf("My age is %d, height is %f, name is %s\n", age, height, name);
// std::cout << "My age is " << age << ", height is " << height << ", name is "
// << name << std::endl;
// 命名空间
// cout 这个 对象 是定义在 std 命名空间中的
// NSString *cout = @"4234324";
}
H:/1218/02_C++增强的结构体_main.c
/* main.c
02-C++特有语法
Created by apple on 13-12-18.
Copyright (c) 2013年 itcast. All rights reserved.
*/
#include
C++:在相同的作用域内,如果2个函数的名字相同,而参数列表不同,就称为“重载”
函数名:test
函数参数列表:空
void test()
{
}
函数名:test
函数参数列表:int a
void test(int a)
{
}
//定义C语言结构体类型
struct Student
{
int age;
double height;
char name[10];
};
int main()
{
定义结构体遍历
struct Student s = {20, 1.78, "jack"};
// C中点是成员访问符号
printf("age is %d\n", s.age);
return 0;
}
H:/1218/02_C++增强的结构体_main.cpp
//
// main.cpp
// 02-C++特有语法
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
// C++原则:如果某个形参没有默认值,那么它左边的参数就不能有默认值
#include
using namespace std;
#pragma mark - 函数重载
void test()
{
cout << "test函数" << endl;
}
void test(int a = 10)
{
cout << "test(int) " << a << endl;
}
void test(int a = 10, int b = 20)
{
cout << "test(int, int) " << a << "," << b << endl;
}
int main(int argc, const char * argv[])
{
// 下面的2个调用都存在二义性,编译器不清楚要调用哪个函数
// test();
// test(20);
test(5, 90); // 调用是合理的
// test(20);
return 0;
}
#pragma mark - 带有默认形参值的函数
int sum(int x = 1, int y = 2)
{
cout << "x=" << x << ", y =" << y << endl;
return x + y;
}
// 系统自带了一个叫做minus的函数
// C++原则:如果某个形参没有默认值,那么它左边的参数就不能有默认值
/*
int my_minus(int x = 26, int y = 20, int z)
{
return x - y;
}
*/
// 一定要保证所有的形参有值
// int a = sum(10, 9);
//
// cout << a << endl;
#pragma mark - 结构体和指针
void testStruct2()
{
struct Date
{
int year;
int month;
int day;
void output()
{
cout << year << "-" << month << "-" << day << endl;
}
};
Date d = {2013, 12, 18};
// . : 直接 利用结构体变量名 访问 结构体内部 的 成员变量 和 成员函数
// d.output();
//
// d.year;
Date *p = &d;
// p->year;
// -> : 利用 指针变量 间接 访问 它所指向结构体内部 的 成员变量 和 成员函数
p->output();
// cout << p->year << endl;
// cout << d.year << endl;
// d.output();
}
#pragma mark - 结构体
struct Student
{
// 成员变量
int age;
double height;
char name[10];
// 2个参数的构造函数,一旦有了这个,就会覆盖掉原来三个参数的构造函数
Student(int age1 = 20, double height1 = 1.98)
{
age = age1;
height = height1;
}
// 成员函数
void study(int a)
{
cout << "学生的年龄是:" << age << ", 身高是:" << height
<< ", 名称是:" << name << endl;
cout << "参数a是:" << a << endl;
}
};
void testStruct()
{
// Student s = {19};
// C++中定义结构体变量时,struct可有可无
Student s = {19, 1.89};
Student s2 = {28, 1.9};
// s2.study(10);
Student s3 = Student(29, 1.99);
s3.study(20);
// struct Student s2;
}
H:/1218/03_C++调用C函数_main.cpp
//
// main.cpp
// 03-extern "C"
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
//
/*
C++调用C函数的原则:
1,只需要在.cpp\.cc文件中前面使用extern "C"
{
#include "zs.h"
}
包含C语言的头文件即可
*/
#include
/*
extern "C"的作用:
1.能够实现C\C++混合编程,实现C\C++之间的函数互调
2.使用场合
1> 在.cpp\.cc文件中包含C语言的头文件
extern "C"
{
#include "zs.h"
}
*/
//#include "zs.h"
//int sum(int, int); // 默认情况下,C++会认为当前函数的名称是sum(int,int)
// extern "C" 告诉编译器 按照 C语言的方式去编译函数(不会实行名字改编机制)
//extern "C" int sum(int, int);
//extern "C" int my_minus(int, int);
extern "C"
{
#include "zs.h"
// int sum(int, int);
// int my_minus(int, int);
}
using namespace std;
int main(int argc, const char * argv[])
{
// int c = sum(10, 12); // _sum
int c = my_minus(10, 12);
cout << c << endl;
return 0;
}
// mangled naming
// C++之所以可以函数重载,是因为使用了函数名字改编机制
// _test
//void test(int a, double b);
//
//void cde()
//{
// test(10, 10.9);
//}
//
_test_int
//void test(int a)
//{
//
//}
//
_test_double
//void test(double a)
//{
//
//}
//
_test_int_bool
//void test(int a, bool b)
//{
//
//}
//void test()
//{
//
//}
//
//int test()
//{
// return 0;
//}
//void test(int a)
//{
// cout << "test(int)" << endl;
//}
//
//void test(double a)
//{
// cout << "test(double)" << endl;
//}
H:/1218/03_C++调用C函数_zs.c
//
// zs.c
// 03-extern "C"
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
/*
C++调用C函数的原则:
1,只需要在.cpp\.cc文件中前面使用extern "C"
{
#include "zs.h"
}
包含C语言的头文件即可
*/
// _sum
int sum(int a, int b)
{
return a + b;
}
int my_minus(int a, int b)
{
return a - b;
}
H:/1218/03_C++调用C函数_zs.h
//
// zs.h
// 03-extern "C"
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
/*
C++调用C函数的原则:
1,只需要在.cpp\.cc文件中前面使用extern "C"
{
#include "zs.h"
}
包含C语言的头文件即可
*/
#ifndef _3_extern__C__zs_h
#define _3_extern__C__zs_h
int sum(int, int);
int my_minus(int, int);
#endif
H:/1218/04_C++函数被C和C++调用_main.c
//
// main.c
// 04-C调用C++函数
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
// C++函数被C和C++调用的原则:
// 1,C++函数要想即被C 又被C++调用,函数只能使用C方式 编译
// 2,.h头文件中,如果是C环境,由于C语法中没有extern "C"{},故不能有extern "C"{}
// 3,.h头文件中,如果是C++环境,要使用extern "C"{},将函数按照C方式编译
// 4,.cpp函数实现的文件中,使用extern "C"{} 将函数按照C方式编译
//#include
//#include "zs.h"
//
int sum(int, int);
//int main()
//{
// int c = sum(10, 11); // C语言会认为函数名叫_sum
//
// printf("c is %d\n", c);
//
// return 0;
//}
H:/1218/04_C++函数被C和C++调用_main.cpp
#include "zs.h" // _sum
#include
// cpp中要想写出一套C\C++都能调用的函数,这个函数只能按照C语言方式编译
// C++函数被C和C++调用的原则:
// 1,C++函数要想即被C 又被C++调用,函数只能使用C方式 编译
// 2,.h头文件中,如果是C环境,由于C语法中没有extern "C"{},故不能有extern "C"{}
// 3,.h头文件中,如果是C++环境,要使用extern "C"{},将函数按照C方式编译
// 4,.cpp函数实现的文件中,使用extern "C"{} 将函数按照C方式编译
using namespace std;
int main()
{
int c = sum(10, 11);
cout << c << endl;
return 0;
}
H:/1218/04_C++函数被C和C++调用_zs.cpp
//
// zs.cpp
// 04-C调用C++函数
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
//
// 1,C++函数要想即被C 又被C++调用,函数只能使用C方式 编译
// 要使用extern "C"{} 将函数按照C方式编译
// C++函数被C和C++调用的原则:
// 1,C++函数要想即被C 又被C++调用,函数只能使用C方式 编译
// 2,.h头文件中,如果是C环境,由于C语法中没有extern "C"{},故不能有extern "C"{}
// 3,.h头文件中,如果是C++环境,要使用extern "C"{},将函数按照C方式编译
// 4,.cpp函数实现的文件中,使用extern "C"{} 将函数按照C方式编译
extern "C"
{
//使用了extern "C"之后,下面函数将按C方式编译,以供C文件调用 _sum
int sum(int a, int b)
{
return a + b;
}
}
H:/1218/04_C++函数被C和C++调用_zs.h
//
// zs.h
// 04-C调用C++函数
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#ifndef ___4_C__C______zs__
#define ___4_C__C______zs__
// C++函数被C和C++调用的原则:
// 1,C++函数要想即被C 又被C++调用,函数只能使用C方式 编译
// 2,.h头文件中,如果是C环境,由于C语法中没有extern "C"{},故不能有extern "C"{}
// 3,.h头文件中,如果是C++环境,要使用extern "C"{},将函数按照C方式编译
// 4,.cpp函数实现的文件中,使用extern "C"{} 将函数按照C方式编译
#ifdef __cplusplus
extern "C" {
#endif
int sum(int, int);
#ifdef __cplusplus
}
#endif
#endif
H:/1218/05_const_main.cpp
//
// main.cpp
// 05-const
//
// Created by apple on 13-12-18.
// Copyright (c) 2013年 itcast. All rights reserved.
//
#include
#define kCount 10
/*
const原则:
1,const与变量类型可以互相调换位置
2,什么不可变,主要看const右边是什么东东,是变量名,还是*变量名
C++推荐使用const,原因是节省内存开销,避免宏替换的那些副作用
const只在第一次开辟内存,而后,只是将内存地址分配给相应的变量
而宏是立即数,每次都是开辟新的内存空间给相应的变量
*/
const int count = 10;
void test()
{
// int a = kCount;
//
// int b = kCount;
//
}
using namespace std;
/*
const的总结:
1.看const右边是什么,const右边的东西都是常量
2.const和数据类型可以调换位置
int const a = 10;
const int a = 10;
*/
//#define kABC 12
//
//const int ABC = 26;
void test(const int *p)
{
cout << *p << endl;
}
// 下面这样写仍然有副作用,如:MAX(++a,b)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
// 宏高级用法1:将传进来的x变为字符串(用双引号""包住)
#define TO_STR(x) #x
// 宏高级用法2:将传进来的x和y拼接在一起
#define CONCAT(x, y) x##y
int main(int argc, const char * argv[])
{
char username[] = "jack";
// 宏的高级用法:将参数连接在一起
cout << CONCAT(user, name) << endl;
cout << name << endl;
int a = 10;
int b = 6;
a=11, c=15
a=12, c=12
c = ( 11 > 6 ? 12 : b)
// 下面这个宏仍然有副作用
int c = MAX(++a, b);
cout << "a=" << a << ", c=" << c << endl;
// const 和int可以互换,右边是变量a,说明a值不可改变,定义时要赋初值
const int a = 10;
int *p = &a;
int a = 10;
// 下面*p是常量,说明p指向的内存空间的值不可变,不能通过*p来修改a的值
const int *p = &a;
int b = 20;
p = &b;
*p = 25;
cout << *p << endl;
int a = 10;
// 下面const修饰p,说明指针只能指向a,p的值不可变,只能放a的地址
int * const p = &a;
*p = 30;
cout << a << endl;
int b = 30;
p = &b;
int a = 20;
// 下面p只能指向a,并且a的值也不可变
const int * const p = &a;
int b = 30;
p = &b;
*p = 50;
// const和类型可以互换
int const a = 10;
int a = 10;
// 下面p1不可变,p1指向的内存空间也不可变,p2是int类型,也不可变
int const * const p1 = &a,p2 = 20;
//p1 *p1 p2
int const * const p1,p2;
// p1 p2
// 下面p1不可变,p1指向的内存空间可变,p2是int类型,不可变
int * const p1,p2;
typedef char * pStr;
#define pStr char *
char string[4] = "bbc";
const char *p1 = string;
// 下面是typedef定义的话,就相当于是const int p2;故p2++是错误的
const pStr p2 = string;
p1++;
p2++;
return 0;
}