从C语言谈程序语言

  到现在为止也学了很多的语言了,像C#,C++,php,JS,从过程化程序设计到面向对象程序设计,从强类型到弱类型。总的来概括,还是引用别人的那一句:”一切程序即内存“。写程序的时候理解内存中的表现,就能把语言学好,学的更深。下面我就把写程序要用的东西梳理一下。

  1.   数据类型
    程序要运行需要各种数据,要用数据之前就需要把数据存起来,不同类型的数据就要用不同的形式存放起来,例如整数,C用int这个关键字来声明,一个字符的话,C用char声明。不过C语言没有字符串这个类型,它的解决方案是用字符数组。php,JS这些弱类型的语言也是有数据类型的,不过就是运行时可以改变变量的数据类型,编译器的语法检查比较弱。下面就用C存放一个整数,一个字符,一个字符串。
    #include <stdio.h>
    #include <string.h>
    void main()
    {
    	int a = 3;
    	char c = 'A';
    	char str[] = {'H', 'e', 'l', 'l', 'o', '!', '\0'};//字符串"Hello!"
    }



  2. 函数
    现在我们手头有数据了,我们迫不及待地想利用我们的智慧写各种精妙的算法。现在就到函数出场了。函数就是一个小功能的具体实现,可以看成是一个小模块。在面向对象的语言中,函数作为类的一部分时,被称作了方法。下面我写了一个函数,实现了字符串的内容倒序(不考虑中文),算法本身很简单,看一眼就懂。
    #include <stdio.h>
    #include <string.h>
    void reverseStr(char str[])
    {
    	int n = strlen(str);
    	for (int i = 0; i < n / 2; i++)
    	{
    		int temp = str[i];
    		str[i] = str[n - 1 - i];
    		str[n - 1 - i] = temp;
    	}
    }
    void main()
    {
    	int a = 3;
    	char c = 'A';
    	char str[] = {'H', 'e', 'l', 'l', 'o', '!', '\0'};//字符串"Hello!"
    	reverseStr(str);
    	puts(str);
    	getchar();
    }

    结果输出:


  3. 注意的问题——传值还是传地址?
    这个问题我觉得还是很值得拿出来说一下的。其实传地址也是传值,只是这个值是一个地址嘛。现在我们突然有这样的一个需求:想用一个函数交换两个数的值。一开始,我们认为这个很简单,然后我们立即动手写了一下。
    #include <stdio.h>
    #include <string.h>
    void swap(int a, int b)
    {
    	int temp = a;
    	a = b;
    	b = temp;
    }
    void main()
    {
    	int a = 4;
    	int b = 6;
    	swap(a, b);
    	printf("a = %d, b = %d\n", a, b);
    	getchar();
    }

    不过我们很伤心的发现,结果跟我们预想的不一样:


    对于这个问题,估计C语言的老师应该是说了无数次这个是因为传值的原因。我们可以这么理解,在调用函数的过程中在函数的内部创建了两个局部的变量,它们也叫a和b,然后外部的a和b这两个变量分别把值赋给内部的a和b,所以,井水不犯河水,内部的a和b两个值被交换了,外面的当然不会变,因为根本是不同的内存。
    那么,我们该怎么办呢?当然解决的方案有很多,最简单的,用C强大的指针。下面我就写了另一个版本的swap函数:
    #include <stdio.h>
    #include <string.h>
    void swap(int *a, int *b)
    {
    	int temp = *a;
    	*a = *b;
    	*b = temp;
    }
    void main()
    {
    	int a = 4;
    	int b = 6;
    	swap(&a, &b);
    	printf("a = %d, b = %d\n", a, b);
    	getchar();
    }

    运行结果:


    我们终于理解了原因,函数传值永远是个副本,所以我们就让这个值是一个地址,这样就可以操作原来的那块内存了。对于C++,我们还有更简单的方法,那就是用引用,我又写了一个版本的swap函数:
    #include <stdio.h>
    #include <string.h>
    void swap(int &a, int &b)
    {
    	int temp = a;
    	a = b;
    	b = temp;
    }
    void main()
    {
    	int a = 4;
    	int b = 6;
    	swap(a, b);
    	printf("a = %d, b = %d\n", a, b);
    	getchar();
    }

    运行结果:


    加上了”&“号你可以这么理解,内部的a和外部的a(b也是同样的)都访问同一块内存,所以交换的效果也就达到了。
    其实C#,java,php,JS这些语言中也是有引用这个概念的,像C#中声明的类类型的变量就是一个引用变量:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace test
    {
        class Person
        {
            public int age;//年龄
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                Person p1 = new Person();
                p1.age = 20;
                Person p2 = p1;
                p2.age = 10;
                Console.WriteLine(p1.age);
                Console.ReadLine();
            }
        }
    }
    

    运行结果:


    结果变成了10,那是因为p1和p2这两个变量都是指向同一块内存的。
    以上就是我觉得编程中基本的要素,当然想流程控制,类型转换之类的,看一下就懂了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值