重拾C++(2) 几个小练习

240 阅读3分钟

1.二维数组

二维数组可以分为动态与静态两种。

  1. 静态的二维数组大小是在编译期间确定分配,其内存在使用结束后由计算机自动释放,效率高;
  2. 动态数组是在程序运行时,由程序员根据实际需要从堆内存中动态申请的,使用结束后由程序员进行释放,效率低。
//静态二维数组,分配内存在栈上。
	const size_t n = 2;// size_t为unsigned int
	int arr[n][10];//
	for (size_t i = 0; i < n; i++) {
		for (size_t j = 0; j < n; j++)
			arr[i][j] = i * n + j;
	}

//动态数组
//等式左边声明一个名为pchar的指针,指向的类型为char[10],右边为pchar分配了n*10*sizeof(char)字节的内存块,new返回指向该内存块首地址(第一个字节)的指针
	char (*pchar)[10] = new char[n][10];
	
//也可以这么写
    const int n = 2;
    int** arr = new int* [n];//arr是指向指针的指针,分配n个元素的指针数组
    for (int i = 0; i < n; i++) {
        arr[i] = new int[10];
    }
    //赋值
    for (int i = 0; i < n; i++)
        for (int j = 0; j < 10; j++)
            arr[i][j] = i*10+j;
    //释放内存
    for (int i = 0; i < n; i++)
        delete[] arr[i];
    delete[] arr;

2.重载

int add( int a, int b )
{
    return a+b;
}

int add( int a, int b, int c=0 )
{
    return a+b+c;
}

int main( int argc, char **argv )
{
    // int value = add(1,2); //报错,因为尽管两个函数的参数数量不同,但是第二个函数使用了默认参数,所以也可以传两个参数,造成编译器无法判断调用哪个函数
    return 0;
}

3.指针与引用

不能定义指向引用的指针。但存在对指针的引用:

int i = 42;
int *p;
int *&r = p;

要理解r的类型到底是什么,最简单的办法是从右向左阅读r的定义。离变量最近的符号(&)对变量的类型有最直接的影响,因此r是一个引用。声明符其余部分确定r引用的类型是什么,*说明引用的是一个指针。最后,声明的基本数据类型部分指出r引用的是一个int指针。

int &*r;// ERR:pointer to reference is not allowed.

如果这些写就会提示:pointer to reference is not allowed. 下面程序分别利用指针与引用实现两个变量值的交换

#include <iostream>

void swap_ref( int & a, int & b )
{
    int c = a;
    a = b;
    b = c;
}

void swap_ptr( int * a, int * b )
{
    int c = *a;
    *a = *b;
    *b = c;
}
//通过对指针变量引用,交换两个指针变量的值
void swap_ref_ptr( int * & a, int * & b )
{
    int *c = a;
    a = b;
    b = c;
}

int main( int argc, char **argv )
{
    int i1 = 1;
    int i2 = 2;
    int * p1 = &i1;
    int * p2 = &i2;

    std::cout << "i1 = " << i1 << ", " << "i2 = " << i2 << std::endl;
    swap_ref(i1,i2);
    std::cout << "i1 = " << i1 << ", " << "i2 = " << i2 << std::endl;
    std::cout << std::endl;

    std::cout << "*p1 = " << *p1 << ", " << "*p2 = " << *p2 << std::endl;
    swap_ptr(p1,p2);
    std::cout << "*p1 = " << *p1 << ", " << "*p2 = " << *p2 << std::endl;
    std::cout << std::endl;

    std::cout << "*p1 = " << *p1 << ", " << "*p2 = " << *p2 << std::endl;
    swap_ref_ptr(p1,p2);
    std::cout << "*p1 = " << *p1 << ", " << "*p2 = " << *p2 << std::endl;

    return 0;
}

4.断言Assert

声明:void assert(int expression);

expression在大多数情况下可以是任何有效的C语言表达式。 在下面的程序中,我们将两个整数相除或计算a / b(其中a和b是整数),并且您知道b不能为零,因此我们在程序中使用assert(b!= 0)。 如果条件(b!= 0)成立,则程序将继续执行。 否则,它将终止,并在屏幕上显示错误消息,指定文件名,行号,函数名以及不成立的条件

#include <stdio.h>
#include <assert.h>
 
int main() {
  int a, b;
 
  printf("Input two integers to divide\n");
  scanf("%d%d", &a, &b);
 
  assert(b != 0);
 
  printf("%d/%d = %.2f\n", a, b, a/(float)b);
 
  return 0;
}