0% found this document useful (0 votes)
6 views7 pages

C Questions

The document outlines various concepts and limitations of the C programming language, including array limitations, pointer types, memory allocation, and the use of typedef. It explains the differences between object files and executable files, the importance of return statements in functions, and the accessibility of variables in nested blocks. Additionally, it covers the use of preprocessor directives, static functions, and the distinction between character constants and string literals.

Uploaded by

foheke6586
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views7 pages

C Questions

The document outlines various concepts and limitations of the C programming language, including array limitations, pointer types, memory allocation, and the use of typedef. It explains the differences between object files and executable files, the importance of return statements in functions, and the accessibility of variables in nested blocks. Additionally, it covers the use of preprocessor directives, static functions, and the distinction between character constants and string literals.

Uploaded by

foheke6586
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 7

1.

Limitations of arrays in C
Arrays in C have several limitations:

 Fixed size that must be declared at compile time (unless using dynamic allocation)
 No bounds checking (can lead to buffer overflows)
 Cannot be resized without creating a new array
 Cannot return entire arrays from functions (only pointers to them)
 No built-in methods to find length or perform operations like sorting

Example of fixed size limitation:

int numbers[5]; // Can only store 5 integers


numbers[5] = 10; // This is out of bounds but C won't detect it

2. Dangling and null pointers


Null pointer: A pointer that doesn't point to any memory location. It's explicitly assigned
NULL.

int *ptr = NULL; // Null pointer

Dangling pointer: A pointer that points to memory that has been freed or is no longer valid.

int *ptr = (int *)malloc(sizeof(int));


free(ptr); // ptr is now a dangling pointer
// Using ptr here is dangerous

3. Far, near, and huge pointers


These are memory model concepts from older C compilers for 16-bit systems:

 Near pointer: 16-bit pointer that can access only the current segment (64KB)
 Far pointer: 32-bit pointer with 16 bits for segment and 16 bits for offset
 Huge pointer: Similar to far pointers but with normalized segment:offset

Modern C on 32/64-bit systems typically doesn't use these distinctions.

4. Use of #define in C
#define is a preprocessor directive used to define constants and macros:

// Define a constant
#define PI 3.14159

// Define a macro
#define SQUARE(x) ((x) * (x))

int main() {
float radius = 5.0;
float area = PI * SQUARE(radius);
printf("Area: %f\n", area);
return 0;
}

5. Static function in C
A static function is only visible within the file it's defined in. It can't be called from other
files.

// This function is only visible in this file


static int privateFunction() {
return 42;
}

// This function can be called from other files


int publicFunction() {
return privateFunction() + 10;
}

6. Difference between " " and < > for include


 #include "file.h" - Searches for the header file first in the current directory, then
in standard directories
 #include <file.h> - Searches only in standard system directories

Use double quotes for your own header files and angle brackets for system headers:

#include <stdio.h> // System header


#include "myheader.h" // User-defined header

7. Nested loops
Nested loops are loops inside other loops. The inner loop completes all its iterations for each
iteration of the outer loop.

// Print a 5x5 multiplication table


for (int i = 1; i <= 5; i++) {
for (int j = 1; j <= 5; j++) {
printf("%d\t", i * j);
}
printf("\n");
}

8. Difference between object file and executable file


 Object file (.o or .obj): Contains machine code but isn't directly executable. It has
unresolved references to external functions.
 Executable file (.exe or no extension): Fully linked program that can be executed
directly. All references are resolved.

Compilation process:
1. Source code (.c) → Compiler → Object file (.o)
2. Object file(s) → Linker → Executable file

9. Program using dynamic memory allocation


#include <stdio.h>
#include <stdlib.h>

int main() {
int size, i, sum = 0;
int *numbers;

printf("How many numbers? ");


scanf("%d", &size);

// Allocate memory
numbers = (int *)malloc(size * sizeof(int));

if (numbers == NULL) {
printf("Memory allocation failed\n");
return 1;
}

// Get values
for (i = 0; i < size; i++) {
printf("Enter number %d: ", i+1);
scanf("%d", &numbers[i]);
sum += numbers[i];
}

printf("Sum: %d\n", sum);

// Release memory
free(numbers);

return 0;
}

10. Difference between 'I' and 'II'


In C:

 'I' is a character constant with ASCII value 73


 "I" is a string literal (character array) containing 'I' and '\0'

char c = 'I'; // Single character


char *s = "I"; // String (array of characters)

11. Converting a character to ASCII


In C, characters are already stored as their ASCII values, so you can:

#include <stdio.h>

int main() {
char ch = 'A';
int ascii = (int)ch; // Explicit conversion (optional)

printf("The ASCII value of %c is %d\n", ch, ascii);


// Or simply:
printf("The ASCII value of %c is %d\n", ch, ch);

return 0;
}

12. Integer addition/subtraction with pointers


When you add or subtract an integer from a pointer, the pointer moves by that many elements
of the pointer's type:

#include <stdio.h>

int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *ptr = arr; // Points to first element

printf("*ptr = %d\n", *ptr); // 10

ptr = ptr + 2; // Move forward 2 integers (8 bytes on most systems)


printf("*ptr after +2 = %d\n", *ptr); // 30

ptr = ptr - 1; // Move back 1 integer


printf("*ptr after -1 = %d\n", *ptr); // 20

return 0;
}

13. Using typedef for structures


typedef creates a new name (alias) for a data type, making structure declarations cleaner:

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

// Without typedef
struct Person {
char name[50];
int age;
};

// With typedef
typedef struct {
char name[50];
int age;
} Student;

int main() {
// Without typedef
struct Person person1;
strcpy(person1.name, "John");
person1.age = 25;
// With typedef
Student student1;
strcpy(student1.name, "Alice");
student1.age = 20;

printf("%s is %d years old\n", person1.name, person1.age);


printf("%s is %d years old\n", student1.name, student1.age);

return 0;
}

14. Block scope for an identifier


In C, block scope means a variable is only accessible within the block (code between { })
where it's declared:

#include <stdio.h>

int main() {
int outer = 10;

{ // Start of a new block


int inner = 20;
printf("Inside block: outer = %d, inner = %d\n", outer, inner);
} // End of block

printf("Outside block: outer = %d\n", outer);


// printf("inner = %d\n"); // Error: inner is not accessible here

return 0;
}

15. How nested blocks affect accessibility


Variables in outer blocks are accessible in inner blocks, but not vice versa:

#include <stdio.h>

int main() {
int a = 10;

{
int b = 20;
printf("Inner block can access a: %d\n", a);

{
int c = 30;
printf("Innermost block can access a: %d, b: %d\n", a, b);
}

// Cannot access c here


}

// Cannot access b or c here

return 0;
}
16. When is the return statement mandatory in a
function?
The return statement is mandatory in functions with non-void return types:

// Must have return statement


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

// Return statement optional


void greet() {
printf("Hello!\n");
// return; is optional here
}

17. Why void pointers need explicit type casting


Void pointers have no type information, so the compiler doesn't know how many bytes to
dereference:

#include <stdio.h>

int main() {
int num = 42;
void *vptr = &num;

// This won't work: printf("%d\n", *vptr);

// Need explicit casting


printf("%d\n", *(int *)vptr);

return 0;
}

18. Pointer to a pointer


A pointer to a pointer is a variable that stores the address of another pointer:

#include <stdio.h>

int main() {
int value = 42;
int *ptr = &value; // Pointer to value
int **ptrToPtr = &ptr; // Pointer to pointer

printf("value: %d\n", value);


printf("*ptr: %d\n", *ptr);
printf("**ptrToPtr: %d\n", **ptrToPtr);

return 0;
}

19. Extending pointers to multiple levels


Yes, pointers can be extended to any level by adding more asterisks:

#include <stdio.h>

int main() {
int value = 42;
int *ptr1 = &value; // Level 1
int **ptr2 = &ptr1; // Level 2
int ***ptr3 = &ptr2; // Level 3
int ****ptr4 = &ptr3; // Level 4

// Access the value through all levels


printf("value: %d\n", value);
printf("*ptr1: %d\n", *ptr1);
printf("**ptr2: %d\n", **ptr2);
printf("***ptr3: %d\n", ***ptr3);
printf("****ptr4: %d\n", ****ptr4);

// Modify the value through the deepest pointer


****ptr4 = 100;
printf("After modification, value = %d\n", value);

return 0;
}

This verifies that pointers can be extended to any level, limited only by practical
considerations.

You might also like