A Review of Some C Language Knowledge Points Learned in Student Age

A Review of Some C Language Knowledge Points Learned in Student Age (1)

0. Preface

Time flies so fast that I have graduated for many years in the blink of an eye. C is the first programming language I learned in college. Because it has been unused for a long time, many knowledge points have become unfamiliar. Recently, I took a space to review some of the previous knowledge points. I would like to record these knowledge points just reviewed with this series of articles.

1. Multiplication of Integer and Floating Point Data Types

#include<stdio.h>
int main()
{
  int a = 20;
  float b = 20.34;
  printf("%f\n",a*b);
  return 0;
}
//406.799988
#include<stdio.h>
int main()
{
  int a = 20;
  float b = 20.34;
  printf("%d\n",a*b);
  return 0;
}
//-1409143032
#include<stdio.h>
int main()
{
  int a = 20;
  float b = 20.34;
  printf("%d\n",(int)(a*b));
  return 0;
}
//406

Integers cannot save floating-point data without mandatory type conversion.

2. Command-line parameterization

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char *argv[])
{
  int memory_num = 0;
  int i;
  char *cmd,*temp;
  for (i = 0; i < argc; i++)
      memory_num += strlen(argv[i]);
  cmd = (char *)malloc(memory_num + argc*strlen(" "));
  for (i = 1; i < argc; i++)
  {
     //printf("argv:%s\n",argv[i]);
     temp = (char *)malloc(strlen(argv[i])+strlen(" "));
     strcpy(temp,argv[i]);
     strcat(temp," ");
     //printf("argc[%d]:%s|\n",i,temp);
     strcat(cmd,temp);
     free(temp);
  }
  printf("%s\n",cmd);
  system(cmd);
  return 0;
}
/*
$ ./cmd ls /;tree ~/docker-build/tesseract-ocr/
ls /
bin  boot  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
/home/gysl/docker-build/tesseract-ocr/
├── 124.jpg
├── 124.txt
├── 1.png
├── 2.jpg
├── 3.jpg
├── 4.png
├── 4.txt
├── build
│   ├── 4.1.0.tar.gz
│   ├── Dockerfile
│   ├── leptonica-1.78.0.tar.gz
│   └── tesseract_langs.tar.gz
├── gysl.jpg.txt
├── gysl.txt
└── langs
    ├── chi_sim.traineddata
    ├── chi_sim_vert.traineddata
    └── eng.traineddata

2 directories, 16 files
*/

This code demonstrates the specific case of main() function parameter transfer, a little modification can be used for encryption of some shell scripts with higher security.

3. Operator priority

#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 5, b, c;
  c = (b = a + 2) - (a=1);
  printf("%d\t%d\n",c,a);
  return 0;
}

// 6       1

4. Comma operators in for statements

#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 15, b = 26, i, j;
  for ( ; i < a, j < b;i++, j++)
  {}
  printf("%d\t%d\n",i,j);
  return 0;
}
// 26      26
#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 15, b = 26, i, j;
  for ( ; i < a, j < b;i++, j++)
  ;//{}
  printf("%d\t%d\n",i,j);
  return 0;
}
// 26      26
#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 15, b = 26, i, j;
  for ( ; i < a, j < b;i++, j++)
  //{}
  printf("%d\t%d\n",i,j);
  return 0;
}
/*
0       0
1       1
2       2
3       3
4       4
5       5
6       6
7       7
8       8
9       9
10      10
11      11
12      12
13      13
14      14
15      15
16      16
17      17
18      18
19      19
20      20
21      21
22      22
23      23
24      24
25      25
*/
#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 15, b = 6, i, j;
  for ( ; i < a, j < b;i++, j++)
  {}
  printf("%d\t%d\n",i,j);
  return 0;
}
// 6       6
#include<stdio.h>

int main(int argc,char *argv[])
{
  int a = 5, b = 6, i, j;
  for ( ; i < a, j < b;i++, j++)
  //{}
  printf("%d\t%d\n",i,j);
  return 0;
}
/*
0       0
1       1
2       2
3       3
4       4
5       5
*/

In this case, the value of a variable is the upper limit. The for statement continues to execute the last part of the loop body once the loop ends.

5. Length of each data type

#include<stdio.h>

int main(int argc,char *argv[])
{
  printf("int:%d\nlong int:%d\nshort int:%d\nunsigned int:%d\nunsigned long int:%d\nunsigned short int:%d\n",sizeof(int),sizeof(long int),sizeof(short int),sizeof(unsigned int),sizeof(unsigned long int),sizeof(unsigned short int));
  return 0;
}
/*
int:4
long int:8
short int:2
unsigned int:4
unsigned long int:8
unsigned short int:2
*/

6. Structures

#include <stdio.h>
struct stu{
    char *name;  //Full name
    int num;  //Student ID
    int age;  //Age
    char group;  //Working Group
    float score;  //achievement
}stus[] = {
    {"Zhou ping", 5, 18, 'C', 145.0},
    {"Zhang ping", 4, 19, 'A', 130.5},
    {"Liu fang", 1, 18, 'A', 148.5},
    {"Cheng ling", 2, 17, 'F', 139.0},
    {"Wang ming", 3, 17, 'B', 144.5}
}, *ps;
int main(){
    //Finding Array Length
    int len = sizeof(stus) / sizeof(struct stu);
    printf("Name\t\tNum\tAge\tGroup\tScore\t\n");
    for(ps=stus; ps<stus+len; ps++){
        printf("%s\t%d\t%d\t%c\t%.1f\n", ps->name, ps->num, ps->age, ps->group, ps->score);
    }
    return 0;
}

7. Some Questions Worth Consideration

# include<stdio.h>
# include<string.h>

int main(int argc,char *argv[])
{
  char e[4] = "20d0";
  int i;
  printf("Sizeof: %d\t%d\n",(sizeof e),strlen(e));
  printf("Sizeof int: %d\n",sizeof (int));
  printf("Sizeof e: %d\n",sizeof (e));
/*
  for ( i = 0; i < strlen(e); i++)
    printf("e[%d]: %c\n",i,e[i]);
*/
  printf("%lu\n",((unsigned long)sizeof(int)));
  return 0;
}

When the comment section of the above code is removed, the value of the first printf output will be different.

8. Initialization of arrays

# include<stdio.h>

int main(int argc, char *argv[]){
  int a[10] = {1,2,4,5,[0] = 0,6,8,9,3};
  int i = 0;
  for ( i = 0; i < 10; i++)
    printf("a[%d]: %d\n",i, a[i]);
  return 0;
}
/*
a[0]: 0
a[1]: 6
a[2]: 8
a[3]: 9
a[4]: 3
a[5]: 0
a[6]: 0
a[7]: 0
a[8]: 0
a[9]: 0
*/
# include<stdio.h>

int main(int argc, char *argv[]){
  int a[10] = {1,2,4,5,[3] = 0,6,8,9,3};
  int i = 0;
  for ( i = 0; i < 10; i++)
    printf("a[%d]: %d\n",i, a[i]);
  return 0;
}
/*
a[0]: 1
a[1]: 2
a[2]: 4
a[3]: 0
a[4]: 6
a[5]: 8
a[6]: 9
a[7]: 3
a[8]: 0
a[9]: 0
*/

Such an affirmation is unlawful. The compiler processes the initialization list by recording the location of the next array element to be initialized. Normally, the next element is the one behind the element that has just been initialized. However, when an initializer appears in the list, the next element is forced to be the corresponding element of the indicator, even if the element has already been initialized.

9. Initialization of variable-length arrays

# include<stdio.h>

int main(int argc, char *argv[]){
  int n, i, a[n];
  scanf("%d",&n);
  for ( i = 0; i < n; i++){
    scanf("%d",&a[i]);
  }
  for ( i = 0; i < n; i++){
    printf("a[%d]: %d\n",i,a[i]);
  }
  return 0;
}
/*
3
5
8
1
a[0]: 5
a[1]: 8
a[2]: 1
*/

The n inside square brackets in line 4 of the code cannot be omitted. The length of variable-length arrays is calculated at execution time. Variable-length arrays can also be multidimensional.

10. Nested calls to functions

# include<stdio.h>

int main(int argc, char *argv[]){
  int array[10] = { 2,1,0,3,6,5,4,7,9,8};
  int ModifyNumber(int a[],int i);
  void show(int a[], int n);
  show(array,10);
  ModifyNumber(array,3);
  printf("The value has been updated. Please check: \n");
  show(array,10);
  return 0;
}
int ModifyNumber(int a[],int i){
  void PrintMsg();
  PrintMsg();
  scanf("%d",&a[i]);
  return 0;
}

void PrintMsg(){
  printf("Please input a new value:\n");
}

void show(int array[], int n){
  for (int i = 0; i < n; i++){
    printf("Array[%d]: %d\n", i, array[i]);
  }
}
/*
Array[0]: 2
Array[1]: 1
Array[2]: 0
Array[3]: 3
Array[4]: 6
Array[5]: 5
Array[6]: 4
Array[7]: 7
Array[8]: 9
Array[9]: 8
Please input a new value:
90
The value has been updated. Please check:
Array[0]: 2
Array[1]: 1
Array[2]: 0
Array[3]: 90
Array[4]: 6
Array[5]: 5
Array[6]: 4
Array[7]: 7
Array[8]: 9
Array[9]: 8
*/

In C language, defining functions are allowed to call each other (calling another function in one function), but nested definitions of functions (defining another function in one function) are not allowed. Similar to the following function definition, it can be compiled through the system, but the program can not be executed properly:

# include<stdio.h>
int main(int argc,char *argv[]){
  void SendMsg();
  void PrintMsg();
  SendMsg();
  PrintMsg();
  return 0;
}

void SendMsg(){
  void PrintMsg();
  PrintMsg();
  printf("This  function is SendMsg.\n");
}

void PrintMsg(){
  void SendMsg();
  SendMsg();
  printf("This function is PrintMsg.\n");
}

This is an indirect recursive form, which must ensure the normal termination of the two functions.

11. Static variables

# include<stdio.h>
int main(int argc,char *argv[]){
  int Sta(int);
  int  n;
  scanf("%d",&n);
  printf("First value: %d\n",Sta(n));
  printf("Second value: %d\n",Sta(n));
  return 0;
}

int Sta(int n){
  static int b = 0;
  b = b + n;
  return b;
}
/*
6
First value: 6
Second value: 12
*/

When the Sta() function is called the second time, the value of the static variable b is already 6. In other words, static variables hide data from other functions and retain it for future calls.

12. Local and external variables

# include<stdio.h>
int main(int argc,char argv[]){
  void test();
  extern int i;
  test();
  printf("%d\n",i);
  return 0;
}

int i = 1;

void test(){
  int j = i;
  int i =2;
  printf("%d\n",j);
}
// 1
// 1

The code is legal. If the keyword extern is removed, the second printed value will be 0.

Tags: Docker C Programming shell

Posted on Mon, 09 Sep 2019 03:29:59 -0700 by EODC