You are on page 1of 28

1.

C Program to print numbers from 1 to N


without using semicolon?

Method 1 (Recursive)
// A recursive C program to print all numbers from 1
// to N without semicolon
#include<stdio.h>
#define N 10

int main(int num)


{
if (num <= N && printf("%d ", num) && main(num + 1))
{
}
}
Output: 1 2 3 4 5 6 7 8 9 10
Method 2 (Iterative)
// An iterative C program to print all numbers from 1
// to N without semicolon
#include<stdio.h>
#define N 10

int main(int num, char *argv[])


{
while (num <= N && printf("%d ", num) && num++)
{
}
}

Output: 1 2 3 4 5 6 7 8 9 10
How do these solutions work?
• main() function can receive arguments. The first
argument is argument count whose value is 1 if no
argument is passed to it. The second argument is always program
name.
#include<stdio.h>
int main(int num, char *argv[])
{
printf("num = %d\n", num);
printf("argv[0] = %s ", argv[0]);
return 0;
}
Output:
num = 1
argv[0] = <file_name>
2. Print “Hello World” in C without using any header
file:

//Declare the printf() function


int printf(const char *format, ...);

int main()
{
printf( "Hello World" );
return 0;
}

Output: Hello World


Declaration for printf():

• The C library function int printf(const char *format, ...) sends


formatted output to stdout

• Following is the declaration for printf() function

• int printf(const char *format, ...)


3. How to print a variable name in C?

#include <stdio.h>
#define getName(var) #var

int main()
{
int MyVar = 10;
printf("%s", getName(MyVar));
return 0;
}

Output:
MyVar
Stringizing Operator (#)
• Converts macro parameters to string literals without expanding the
parameter definition
• It is used only with macros that take arguments

#include<stdio.h>
#define printf_s( x ) printf(#x "\n")
int main()
{
printf_s( In quotes in the printf function call);
printf_s( "In quotes when printed to the screen" );
printf_s( "This: \" prints an escaped double quote" );
return 0;
}
Charizing Operator (#@):

• The charizing operator can be used only with


arguments of macros.
• Treated as a character when the macro is
expanded
Token-Pasting Operator (##)

• (##), which is sometimes called the "merging" operator, is used in


both object-like and function-like macros

#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
return 0;
} Output: token9 = 9
4. Write a C program to print “FACE” without using a
semicolon:

Using if condition:

#include<stdio.h>
int main()
{
if (printf(“FACE") )
{ }
}
Output: FACE
Using while condition:

#include<stdio.h>
int main(){
while (!printf( “FACE" ))
{ }
}
Using switch case:

#include<stdio.h>
int main(){
switch (printf(" FACE " ))
{ }
}
Using Macros

#include<stdio.h>
#define PRINT printf(" FACE ")
int main()
{
if (PRINT)
{ }
}
5. How to write a running C code without main()?

Using a macro that defines main

#include<stdio.h>
#define fun main
int fun(void)
{
printf(" FACE ");
return 0;
}
Output: FACE
Using Token-Pasting Operator

#include<stdio.h>
#define fun m##a##i##n
int fun()
{
printf(" FACE ");
return 0;
}

Output: FACE
Using Argumented Macro:

#include<stdio.h>
#define begin(m,a,i,n) m##a##i##n
#define start begin(m,a,i,n)

void start() {
printf(" FACE ");
}

Output: FACE
6. To find sum of two numbers without using any
operator

int add(int x, int y)


{
return printf("%*c%*c", x, ' ', y, ' ');
}
int main()
{
printf("Sum = %d", add(3, 4));
return 0;
}

Output:
Sum = 7
Output without leading spaces:
int add(int x, int y)
{
return printf("%*c%*c", x, '\r', y, '\r');
}

int main()
{
printf("Sum = %d", add(3, 4));
return 0;
}

Output:
Sum = 7
7. Print a character 'A', without using format
specifiers.

Representing in hex:

#include <stdio.h>
int main(void)
{
printf("\x41");
return 0;
}
8. Print a character 'A', without using format
specifiers (using octal).

#include <stdio.h>
int main()
{
printf("\101");
return 0;
}
Wild pointer:

• Uninitialized pointers are known as wild pointers because


they point to some arbitrary memory location and may cause
a program to crash or behave badly

int function1()
{
int a=5;
int *b; // wild pointer(uninitialized)
printf("value of a=%d",a);
}
Dangling pointer:

• A pointer pointing to a memory location that has been


deleted (or freed) is called dangling pointer. The memory location
pointed by dangling pointer is known as dangling reference

void function(){
int *ptr = (int *)malloc(SIZE);
......
......
free(ptr); //ptr now becomes dangling pointer
which is pointing to dangling reference
ptr=NULL; //now ptr is not dangling pointer
}
Void pointer:
• Pointers defined using specific data type cannot hold the address
of the some other type of variable . When a pointer variable is
declared using keyword void – it becomes a general purpose pointer
variable. Address of any variable of any data type (char, int, float etc.)can
be assigned to a void pointer variable. Pointer arithmetic can not be
performed in a void pointer. To De-reference this void pointer we should
typecast the pointer variable.
void main()
{
int a=10;
void *ptr; // Declaring a void pointer
ptr=&a; // Assigning address of integer to void pointer.
printf("The value of integer variable is= %d",*( (int*) ptr) );
// (int*)ptr - is used for type casting. Where as *((int*)ptr)
dereferences the typecasted void //pointer variable.
}
Generic pointer:

• Void pointer or generic pointer is a special type of pointer that


can be pointed at objects of any data type. void pointer is
itself called generic pointer.
Null Pointer:
• Points to nothing. It is always a good practice to assign a NULL
value to a pointer variable in case you do not have an exact
address to be assigned. This is done at the time of variable declaration. A
pointer that is assigned NULL is called a null pointer.

#include <stdio.h>
int main () {
int *ptr = NULL; // Null pointer
printf("The value of ptr is : %x\n", ptr ); //ptr print 0.
return 0;
}

• The NULL pointer is a constant with a value of zero defined in several


standard libraries(stdio.h, alloc.h, mem.h, stddef.h, stdlib.h).
Far, huge, near pointers:
• far pointer : A far pointer is a 32-bit pointer and contains both a segment
address and an offset address.

• huge pointer : A huge pointer is also 32-bit pointer and contains both a
segment address and an offset address. When a far pointer is incremented
or decremented ONLY the offset of the pointer is actually incremented or
decremented but in case of huge pointer both segment and offset value
will change.

• near pointer : A near pointer is a 16-bit pointer. The current content of the
Code Segment or Data Segment is used as the segment part and near
pointer contains the offset part.

You might also like