EEEE 1042/1032 INTRODUCTION TO SOFTWARE ENGINEERING AND PROGRAMMING

Hello, if you have any need, please feel free to consult us, this is my wechat: wx91due

EEEE 1042/1032 INTRODUCTION TO SOFTWARE
ENGINEERING AND PROGRAMMING
Time allowed: TWO Hours + 30 min upload time
Answer ALL questions. Please read them carefully
There is a maximum of 80 marks available.
Marks awarded for sections of questions are shown in brackets after the relevant section.
This Exam is worth 40% of the full-year EEEE1042 10-credit module.
1. (a)  Give a description of the three main stages that the compiler goes through as it processes a C-program to an executable file. Describe the inputs
and outputs that are created at each stage, and how the files are brought together to form the final-output executable file. Give as much detail for each stage as you are able.[10 marks]


(b) i) What is the difference between a function definition and a function declaration in terms of what they do and their significance to the compiler?[4 marks]


ii) What category of C-token is a function to the C-compiler? Given that it is this category of C-token, where are the typical, or required places where the function definitions and function declarations reside within the source code, or system and why are they located there? [6 marks]


2. (a) Describe what are the two input parameters argc and argv to the main function. [3 marks]


(b) i) Create a small program in C showing how you would sequentially process each input given to your C-program at the command line. For each input coming from the command-line, show how you would pass it to a subfunction called progessInput() being called to processes each input from the command line. The subfunction progessInput() should just take the input argument and the index and print them both to the screen, and then return to the calling environment. Include a short main that calls progessInput()  for each input parameter given by the user at the command line. Save your program to the file: lastName_firstName_EEEE1042Final_2b.c and submit it together with your exam. For full marks you must adequately comment your code.[9 marks]

ii) Write a second version of the function progessInput2() that instead of printing the string, prints the string in reverse. For example if the input is "abcdef" the function prints "fedcba". Setup your program such that it can be switched between the original progessInput() and the new progessInput2() at the calling line in main to easily switch between testing of the two functions you’ve created. [8 marks]

3. (a) i) What is the difference between call by reference and call by value? Discuss the different ways in which functions can modify variables in the environment in which they are called.[4 marks]
(b) Write a short C program that demonstrates:

i) An example of a function that uses calling by value. Create a main that declares and initializes two floats of your choice, and passes them into thefunction which returns the product of the two. Save your program to the file: lastName_firstName_EEEE1042Final_3bi.c and submit it together with your exam. For full marks you must adequately comment your code. [5 marks]

ii) An example of a function that uses calling by reference. Create a main that declares and initializes two floats and passes them into the function that exchanges their values. Save your program to the file:

lastName_firstName_EEEE1042Final_3bii.c and submit it together with your exam. For full marks you must adequately comment your code. [5 marks]

iii) Repeat b)ii above, but now swapping two strings (char-arrays) First string  and Second string  rather than two floats. Save your program to the file: lastName_firstName_EEEE1042Final_3biii.c and submit it together with your exam. For full marks you must adequately comment your code. [6 marks]

4. (a) Julius Caesar used a cipher to keep his communications safe from spies and enemy capture. Caesar’s cipher was simple: he shifted each letter over by 3 such that a→d , b→e  etc... while towards the end of the alphabet, x→a , y→b❜ and z→c .

Write a C function that implements the Caesar cipher named caesarCipher(). The function should take 4 input parameters:

1. input: an input array of characters provided by the function caller to be encoded

2. output: a pointer to an output array of characters to be filled-in by the function

3. N: the number of characters in the input string which needs to be equal to (at least) the number of characters in the output string.

4. os: an offset shift of characters which was equal to 3 in the original Caesar code.

The function should shift the N characters ininput by os, copying them into output, modulo 26.

Create a main program that shows how to call your above de- fined function with the input "abcdefghijklmnopqrstuvwxyz" first and with "ABCDEFGHIJKLMNOPQRSTUVWXYZ" next and with offset os=15 in the both cases. Save your program to the file: lastName_firstName_EEEE1042Final_4.c and submit it together with your exam. For full marks you must adequately comment your code.[17 marks]

(b) Use your function to decipher the message: "Oazsdmfgxmfuaze kag tmhq odmowqp ftq oubtqd ftdagst ndgfq radoq"[3 marks]

1a [10]. There are three main stages that the compiler goes through on the way to creating the executable program:

1. The first stage is C-Preprocessing. The C preprocessor provides various functionalities prior to passing it to the compiler:

• Inclusion of header files via #include<>. These are files of declarations that can be substituted into your program.

• Macro expansion via #define. You can define macros, which are abbreviations for arbitrary fragments of C code, and then the C preprocessor will replace the macros with their definitions throughout the program.

• Conditional compilation via #ifdef. Using special preprocessing directives, you can include or exclude parts of the program according to various conditions.

2. Compilation: The compiler steps through each line of the C program processing it token by token and converting line by line into object code. When the compiler encounters a subfunction call, it creates a stub in the object code that details the passing of inputs to and retrieving of outputs from that subfunction. The rest of the source code is compiled into machine language that the CPU is able to execute.

3. Linking: The compiler (or now linker) links object code from various subfunctions and sources together into the final executable program. Where ever there was previously a stub to a subfunction in the object-code file, the linker must be told (or know) where to retrieve that function and connect it to

that subfunction in the final executable.
1b i[4]. A function declaration declares the function to the compiler, which means it makes the function known to the compiler. Once the function is declared to the compiler, the compiler knows how to create the object code stub for that subfunction when it is called.
A function definition defines what the function does with its inputs and how it generates the function outputs that are returned to the calling environment.

1b ii[6]. Functions are within the identifier category of C-tokens.

As they are identifiers, functions must be declared prior to them first being used (or called) within the program. Thus function declarations are placed above the main  function or within the header files that are #include’d in at the start of the C - program.

Function definitions can occur anywhere so long as the compiler is told (or knows) where to find them, as they are not used until the linking stage. Some typical placeswhere they can occur are: before the main program, after the main program, in another .c file (in which case the compiler must be given that file for linking) or in another library (in which case the compiler must be given the name of the library for linking).

2a [3]. argc is an integer denoting the number of arguments typed at the command line. argv is an array of strings, each string being one of the argc inputs typed in at the command line. argv[] is the name of the calling program while argv[1] onwards
are the parameters being passed into the program.
2b i[9].#include<stdio.h>
void processInput(intindex,char *parmName); // function declaration
// Main function
int main(int argc,char **argv) {
int i;
for (i=0;i<argc;i++) {
processInput (i,argv[i]);
}
}
// processInput function
void processInput(intindex,char *parmName){
printf("%2d %s\n",index,parmName);
}
2b ii[8]. // processInput2 function
void processInput2(intindex, char *parmName) {
int i;
printf("%2d ",index);
for (i=strlen(parmName);i--;i>=0){
printf("%c",parmName[i]);
}
printf("\n");

3a i[4]. Call-by-reference and call-by-value refer to two ways in which functions are called in C. In call-by-value, the value of the input parameter is passed to the function by copying it into a local variable within the function’s scope and the function receives its input variable through the copy in the local variable. The function can modify this local variable, but it has no impact on the original variable in the calling environment scope.

Call-by-reference on the other hand, passes the address of the variable to the function. The function therefore has access to the same memory assigned to that variable in the calling environment’s scope and therefore it can change the variable’s value within the calling environment.

A function can modify variables in the calling environment either through its return value, which the calling function needs to assign to an appropriate variable in the calling environment, or through call-by-reference. Only 1 value can be returned directly through the return() function. Therefore any additional variables that need to be returned by the function must be returned through call-by-reference, in which the function modifies the variable in the calling environment by use of a pointer.

3b i[5].// Example of a function that uses call-by-value
float calcProduct(float a, float b) {
return(a*b);
}
int main(){
float a=5,b=7;
float z;
z=calcProduct(a,b);
printf("a=%f,b=%f,z=%f\n",a,b,z);
3b ii[5]. // Example of a function that uses call-by-reference to swap 2 floats
void swapFloats(float *a, float *b) {
float tmp;
tmp = *a;
*a =*b;
*b=tmp;
return;
}
int main() {
float a=5,b=7;
printf("Before swap: a=%f,b=%f\n",a,b);
swapFloats(&a,&b);
printf("After swap: a=%f, b=%f\n",a,b);
}
3b iii[6]. // Example of a function that uses call-by-reference to swap strings
void swapStrings(char **a, char **b) {
char *tmp;
tmp = *a;
*a =*b;
*b=tmp;
return;
}
int main(){
char s1[]="First string";
char s2[]="Second string";
char *s3=s1,*s4=s2;
printf("Before Swapping:\ns3=%s\ns4=%s\n",s3,s4);
swapStrings(&s3,&s4);
}
printf("After Swapping:\ns3=%s\ns4=%s\n",s3,s4);

4a [17]. #include<stdio.h>
#include<string.h>
void caesarCipher(const unsigned char *input, unsigned char *output, int
N, int os){
for (i=0;i<N;i++) {
if((input[i]>='a’&& input[i]<='z')||(input[i]>='A’&&
int i;
input[i]<='Z')) {
output[i]=input[i]+os;
if((output[i]>'z')&&(input[i]<='z’)) output[i]-=26;
if ((output[i]>'Z’)&&(input[i]<='Z')) output[i]-=26;
} else {
output[i]=input[i];
}
}
output[N]='\0’;
int main (int argc,char **argv) {
char input[]="abcdefghijklmnopqrstuvwxyz";
char output [60];
int os=15;
caesarCipher(input,output,strlen(input),os);
printf("input =%s\n",input);
printf("outp|ut=%s\n",output);
int i;
char input2[]="0azsdmfgxmfuaze kag tmhq odmowqp ftq oubtqd ftdagst
ndgfq radoq";
for (i=1;i<26;i++){
}
caesarCipher(input2,output,strlen(input2),i);

printf("%2d %s\n",i,output);

}

}


4b [3]. Trying to shift the encoded message by all offsets from 1 to 26 allows us to find the deciphered message: "Congratulations you have cracked the ,cipher through brute force"

发表评论

电子邮件地址不会被公开。 必填项已用*标注