《linux c编程一站式学习》笔记2

1. 数组的基本概念 
数组(Array)也是一种复合数据类型,它由一系列相同类型的元素(Element)
组成。例如定义一个由4个int型元素组成的数组count
int count[4]; 
一个由4个结构体元素组成的数组:
struct complex_struct { 
  double x, y; 
} a[4]; 
也可以定义一个包含数组成员的结构体: 
struct { 
  double x, y; 
  int count[4]; 
} s; 


8.1 定义和访问数组
#include<stdio.h>
int main(void)
{
int count[4] = {3,2,}, i;
for(i=0; i<4; i++)
printf("count[%d] = %d\n", i, count[i]);
return 0;
}
程序输出:
[root@redhat-beijing test]# gcc -Wall a.c 
[root@redhat-beijing test]# ./a.out 
count[0] = 3
count[1] = 2
count[2] = 0
count[3] = 0
数组也可以像结构体一样初始化,未赋初值的元素也是用 0来初始化。
数组类型做右值使用时,自动转换成指向数组首元素的指针。


1、编写一个程序,定义两个类型和长度都相同的数组,将其中一个数组的所有
元素拷贝给另一个。既然数组不能直接赋值,想想应该怎么实现。 
#include<stdio.h>
int main(void)
{
int count[4] = {3,2,1,0}, i;
int count_copy[4]; //未初始化,故产生的是随即值。 若初始化,int count_copy[4] ={};则count_copy中的元素都为0
for(i=0; i<4; i++)
        printf("count[%d] = %d\n", i, count[i]);
for(i=0; i<4; i++)
        printf("before: count_copy[%d] = %d\n", i, count_copy[i]);
for(i=0; i<4; i++)
        count_copy[i] = count[i];
for(i=0; i<4; i++)
        printf("After: count_copy[%d] = %d\n", i, count_copy[i]);
return 0;
}
output:
[root@redhat-beijing test]# gcc -Wall a.c
[root@redhat-beijing test]# ./a.out 
count[0] = 3
count[1] = 2
count[2] = 1
count[3] = 0
before: count_copy[0] = 14012404
before: count_copy[1] = 14004740
before: count_copy[2] = -1079859528
before: count_copy[3] = 134513833
After: count_copy[0] = 3
After: count_copy[1] = 2
After: count_copy[2] = 1
After: count_copy[3] = 0


2. 数组应用实例:统计随机数 
问题是这样的:首先生成一列0~9的随机数保存在数组中,然后统计其中每个数字出现的次数并打印,检查这些数字的随机性如何。
#include <stdio.h> 
#include <stdlib.h> 
#define N 20 
int a[N]; 
 
void gen_random(int upper_bound) 

  int i; 
  for (i = 0; i < N; i++) 
    a[i] = rand() % upper_bound; 
}
void print_random() 

  int i; 
  for (i = 0; i < N; i++) 
    printf("a[%d]=%d ", i, a[i]); 
  printf("\n"); 



int main(void) 

  gen_random(10); 
  print_random(); 
  return 0; 



[root@redhat-beijing test]# gcc -Wall a.c
[root@redhat-beijing test]# ./a.out 
a[0]=3
a[1]=6
a[2]=7
a[3]=5
a[4]=3
a[5]=5
a[6]=6
a[7]=2
a[8]=9
a[9]=1
a[10]=2
a[11]=7
a[12]=0
a[13]=9
a[14]=3
a[15]=6
a[16]=0
a[17]=6
a[18]=2
a[19]=6


编译器的工作分为两个阶段,先是预处理(Preprocess)阶段,然后才是编译阶段,用gcc的-E选
项可以看到预处理之后、编译之前的程序:  gcc -E a.c
int a[20];


void gen_random(int upper_bound)
{
  int i;
  for (i = 0; i < 20; i++)
    a[i] = rand() % upper_bound;
}
void print_random()
{
  int i;
  for (i = 0; i < 20; i++)
    printf("a[%d]=%d\n", i, a[i]);
  printf("\n");
}


int main(void)
{
  gen_random(10);
  print_random();
  return 0;
}
[root@redhat-beijing test]# 


用cpp a.c也可以达到同样的效果,只作预处理而不编译,cpp表示C preprocessor。


#include <stdio.h> 
#define RECTANGULAR 1 
#define POLAR 2 
 
int main(void) 

  int RECTANGULAR; 
  printf("%d %d\n", RECTANGULAR, POLAR); 
  return 0; 

编译报错
[root@redhat-beijing test]# gcc -Wall a.c
a.c: In function ‘main’:
a.c:642: error: expected identifier or ‘(’ before numeric constant


在整形常量前不能加 int, 例如 int 3; 在编译时会报同样的错误。
将   int RECTANGULAR;  注释掉,就能编译通过。 
[root@redhat-beijing test]# gcc -Wall a.c
[root@redhat-beijing test]# ./a.out 
1 2


例 8.3. 统计随机数的分布 
#include <stdio.h> 
#include <stdlib.h> 
#define N 100000 
 
int a[N]; 
 
void gen_random(int upper_bound) 

  int i; 
  for (i = 0; i < N; i++) 
    a[i] = rand() % upper_bound; 

 
int howmany(int value) 

  int count = 0, i; 
  for (i = 0; i < N; i++) 
    if (a[i] == value) 
      ++count; 
  return count; 

 
int main(void) 

  int i; 
 
  gen_random(10);   
  printf("value\thow many\n"); 
  for (i = 0; i < 10; i++) 
    printf("%d\t%d\n", i, howmany(i)); 
 
  return 0; 
}   
程序运行结果:
[root@redhat-beijing test]# ./a.out 
value   how many
0       10130
1       10072
2       9990
3       9842
4       10174
5       9930
6       10059
7       9954
8       9891
9       9958
[root@redhat-beijing test]# 


1、用rand函数生成[10, 20]之间的随机整数,表达式应该怎么写? 
rand() % 11 + 10;


-----------------
直方图
#include <stdio.h>
#include <stdlib.h>
#define N 100000 


int a[N];


void gen_random(int upper_bound)
{
  int i;
  for (i = 0; i < N; i++)
    a[i] = rand() % upper_bound;
}


int howmany(int value)
{
  int count = 0, i;
  for (i = 0; i < N; i++)
    if (a[i] == value)
      ++count;
  return count;
}
int main(void)
{
  int i, histogram[10];


  gen_random(10);
  for (i=0; i< 10; i++)
        {
                histogram[i] = howmany(i);
                printf("histogram[%d]=%d\n", i, histogram[i]);
        }
printf("value\thow many\n");
  for (i = 0; i < 10; i++)
    printf("%d\t%d\n", i, howmany(i));


  return 0;
}
运行结果如下:
[root@redhat-beijing test]# gcc -Wall a.c -o a.out
[root@redhat-beijing test]# ./a.out 
histogram[0]=10130
histogram[1]=10072
histogram[2]=9990
histogram[3]=9842
histogram[4]=10174
histogram[5]=9930
histogram[6]=10059
histogram[7]=9954
histogram[8]=9891
histogram[9]=9958
value   how many
0       10130
1       10072
2       9990
3       9842
4       10174
5       9930
6       10059
7       9954
8       9891
9       9958
尽管上面的方法可以准确地得到统计结果,但是效率很低,这 100000个随机数
需要从头到尾检查十遍,每一遍检查只统计一种数字的出现次数。其实可以把
histogram中的元素当作累加器来用,这些随机数只需要从头到尾检查一遍
(Single Pass)就可以得出结果: 
#include <stdio.h>
#include <stdlib.h>
#define N 100000 


int a[N];


void gen_random(int upper_bound)
{
  int i;
  for (i = 0; i < N; i++)
    a[i] = rand() % upper_bound;
}


int main(void)
{
int i, histogram[10]={0};
gen_random(10);
for(i=0; i<10; i++)
        printf("histogram[%d]=%d\n",i,histogram[i]);
for(i=0; i<N; i++)
        {
                histogram[a[i]]++;
        }
for(i=0; i<10; i++)
        printf("histogram[%d]=%d\n",i,histogram[i]);
return 0;
}
输出:
[root@redhat-beijing test]# gcc -Wall a.c -o a.out 
[root@redhat-beijing test]# ./a.out 
histogram[0]=0
histogram[1]=0
histogram[2]=0
histogram[3]=0
histogram[4]=0
histogram[5]=0
histogram[6]=0
histogram[7]=0
histogram[8]=0
histogram[9]=0
histogram[0]=10130
histogram[1]=10072
histogram[2]=9990
histogram[3]=9842
histogram[4]=10174
histogram[5]=9930
histogram[6]=10059
histogram[7]=9954
histogram[8]=9891
histogram[9]=9958
编译运行几次,发现产生的结果一样,可知 rand()产生的是伪随机数。                    

在调用 rand()函数之前,先运行srand(time(NULL));  再次编译运行,会产生不同的结果。
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define N 100000 


int a[N];


void gen_random(int upper_bound) {
  int i;
  for (i = 0; i < N; i++)
    a[i] = rand() % upper_bound;
}


int main(void)
{
int i, histogram[10]={0};
srand(time(NULL));
gen_random(10);
for(i=0; i<N; i++)
        {
                histogram[a[i]]++;
        }
for(i=0; i<10; i++)
        printf("histogram[%d]=%d\n",i,histogram[i]);
return 0;
}
输出:
[root@redhat-beijing test]# gcc -Wall a.c -o a.out 
[root@redhat-beijing test]# ./a.out 
histogram[0]=10091
histogram[1]=10021
histogram[2]=10073
histogram[3]=10033
histogram[4]=10118
histogram[5]=9888
histogram[6]=10232
histogram[7]=9680
histogram[8]=9862
histogram[9]=10002

[root@redhat-beijing test]# 


习题
1、补完本节直方图程序的main函数,以可视化的形式打印直方图。例如上一节统计20个随机数的结果是:


0  1  2  3  4  5  6  7  8  9


*  *  *  *     *  *  *     *
*     *  *     *  *  *     *
      *  *        *
                  *
                  *


#include <stdio.h>  
#include <stdlib.h>  
#include <time.h>  
#define N 20  
  
int a[N];  
  
void gen_random(int upper_bound)  
{  
    int i;  
    unsigned int seed;  
    seed = time(NULL);  
    srand(seed);  
    for (i = 0; i < N; i++)  
        a[i] = rand() % upper_bound;  
}  
  
int main(void)  
{  
    int i, j, max = 0, histogram[10] = {0};  
  
    gen_random(10);  
    for (i = 0; i < N; i++)  
        histogram[a[i]]++;  
    //水平方向打印  
    printf("水平方向:\n");  
    for (i = 0; i < 10; i++) {  
        printf("%d  ", i);  
        for (j = 0; j < histogram[i]; j++)  
            printf("* ");  
        printf("\n");  
    }  
  
    //垂直打印  
    printf("\n\n垂直方向:\n");  
    for (i = 0; i < 10; i++) {  
        max = (max > histogram[i]) ? max : histogram[i];  
        printf("%d ", i);  
    }  
    printf("\n\n");  
    for (i = 0; i < max; i++) {  
        for (j = 0; j < 10; j++) {  
            if (histogram[j] > 0) {  
                printf("* ");  
                --histogram[j];  
            } else  
                printf("  ");  
        }  
        printf("\n");  
    }  
    printf("\n");  
  
    return 0;  
}  
输出:
[root@redhat-beijing test]# gcc -Wall a.c -o a.out
[root@redhat-beijing test]# ./a.out 
水平方向:
0  * * * 
1  * * 
2  * * 
3  * * * 
4  
5  * * * 
6  * * * 
7  * * 
8  * 
9  * 




垂直方向:
0 1 2 3 4 5 6 7 8 9 


* * * *   * * * * * 
* * * *   * * *     
*     *   * *     



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值