(待整理)C++_001_引用_结构体_C和C++相互调用_const

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;
}


你可能感兴趣的:(C++)