Native C
1) Is C an Interpreted or Compiled language ?
C is Compiled.
This means there is a build/compile step.
The compiler needs to take the code, process it and create a binary executable.
2) Is C a Strongly or Weakly Typed programming language ?
C is Weakly Typed.
It allows implicit type conversion when data types are not compatible.
There is aggressive implicit type conversion.
char letter = 'A'; // ASCII value is 65
int number = 10;
double result;
result = letter + number;
printf("Result: %f\n", result); // Outputs: 75.00
3) Is C a Dynamically or Statically Typed programming language ?
C is Statically Typed.
You must declare a variable's type before using it, and that variable's type can never change during execution.
If you declare a variable called "MyVar" to be an int data type, it will always be an int.
int myNumber = 10;
char myLetter = 'A';
double myPrice = 10.35;
4) What is the latest version of the C Programming language.
This is C23, released in 2024.
5) Do I need to use C++ to be my XLL or can everything be done using C ?
Everything can be done using C.
The C programming language in 1997 (C89) was very different to the latest version (C23).
The following are now all possible.
mixed declarations and statements
loop local variables
boolean data type
64 bit integer support (long long)
standard treading support and atomics (_Thread_local)
dedicated null pointer (nullptr)
C++ style comments (//--)
6) What is a Header file ?
Header files (such as <stdio.h> or <stdlib.h>) declare built-in functions, constants, and macros.
The #include preprocessor directive tells the compiler to insert the contents of that header file before compiling the code.
This is so the program knows how to call standard functions like printf or scanf.
7) Can you give some examples of header files ?
#include <assert.h> // Contains the assert macro, detect logical errors and other types of bugs
#include <complex.h> // Contains functions for manipulating complex numbers
#include <ctype.h> // Contains functions for examining and converting individual characters
#include <errno.h> // Contains functions for testing error codes reported by library functions
#include <math.h> // Defines common mathematical functions
#include <stdbool.h> // Defines a boolean data type
#include <stdio.h> // Define score input and output functions
#include <stdlib.h> // Defines numeric conversion functions, random numbers and memory allocation
#include <string.h> // Defines string handling functions
#include <time.h> // Defines date and time handling functions
#include <windows.h> // Includes declarations, constants, structures and other definitions
#include <winhttp.h> // A thread safe, optimised http windows service
8) What is a Pointer ?
Also called a pointer variable, this is a special variable that points to an address in memory.
To declare a pointer (or pointer variable) you use the dereference operator (or star operator).
int *my_ptr; // this is the preferred syntax
int* my_ptr;
9) Can a pointer refer to a normal variable ?
Yes. To obtain a memory address from a variable you can use the address operator / ampersand.
int myval = 46;
int *myptr = &myval;
int myval2 = *my_ptr;
10) How do I modify a value using a pointer ?
You can use the dereference operator to read or write the value it points to.
(*myptr = 20) does not change the pointer, it changes the value that the pointer refers to.
int myval = 10;
int *myptr = &myval; // gets the memory address
*myptr = 20 // change the value
printf(*myptr); // prints 20
printf(myval); // prints 20
11) Should I always initialise a pointer ?
Yes. If you do not have a value, then always assign to NULL (which is a safe, invalid address).
int *myval = 10;
int *myval = NULL;
12) What is the main() function ?
The main() function is the only component that has to be included in every C program.
13) Should I always check a pointer is not NULL before it is dereferenced ?
Yes. You should never dereference a NULL pointer.
int *myval = NULL;
if (myval == NULL) {
// not safe
} else {
free(myval)l
}
14) What happens if you dereference an uninitialised pointer ?
15) What is a segmentation fault ?
A segmentation fault is a runtime crash that occurs when your program tries to read or write to a restricted or invalid memory address.
This frequently happens in C due to dereferencing a NULL or uninitialized pointer, or writing past the bounds of an array.
16) What are the C Programming data types ?
| Keyword | Description | Bytes | Range |
| char | character | 1 | -128 to 127 |
| short | short int | 2 | -32767 to 32767 |
| int | integer | 4 | -2,147,483,647 to 2,147,438,647 |
| long | long integer | 4 | -2,147,483,647 to 2,147,438,647 |
| unsigned char | unsigned character | 1 | 0 to 255 |
| unsigned short | unsigned short integer | 2 | 0 to 65535 |
| unsigned int | unsigned integer | 4 | 0 to 4,294,967,295 |
| unsigned long | unsigned long integer | 4 | 0 to 4,294,967,295 |
| float | single precision floating point | 4 | 1.2E-38 to 3.4E38 |
| double | double precision floating point | 8 | 2.2E-308 to 1.8E308 |
17) Is there a boolean data type ?
Yes. In C23 the boolean data type was been added alongside the false and true keywords.
However C23 is not used for XLL development.
In C90 you can add #include <windows.h>
In C99 you can add #include <stdbool.h> and use _Bool (not recommended)
#include <windows.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
18) Is there a string data type ?
No. There is not a built-in data type for storing strings.
A C String is an array of characters (char) that ends with a special marker called the null terminator (\0)
char name[] = "Richard"; // stored as R i c h a r d \0
char greeting[] = "Hello"; // Compiler automatically figures out the size is 6
char name[20] = "Alice"; // Creates a 20-byte buffer, leaves empty spaces at the end
char name[10] = "some text"; // Adding one to the length, to include the string termination character)
19) What is the difference between char* and wchar_t* ?
They are both pointers to strings.
char* text = "Hello";
The char uses 1 byte and is used for ASCII. Often referred to as a byte string.
This should be used for the actual data being transferred as JSON.
wchar_t* text = L"Hello";
The wchar_t* uses 2 bytes and is used for UNICODE. Often referred to as a wide character string.
This should be used for the registration functions, string literals and windows API calls (not the actual data).
20) How do we do string manipulation ?
Using the standard library functions
| Byte Strings | Wide Characters Strings |
| strlen - calculates the length of a string | wcslen |
| strchr - search for the first occurrence | wcschr |
| strncat - appends characters to the end | wcscat |
| strncmp - compares two strings | wcscmp |
| strncpy - copy characters from one string to another | wcsncpy |
21) What does LPSTR stand for ?
This stands for "Long Pointer to String" and is a Windows API data type (not C or C++ specific)
typedef char* LPSTR
22) What are these data types ?
| HWND | ||
| UINT | ||
| UINT_PTR | ||
| LPVOID | ||
| LPXLOPER12 |
23) How can you define a constant ?
Literal constants can change during your program execution.
Symbolic constants cannot change.
// this is a literal constant
float radius = 10;
// this is a symbolic constant
const float radius = 10;
#define RADIUS 10 (no semi-colon)
24) How can you add comments ?
// starts a single line comment
/* Starts a multiline comments and is ended by */
25) What are the operators ?
| Operator | Description | Precedence |
| ++ | Postfix increment (left-to-right) | 1 |
| -- | Postfix decrement (left-to-right) | 1 |
| ++ | Prefix increment (right-to-left) | 2 |
| -- | Prefix decrement (right-to-left) | 2 |
| sizeof | Size of | 2 |
| * | Multiplication (left-to-right) | 3 |
| / | Division | 3 |
| % | Modulo(remainder) | 3 |
| + | Addition (left-to-right) | 4 |
| - | Subtraction | 4 |
| < | Less than (left-to-right) | 5 |
| <= | Less than or equal to | 5 |
| > | Greater than | 5 |
| >= | Greater than or equal to | 5 |
| == | Equal to (left-to-right) | 6 |
| != | Not equal to | 6 |
| = | Direct assignment (right-to-left) | 7 |
| += | Assignment by sum | 7 |
| -= | Assignment by difference | 7 |
| *= | Assignment by product | 7 |
| /= | Assignment by quotient | 7 |
| && | Logical AND | |
| || | Logical OR |
26) What are the malloc and free functions ?
Malloc allocates memory dynamically and should be used when you want a variable to be available outside of a function call.
MyType *my_obj = (MyType*)malloc(sizeof(MyType));
Free deallocates (or frees) the dynamically allocated memory. It does not delete the variable, just the data that it points to
free (my_obj);
27) What is the difference between malloc and calloc ?
calloc sets all ints to 0, all pointers to NULL and all strings to empty.
malloc does not initialise and therefore requires manual initialisation by copying in the necessary data.
28) What is the difference between the Stack and the Heap ?
Stack is a contiguous block of memory where allocation happens in the function call stack of a program.
Heap is a dynamic allocation of memory at runtime.
29) What is a function prototype ?
This is a declaration of a function that tells the compiler about the function's name, return type, and parameters.
Sometimes you can declare the function before it is used but not always.
When a function has not been declared before it is used you need to include a function prototype above it.
static const char* fn_MyFunction(const char* json);
// code that needs to use this function
static const char* fn_MyFunction(
const char* json)
{}
30) Do my functions with no arguments needs to include void ?
No.In C23 standard, empty brackets () mean the same thing as (void).
void myFunction();
void myFunction(void);
31) Are variables passed by value or by reference ?
Everything is passed by value, by default.
// Passed by Value
void myfunc(int x) {
x = 20;
}
If you want to pass by reference, you need to use a pointer.
// Passed by Reference
void myfunc(int *x) {
*x = 20;
}
32) Can you give an example of passing in a value by reference ?
In C there is no dedicated syntax for passing a value by reference.
However this can be achieved by using a pointer and passing the address of a variable.
int myval = 10;
myfunc(&myval);
printf(myval);
void myfunc(int *x) {
*x = 20; // must have an asterisk to change the value
}
In C++ there is, and the syntax for this is: void myfunc(int& x)
33) How can you define a user defined type ?
Also called a custom data structure.
typedef struct
{
char item1;
} MyUserDefined1
MyUserDefined1 varName1;
34) Why do you use typedef when declaring a custom data type ?
This allows you to create a user defined type and at the same time give it an alias name.
Using an alias means you do not have to include the struct keyword every time you declare a new variable of this data type.
struct MyUserDefined2
{
char item1;
}
struct MyUserDefined2 varName2;
35) Can you have static variables ?
Yes. This will create a static local variable.
Initialized only once when the program starts. When the function exits, the variable retains its current value. The next time you call the function, it picks up right where it left off.
void countCalls() {
static int counter = 0;
36) What does static infront of a function mean ?
When you put static in front of a global variable or a function at the top-level of a file, it acts as an access modifier
It limits the visibility of that item to that specific file only.
static int secretData = 100;
static void privateHelper() {
37) What does inline mean infront of a function name ?
This tells the compiler to replace a function call directly with the function's actual code during compilation.
Every time a standard function is called, there is a small amount of overhead, so doing this can increase performance.
This overhead can often take more time than executing the actual function itself.
inline int square(int x)
{
return x * x;
}
38) What are Excel4, Excel12, and the XLOPER12 structures?
These are the primary framework callback functions and data structures used to pass data to and from Excel.
Excel4 uses XLOPER and supports 256 columns and 65,536 rows.
Excel12 was introduced with Excel 2007, uses XLOPER12, supports Unicode, and supports 16,384 columns and 1,048,576 rows.
39) What is the difference between xlbitXLFree and xlbitDLLFree with regards to memory handling ?
xlbitXLFree - Set by Excel when it returns a value to your DLL.
xlbitDLLFree - Set by your C function when returning data back to an Excel cell. It then calls xlAutoFree12() hook so my C code can safely free its own memory"
40) Can a C API function be called from background worker threads?
No. The C API is strictly single-threaded on Excel's main thread.
You cannot spawn an arbitrary background thread in C and call back into Excel via Excel12().
41) What functionality was added in Excel 2010 to help with multi threading ?
In Excel 2010 it became possible to declare asynchronous user defined functions.
A native async UDF splits execution into two parts: a synchronous entry point that immediately returns control to Excel's calculation engine (keeping Excel responsive), and an asynchronous worker thread that handles the heavy lifting
The xlAsyncReturn callback specifically so background processes could safely drop results back into Excel's main thread loop once finished.
link - learn.microsoft.com/en-us/office/client-developer/excel/asynchronous-user-defined-functions
42) What is WINAPI ?
__declspec(dllexport) int WINAPI xlAutoOpen
#const WINAPI __stdcall
The WINAPI is just a macro/constant definition
Any function that you want to call from Excel must include the modifier "__stdcall"
43) What is '__stdcall' ?
int __stdcall xlAutoOpen
This is a windows calling convention that defines stack cleanup, argument passing and symbol naming
This function cleans up the stack automatically.
44) What is '__cdecl' ?
This is a windows calling convention that defines stack cleanup, argument passing and symbol naming
The function does not clean up the stack and relies on the caller to do it.
This is the default on Win32.
45) What is DWORD ?
This is a windows API data type found in "windows.h".
typedef unsigned long DWORD
46) What calling convention is used in 64-bit Excel.
__stdcall is the only convention that is used.
pg 93
47) What is '__declspec()' ?
This is a compiler directive that can be used to add attributes to declarations.
This line of code is a function declaration designed to create a custom Excel worksheet function inside an XLL.
__declspec(dllexport) LPXLOPER12 WINAPI my_new_function()
48) What is extern "C" ?
This can be added to tell the compiler not to apply C++ name mangling and to export this symbol as if it was written in C.
49) What is #pragma ?
This is a compiler directive that embeds instructions inside the compiled object file (.obj).
# pragma comment(lib, "oleauto32.lib")
A pragma is a special instruction to the compiler.
The program being used on this line is called "comment" which means add this library when the file is compiled
50) What does this mean ?
static const char* MyFunction()
This declares a function that returns a pointer to a string that must not be modified.
The static means that the function is only visible in this particular (.c) file.
51) What does this mean ?
BOOL WINAPI DllMain()
This is a callback function that Windows calls automatically when your XLL is loaded/unloaded and runs before xlAutoOpen.
52) Write a For loop
for (i=0; i<10; i++) {
}
53) Write a While loop
while (true) {
break / continue
}
54) How do you declare an array ?
Array names are just pointers to the first element in the array.
int arr[3] = { 1 , 2 , 3 };
int *ptr = arr;
int *ptr2 = &arr[0];
55) How do you declare a multi-dimensional array ?
int multi[x][y]
56) How do you loop through an array ?
int arr[3] = { 1 , 2, 3 };
for (int i=0, i<3, i++)
printf(arr[i]);
}
57) Can you explain the printf function ?
This function can send formatted text directly to the standard output stream.
This is not type-safe and there is a risk of buffer overrun.
#include <stdio.h>
printf("formt string", arg1, arg2, ..);
%d - signed integer (int)
%i - signed integer (int)
%f - floating point number (float/double)
%c - single character (char)
%s - strings of characters (text)
58) Can you explain the sprintf function ?
This is a function in the <stdio.h> that formats and stores a series of characters and values into a string buffer.
59) What is the difference between sprintf and sprintf_s ?
sprintf only takes the destination buffer and the format string.
If your text is 100 characters long but your buffer is only 10 bytes, it will overwrite adjacent memory.
sprinf_s forces you to pass the maximum size of your buffer as a second argument.
sprintf_s(message, sizeof(message), "I am %d years old.", age);
60) Can you explain the scanf function ?
This function reads input from the standard input stream, which is typically the user's keyboard.
#include <stdio.h>
int main() {
int x;
printf("Enter a number: ");
scanf("%d", &x);
printf("You entered: %d\n", x);
return 0;
}
61) Can you explain the difference between the strcpy and the strcpy_s functions ?
strcpy_s is the modern, bounds-checked alternative introduced to prevent memory corruption and security vulnerabilities.
62) What is the strlen function ?
This returns the length of a string
63) What is the difference between ++i (pre-increment) and i++ (post-increment) ?
Pre-increment (++i) increments the value of i first and then uses the new value in the expression.
Post-increment (i++) uses the current value of i in the expression first and then increments i afterward.
64) Are there any suggested naming conventions ?
lower case - function names
lower case - variables (with underscores)
proper case - Excel functions (no underscores)
65) How can you do error handling ?
There is no built-in try-throw-catch mechanism.
BOOL Success;
Success = DoSomething();
if (!Success)
{
return 0;
}
66) Can you create classes ?
No. C does not support classes or any object orientated principles.
To achieve something similar you create a user defined type (using struct) and define specific functions that operate on that type.
typedef struct {
char name[20];
int age;
} Person;
void Person_Init(Person *P,
const char *name,
int age)
{}
void Person_Method(const Person *p)
{}
// usage
Person P;
Person_Init(&p, "Simon", 20);
Person_Method(&p);
© 2026 Better Solutions Limited. All Rights Reserved. © 2026 Better Solutions Limited TopPrevNext